diff --git a/.buildkite/ftr_platform_stateful_configs.yml b/.buildkite/ftr_platform_stateful_configs.yml index f55fc2f7b4898..c1236a04685fb 100644 --- a/.buildkite/ftr_platform_stateful_configs.yml +++ b/.buildkite/ftr_platform_stateful_configs.yml @@ -64,7 +64,6 @@ enabled: - test/functional/apps/dashboard/group5/config.ts - test/functional/apps/dashboard/group6/config.ts - test/functional/apps/discover/ccs_compatibility/config.ts - - test/functional/apps/discover/classic/config.ts - test/functional/apps/discover/embeddable/config.ts - test/functional/apps/discover/esql/config.ts - test/functional/apps/discover/group1/config.ts @@ -231,6 +230,7 @@ enabled: - x-pack/test/functional/apps/lens/group4/config.ts - x-pack/test/functional/apps/lens/group5/config.ts - x-pack/test/functional/apps/lens/group6/config.ts + - x-pack/test/functional/apps/lens/group7/config.ts - x-pack/test/functional/apps/lens/open_in_lens/tsvb/config.ts - x-pack/test/functional/apps/lens/open_in_lens/agg_based/config.ts - x-pack/test/functional/apps/lens/open_in_lens/dashboard/config.ts diff --git a/.buildkite/ftr_security_serverless_configs.yml b/.buildkite/ftr_security_serverless_configs.yml index 69d4801292cf7..74d82d40c8bce 100644 --- a/.buildkite/ftr_security_serverless_configs.yml +++ b/.buildkite/ftr_security_serverless_configs.yml @@ -19,6 +19,9 @@ disabled: - x-pack/test_serverless/functional/config.base.ts - x-pack/test_serverless/shared/config.base.ts + # MKI only configs files + - x-pack/test_serverless/functional/test_suites/security/config.mki_only.ts + defaultQueue: 'n2-4-spot' enabled: - x-pack/test_serverless/api_integration/test_suites/security/config.ts @@ -32,7 +35,6 @@ enabled: - x-pack/test_serverless/functional/test_suites/security/config.cloud_security_posture.basic.ts - x-pack/test_serverless/functional/test_suites/security/config.cloud_security_posture.essentials.ts - x-pack/test_serverless/functional/test_suites/security/config.cloud_security_posture.agentless.ts - - x-pack/test_serverless/functional/test_suites/security/config.cloud_security_posture.agentless_api.ts - x-pack/test_serverless/functional/test_suites/security/config.saved_objects_management.ts - x-pack/test_serverless/functional/test_suites/security/config.context_awareness.ts - x-pack/test_serverless/functional/test_suites/security/common_configs/config.group1.ts @@ -74,7 +76,8 @@ enabled: - x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/large_prebuilt_rules_package/trial_license_complete_tier/configs/serverless.config.ts - x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/configs/serverless.config.ts - x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/update_prebuilt_rules_package/trial_license_complete_tier/configs/serverless.config.ts - - x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/trial_license_complete_tier/configs/serverless.config.ts + - x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/configs/serverless.config.ts + - x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_disabled/configs/serverless.config.ts - x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/rule_bulk_actions/trial_license_complete_tier/configs/serverless.config.ts - x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/rule_delete/trial_license_complete_tier/configs/serverless.config.ts - x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/rule_delete/basic_license_essentials_tier/configs/serverless.config.ts diff --git a/.buildkite/ftr_security_stateful_configs.yml b/.buildkite/ftr_security_stateful_configs.yml index f7caacba05e1b..46c6f356b3ae4 100644 --- a/.buildkite/ftr_security_stateful_configs.yml +++ b/.buildkite/ftr_security_stateful_configs.yml @@ -58,7 +58,8 @@ enabled: - x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/large_prebuilt_rules_package/trial_license_complete_tier/configs/ess.config.ts - x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/configs/ess.config.ts - x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/update_prebuilt_rules_package/trial_license_complete_tier/configs/ess.config.ts - - x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/trial_license_complete_tier/configs/ess.config.ts + - x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/configs/ess.config.ts + - x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_disabled/configs/ess.config.ts - x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/rule_bulk_actions/trial_license_complete_tier/configs/ess.config.ts - x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/rule_delete/trial_license_complete_tier/configs/ess.config.ts - x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/rule_delete/basic_license_essentials_tier/configs/ess.config.ts diff --git a/.buildkite/pipeline-resource-definitions/kibana-fips-daily.yml b/.buildkite/pipeline-resource-definitions/kibana-fips-daily.yml index bedb81cccc5a4..f651a8c9e4f96 100644 --- a/.buildkite/pipeline-resource-definitions/kibana-fips-daily.yml +++ b/.buildkite/pipeline-resource-definitions/kibana-fips-daily.yml @@ -3,7 +3,7 @@ apiVersion: backstage.io/v1alpha1 kind: Resource metadata: name: bk-kibana-fips-daily - description: Run Kibana FIPS smoke tests + description: Run Kibana test suite with FIPS agents links: - title: Pipeline link url: https://buildkite.com/elastic/kibana-fips @@ -16,10 +16,10 @@ spec: kind: Pipeline metadata: name: kibana / fips - description: Run Kibana FIPS smoke tests + description: Run Kibana test suite with FIPS agents spec: env: - SLACK_NOTIFICATIONS_CHANNEL: '#kibana-operations-alerts' + SLACK_NOTIFICATIONS_CHANNEL: '#kibana-fips' ELASTIC_SLACK_NOTIFICATIONS_ENABLED: 'true' repository: elastic/kibana branch_configuration: main diff --git a/.buildkite/scripts/steps/checks/quick_checks.txt b/.buildkite/scripts/steps/checks/quick_checks.txt index 9bd9224673905..7aa0f68118466 100644 --- a/.buildkite/scripts/steps/checks/quick_checks.txt +++ b/.buildkite/scripts/steps/checks/quick_checks.txt @@ -17,3 +17,4 @@ .buildkite/scripts/steps/checks/prettier_topology.sh .buildkite/scripts/steps/checks/renovate.sh .buildkite/scripts/steps/checks/native_modules.sh +.buildkite/scripts/steps/checks/test_files_missing_owner.sh diff --git a/.buildkite/scripts/steps/checks/test_files_missing_owner.sh b/.buildkite/scripts/steps/checks/test_files_missing_owner.sh new file mode 100755 index 0000000000000..4dfec4e18ab61 --- /dev/null +++ b/.buildkite/scripts/steps/checks/test_files_missing_owner.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +set -euo pipefail + +source .buildkite/scripts/common/util.sh + +echo --- Check for Test Files missing an owner +node scripts/check_ftr_code_owners diff --git a/.eslintrc.js b/.eslintrc.js index 7ff37b0c9fd98..226017e524d84 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -2027,6 +2027,13 @@ module.exports = { '@kbn/imports/uniform_imports': 'off', }, }, + { + files: ['packages/kbn-dependency-ownership/**/*.{ts,tsx}'], + rules: { + // disabling it since package is a CLI tool + 'no-console': 'off', + }, + }, ], }; diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 6bfa40e51856e..f5c2ed37db761 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -329,6 +329,7 @@ packages/kbn-data-service @elastic/kibana-visualizations @elastic/kibana-data-di packages/kbn-data-stream-adapter @elastic/security-threat-hunting packages/kbn-data-view-utils @elastic/kibana-data-discovery packages/kbn-datemath @elastic/kibana-data-discovery +packages/kbn-dependency-ownership @elastic/kibana-security packages/kbn-dependency-usage @elastic/kibana-security packages/kbn-dev-cli-errors @elastic/kibana-operations packages/kbn-dev-cli-runner @elastic/kibana-operations @@ -466,6 +467,7 @@ packages/kbn-rrule @elastic/response-ops packages/kbn-rule-data-utils @elastic/security-detections-response @elastic/response-ops @elastic/obs-ux-management-team packages/kbn-safer-lodash-set @elastic/kibana-security packages/kbn-saved-objects-settings @elastic/appex-sharedux +packages/kbn-saved-search-component @elastic/obs-ux-logs-team packages/kbn-scout @elastic/appex-qa packages/kbn-screenshotting-server @elastic/appex-sharedux packages/kbn-search-api-keys-components @elastic/search-kibana @@ -620,7 +622,7 @@ packages/shared-ux/storybook/mock @elastic/appex-sharedux packages/shared-ux/table_persist @elastic/appex-sharedux src/core @elastic/kibana-core src/plugins/advanced_settings @elastic/appex-sharedux @elastic/kibana-management -src/plugins/ai_assistant_management/selection @elastic/obs-knowledge-team +src/plugins/ai_assistant_management/selection @elastic/obs-ai-assistant src/plugins/bfetch @elastic/appex-sharedux src/plugins/chart_expressions/common @elastic/kibana-visualizations src/plugins/chart_expressions/expression_gauge @elastic/kibana-visualizations @@ -865,6 +867,7 @@ x-pack/plugins/ai_infra/llm_tasks @elastic/appex-ai-infra x-pack/plugins/ai_infra/product_doc_base @elastic/appex-ai-infra x-pack/plugins/aiops @elastic/ml-ui x-pack/plugins/alerting @elastic/response-ops +x-pack/plugins/asset_inventory @elastic/kibana-cloud-security-posture x-pack/plugins/banners @elastic/appex-sharedux x-pack/plugins/canvas @elastic/kibana-presentation x-pack/plugins/cases @elastic/response-ops @@ -918,7 +921,7 @@ x-pack/plugins/monitoring @elastic/stack-monitoring x-pack/plugins/monitoring_collection @elastic/stack-monitoring x-pack/plugins/notifications @elastic/appex-sharedux x-pack/plugins/observability_solution/apm @elastic/obs-ux-infra_services-team -x-pack/plugins/observability_solution/apm_data_access @elastic/obs-knowledge-team @elastic/obs-ux-infra_services-team +x-pack/plugins/observability_solution/apm_data_access @elastic/obs-ux-infra_services-team x-pack/plugins/observability_solution/apm/ftr_e2e @elastic/obs-ux-infra_services-team x-pack/plugins/observability_solution/dataset_quality @elastic/obs-ux-logs-team x-pack/plugins/observability_solution/entities_data_access @elastic/obs-entities @@ -929,10 +932,10 @@ x-pack/plugins/observability_solution/inventory @elastic/obs-ux-infra_services-t x-pack/plugins/observability_solution/inventory/e2e @elastic/obs-ux-infra_services-team x-pack/plugins/observability_solution/investigate @elastic/obs-ux-management-team x-pack/plugins/observability_solution/investigate_app @elastic/obs-ux-management-team -x-pack/plugins/observability_solution/logs_data_access @elastic/obs-knowledge-team @elastic/obs-ux-logs-team +x-pack/plugins/observability_solution/logs_data_access @elastic/obs-ux-logs-team x-pack/plugins/observability_solution/logs_explorer @elastic/obs-ux-logs-team x-pack/plugins/observability_solution/logs_shared @elastic/obs-ux-logs-team -x-pack/plugins/observability_solution/metrics_data_access @elastic/obs-knowledge-team @elastic/obs-ux-infra_services-team +x-pack/plugins/observability_solution/metrics_data_access @elastic/obs-ux-infra_services-team x-pack/plugins/observability_solution/observability @elastic/obs-ux-management-team x-pack/plugins/observability_solution/observability_ai_assistant @elastic/obs-ai-assistant x-pack/plugins/observability_solution/observability_ai_assistant_app @elastic/obs-ai-assistant @@ -1235,6 +1238,7 @@ packages/kbn-monaco/src/esql @elastic/kibana-esql # Observability UI +/x-pack/test/api_integration/apis/streams @elastic/observability-ui # Assigned per https://github.com/elastic/kibana/pull/201293 /x-pack/test_serverless/api_integration/test_suites/observability/config.ts @elastic/observability-ui @elastic/appex-qa /x-pack/test_serverless/api_integration/test_suites/observability/index.ts @elastic/observability-ui @@ -1286,6 +1290,7 @@ packages/kbn-monaco/src/esql @elastic/kibana-esql /x-pack/plugins/observability_solution/infra/server/services @elastic/obs-ux-infra_services-team /x-pack/plugins/observability_solution/infra/server/usage @elastic/obs-ux-infra_services-team /x-pack/plugins/observability_solution/infra/server/utils @elastic/obs-ux-infra_services-team +/x-pack/test_serverless/functional/test_suites/observability/infra @elastic/obs-ux-infra_services-team /x-pack/test/api_integration/services/infraops_source_configuration.ts @elastic/obs-ux-infra_services-team @elastic/obs-ux-logs-team # Assigned per https://github.com/elastic/kibana/pull/34916 ## Logs UI code exceptions -> @elastic/obs-ux-logs-team @@ -2098,7 +2103,9 @@ x-pack/test/api_integration/apis/management/index_management/inference_endpoints /x-pack/test/api_integration/services/security_solution_*.gen.ts @elastic/security-solution /x-pack/test/accessibility/apps/group3/security_solution.ts @elastic/security-solution /x-pack/test_serverless/functional/test_suites/security/config.ts @elastic/security-solution @elastic/appex-qa -/x-pack/test_serverless/functional/test_suites/security/config.feature_flags.ts @elastic/security-solution +x-pack/test_serverless/functional/test_suites/security/config.mki_only.ts @elastic/security-solution @elastic/appex-qa +x-pack/test_serverless/functional/test_suites/security/index.mki_only.ts @elastic/security-solution @elastic/appex-qa @elastic/kibana-cloud-security-posture +/x-pack/test_serverless/functional/test_suites/security/config.feature_flags.ts @elastic/security-solution @elastic/kibana-cloud-security-posture /x-pack/test_serverless/api_integration/test_suites/observability/config.feature_flags.ts @elastic/security-solution /x-pack/test_serverless/functional/test_suites/common/spaces/multiple_spaces_enabled.ts @elastic/security-solution /x-pack/test/functional/es_archives/endpoint/ @elastic/security-solution @@ -2129,11 +2136,15 @@ x-pack/test/api_integration/apis/management/index_management/inference_endpoints # TODO: assign sub directories to sub teams /x-pack/plugins/security_solution_ess/ @elastic/security-solution /x-pack/plugins/security_solution_serverless/ @elastic/security-solution +/x-pack/plugins/security_solution/public/app/404.tsx @elastic/security-solution +/x-pack/plugins/security_solution/public/app/app.tsx @elastic/security-solution +/x-pack/plugins/security_solution/public/app/home @elastic/security-solution # GenAI in Security Solution /x-pack/plugins/security_solution/public/assistant @elastic/security-generative-ai /x-pack/plugins/security_solution/public/attack_discovery @elastic/security-generative-ai /x-pack/test/security_solution_cypress/cypress/e2e/ai_assistant @elastic/security-generative-ai +/x-pack/plugins/security_solution_ess/public/upselling/pages/attack_discovery @elastic/security-generative-ai # Security Solution cross teams ownership /x-pack/test/security_solution_cypress/cypress/fixtures @elastic/security-detections-response @elastic/security-threat-hunting @@ -2149,6 +2160,8 @@ x-pack/test/api_integration/apis/management/index_management/inference_endpoints /x-pack/plugins/security_solution/public/common/components/callouts @elastic/security-detections-response /x-pack/plugins/security_solution/public/common/components/hover_actions @elastic/security-threat-hunting-explore @elastic/security-threat-hunting-investigations +/x-pack/plugins/security_solution/public/common/components/formatted_date/index.tsx @elastic/security-threat-hunting-explore @elastic/security-threat-hunting-investigations +/x-pack/plugins/security_solution/public/common/components/formatted_number/index.tsx @elastic/security-threat-hunting-explore @elastic/security-threat-hunting-investigations /x-pack/plugins/security_solution/server/routes @elastic/security-detections-response @elastic/security-threat-hunting /x-pack/plugins/security_solution/server/utils @elastic/security-detections-response @elastic/security-threat-hunting @@ -2179,6 +2192,7 @@ x-pack/test/security_solution_api_integration/test_suites/sources @elastic/secur /x-pack/plugins/security_solution/server/lib/siem_migrations @elastic/security-threat-hunting /x-pack/plugins/security_solution/common/siem_migrations @elastic/security-threat-hunting /x-pack/plugins/security_solution/public/siem_migrations @elastic/security-threat-hunting +/x-pack/plugins/security_solution/public/common/components/control_columns @elastic/security-threat-hunting ## Security Solution Threat Hunting areas - Threat Hunting Investigations @@ -2207,6 +2221,21 @@ x-pack/test/security_solution_cypress/cypress/tasks/expandable_flyout @elastic/ /x-pack/plugins/security_solution/public/resolver @elastic/security-threat-hunting-investigations /x-pack/plugins/security_solution/public/threat_intelligence @elastic/security-threat-hunting-investigations /x-pack/plugins/security_solution/public/timelines @elastic/security-threat-hunting-investigations +/x-pack/plugins/security_solution/public/common/components/header_actions @elastic/security-threat-hunting-investigations +/x-pack/plugins/security_solution/common/types/header_actions @elastic/security-threat-hunting-investigations +/x-pack/plugins/security_solution/public/flyout/network_details @elastic/security-threat-hunting-investigations +/x-pack/plugins/security_solution/public/flyout/rule_details @elastic/security-threat-hunting-investigations +/x-pack/plugins/security_solution/public/investigations @elastic/security-threat-hunting-investigations +/x-pack/plugins/security_solution/public/detections/configurations/security_solution_detections @elastic/security-threat-hunting-investigations +/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.tsx @elastic/security-threat-hunting-investigations +/x-pack/plugins/security_solution/public/common/hooks/use_resolve_conflict.tsx @elastic/security-threat-hunting-investigations +/x-pack/plugins/security_solution/public/common/components/drag_and_drop @elastic/security-threat-hunting-investigations +/x-pack/plugins/security_solution/public/common/components/draggables @elastic/security-threat-hunting-investigations +/x-pack/plugins/security_solution/public/common/components/events_tab @elastic/security-threat-hunting-investigations +/x-pack/plugins/security_solution_serverless/public/upselling/pages/threat_intelligence_paywall.tsx @elastic/security-threat-hunting-investigations +/x-pack/plugins/security_solution/public/common/mock/mock_timeline_control_columns.tsx @elastic/security-threat-hunting-investigations +/x-pack/plugins/security_solution/public/common/components/exit_full_screen @elastic/security-threat-hunting-investigations +/x-pack/plugins/security_solution/public/app/home/template_wrapper/timeline @elastic/security-threat-hunting-investigations /x-pack/plugins/security_solution/server/lib/timeline @elastic/security-threat-hunting-investigations @@ -2224,6 +2253,13 @@ x-pack/test/security_solution_cypress/cypress/tasks/expandable_flyout @elastic/ /x-pack/test/security_solution_cypress/cypress/tasks/network @elastic/security-threat-hunting-explore /x-pack/plugins/security_solution/public/app/actions @elastic/security-threat-hunting-explore +/x-pack/plugins/security_solution/public/assets @elastic/security-threat-hunting-explore +/x-pack/plugins/security_solution/public/app/solution_navigation/links @elastic/security-threat-hunting-explore +/x-pack/plugins/security_solution/public/common/lib/clipboard @elastic/security-threat-hunting-explore +/x-pack/plugins/security_solution/public/common/components/visualization_actions @elastic/security-threat-hunting-explore +/x-pack/plugins/security_solution/public/common/components/accessibility @elastic/security-threat-hunting-explore +/x-pack/plugins/security_solution/public/common/components/first_last_seen/first_last_seen.tsx @elastic/security-threat-hunting-explore +/x-pack/plugins/security_solution/public/common/components/alert_count_by_status @elastic/security-threat-hunting-explore /x-pack/plugins/security_solution/public/common/components/guided_onboarding_tour @elastic/security-threat-hunting-explore /x-pack/plugins/security_solution/public/common/components/charts @elastic/security-threat-hunting-explore /x-pack/plugins/security_solution/public/detections/components/alerts_table/grouping_settings @elastic/security-threat-hunting-explore @@ -2247,7 +2283,10 @@ x-pack/test/security_solution_cypress/cypress/tasks/expandable_flyout @elastic/ /x-pack/plugins/security_solution/public/explore @elastic/security-threat-hunting-explore /x-pack/plugins/security_solution/public/overview @elastic/security-threat-hunting-explore /x-pack/plugins/security_solution/public/dashboards @elastic/security-threat-hunting-explore - +/x-pack/plugins/security_solution/public/onboarding @elastic/security-threat-hunting-explore +/x-pack/plugins/security_solution/public/common/components/empty_page @elastic/security-threat-hunting-explore +/x-pack/plugins/security_solution/public/common/components/empty_prompt @elastic/security-threat-hunting-explore +/x-pack/plugins/security_solution_serverless/public/components/dashboards_landing_callout @elastic/security-threat-hunting-explore /x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts @elastic/security-threat-hunting-explore /x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/matrix_histogram @elastic/security-threat-hunting-explore /x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network @elastic/security-threat-hunting-explore @@ -2319,6 +2358,7 @@ x-pack/test/security_solution_cypress/cypress/tasks/expandable_flyout @elastic/ /x-pack/plugins/security_solution/public/detections/mitre @elastic/security-detection-rule-management /x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules @elastic/security-detection-rule-management /x-pack/plugins/security_solution/public/rules @elastic/security-detection-rule-management +/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions @elastic/security-detection-rule-management /x-pack/plugins/security_solution/server/lib/detection_engine/fleet_integrations @elastic/security-detection-rule-management /x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules @elastic/security-detection-rule-management @@ -2341,6 +2381,8 @@ x-pack/test/security_solution_cypress/cypress/tasks/expandable_flyout @elastic/ /x-pack/test/functional/es_archives/entity/risks @elastic/security-detection-engine /x-pack/test/functional/es_archives/entity/host_risk @elastic/security-detection-engine /x-pack/test/api_integration/apis/lists @elastic/security-detection-engine +/x-pack/plugins/security_solution/public/value_list @elastic/security-detection-engine +/x-pack/plugins/security_solution/public/detections/components/value_lists_management_flyout @elastic/security-detection-engine /x-pack/plugins/security_solution/public/sourcerer @elastic/security-threat-hunting-investigations /x-pack/plugins/security_solution/public/detection_engine/rule_creation @elastic/security-detection-engine @@ -2396,6 +2438,8 @@ x-pack/packages/kbn-elastic-assistant-common/impl/schemas/defend_insights @elast x-pack/plugins/elastic_assistant/server/__mocks__/defend_insights_schema.mock.ts @elastic/security-defend-workflows x-pack/plugins/elastic_assistant/server/ai_assistant_data_clients/defend_insights @elastic/security-defend-workflows x-pack/plugins/elastic_assistant/server/routes/defend_insights @elastic/security-defend-workflows +/x-pack/plugins/security_solution/public/common/components/response_actions @elastic/security-defend-workflows +/x-pack/plugins/security_solution_serverless/public/upselling/pages/osquery_automated_response_actions.tsx @elastic/security-defend-workflows ## Security Solution sub teams - security-telemetry (Data Engineering) x-pack/plugins/security_solution/server/usage/ @elastic/security-data-analytics diff --git a/api_docs/actions.devdocs.json b/api_docs/actions.devdocs.json index d93ecea54b849..551623f07d054 100644 --- a/api_docs/actions.devdocs.json +++ b/api_docs/actions.devdocs.json @@ -3270,20 +3270,6 @@ "deprecated": false, "trackAdoption": false }, - { - "parentPluginId": "actions", - "id": "def-server.ActionTypeExecutorOptions.isEphemeral", - "type": "CompoundType", - "tags": [], - "label": "isEphemeral", - "description": [], - "signature": [ - "boolean | undefined" - ], - "path": "x-pack/plugins/actions/server/types.ts", - "deprecated": false, - "trackAdoption": false - }, { "parentPluginId": "actions", "id": "def-server.ActionTypeExecutorOptions.taskInfo", @@ -3838,16 +3824,6 @@ "ExecuteOptions", "[]) => Promise<", "ExecutionResponse", - ">; ephemeralEnqueuedExecution: (options: ", - "ExecuteOptions", - ") => Promise<", - { - "pluginId": "taskManager", - "scope": "server", - "docId": "kibTaskManagerPluginApi", - "section": "def-server.RunNowResult", - "text": "RunNowResult" - }, ">; listTypes: ({ featureId, includeSystemActionTypes, }?: ", "ListTypesParams", ") => Promise<", diff --git a/api_docs/actions.mdx b/api_docs/actions.mdx index f843eec3f2a60..25325239da8cb 100644 --- a/api_docs/actions.mdx +++ b/api_docs/actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/actions title: "actions" image: https://source.unsplash.com/400x175/?github description: API docs for the actions plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'actions'] --- import actionsObj from './actions.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 | |-------------------|-----------|------------------------|-----------------| -| 322 | 0 | 316 | 37 | +| 321 | 0 | 315 | 37 | ## Client diff --git a/api_docs/advanced_settings.mdx b/api_docs/advanced_settings.mdx index ccd8e983d2568..3ba1bc950dca4 100644 --- a/api_docs/advanced_settings.mdx +++ b/api_docs/advanced_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/advancedSettings title: "advancedSettings" image: https://source.unsplash.com/400x175/?github description: API docs for the advancedSettings plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'advancedSettings'] --- import advancedSettingsObj from './advanced_settings.devdocs.json'; diff --git a/api_docs/ai_assistant_management_selection.mdx b/api_docs/ai_assistant_management_selection.mdx index 1cead58a537fb..e6a25e9c32d37 100644 --- a/api_docs/ai_assistant_management_selection.mdx +++ b/api_docs/ai_assistant_management_selection.mdx @@ -8,14 +8,14 @@ slug: /kibana-dev-docs/api/aiAssistantManagementSelection title: "aiAssistantManagementSelection" image: https://source.unsplash.com/400x175/?github description: API docs for the aiAssistantManagementSelection plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'aiAssistantManagementSelection'] --- import aiAssistantManagementSelectionObj from './ai_assistant_management_selection.devdocs.json'; -Contact [@elastic/obs-knowledge-team](https://github.com/orgs/elastic/teams/obs-knowledge-team) for questions regarding this plugin. +Contact [@elastic/obs-ai-assistant](https://github.com/orgs/elastic/teams/obs-ai-assistant) for questions regarding this plugin. **Code health stats** diff --git a/api_docs/aiops.mdx b/api_docs/aiops.mdx index 48a9513bcd9f4..5a442711b0a1f 100644 --- a/api_docs/aiops.mdx +++ b/api_docs/aiops.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/aiops title: "aiops" image: https://source.unsplash.com/400x175/?github description: API docs for the aiops plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'aiops'] --- import aiopsObj from './aiops.devdocs.json'; diff --git a/api_docs/alerting.devdocs.json b/api_docs/alerting.devdocs.json index 1e5ae28cecb8d..7e168f7bf1120 100644 --- a/api_docs/alerting.devdocs.json +++ b/api_docs/alerting.devdocs.json @@ -4715,21 +4715,6 @@ "trackAdoption": false, "initialIsOpen": false }, - { - "parentPluginId": "alerting", - "id": "def-server.DEFAULT_MAX_EPHEMERAL_ACTIONS_PER_ALERT", - "type": "number", - "tags": [], - "label": "DEFAULT_MAX_EPHEMERAL_ACTIONS_PER_ALERT", - "description": [], - "signature": [ - "10" - ], - "path": "x-pack/plugins/alerting/server/config.ts", - "deprecated": false, - "trackAdoption": false, - "initialIsOpen": false - }, { "parentPluginId": "alerting", "id": "def-server.ECS_COMPONENT_TEMPLATE_NAME", diff --git a/api_docs/alerting.mdx b/api_docs/alerting.mdx index 5f1e15542b16c..3172ccf49b330 100644 --- a/api_docs/alerting.mdx +++ b/api_docs/alerting.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/alerting title: "alerting" image: https://source.unsplash.com/400x175/?github description: API docs for the alerting plugin -date: 2024-11-29 +date: 2024-12-03 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 | |-------------------|-----------|------------------------|-----------------| -| 881 | 1 | 849 | 50 | +| 880 | 1 | 848 | 50 | ## Client diff --git a/api_docs/apm.mdx b/api_docs/apm.mdx index b8ad4016367b1..d9d9c62757559 100644 --- a/api_docs/apm.mdx +++ b/api_docs/apm.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/apm title: "apm" image: https://source.unsplash.com/400x175/?github description: API docs for the apm plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'apm'] --- import apmObj from './apm.devdocs.json'; diff --git a/api_docs/apm_data_access.devdocs.json b/api_docs/apm_data_access.devdocs.json index 6d0f3b4532dc4..be97ce96ca40e 100644 --- a/api_docs/apm_data_access.devdocs.json +++ b/api_docs/apm_data_access.devdocs.json @@ -441,6 +441,78 @@ ], "functions": [], "interfaces": [ + { + "parentPluginId": "apmDataAccess", + "id": "def-server.ApmDataAccessPrivilegesCheck", + "type": "Interface", + "tags": [], + "label": "ApmDataAccessPrivilegesCheck", + "description": [], + "path": "x-pack/plugins/observability_solution/apm_data_access/server/lib/check_privileges.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "apmDataAccess", + "id": "def-server.ApmDataAccessPrivilegesCheck.request", + "type": "Object", + "tags": [], + "label": "request", + "description": [], + "signature": [ + { + "pluginId": "@kbn/core-http-server", + "scope": "server", + "docId": "kibKbnCoreHttpServerPluginApi", + "section": "def-server.KibanaRequest", + "text": "KibanaRequest" + }, + "" + ], + "path": "x-pack/plugins/observability_solution/apm_data_access/server/lib/check_privileges.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "apmDataAccess", + "id": "def-server.ApmDataAccessPrivilegesCheck.security", + "type": "Object", + "tags": [], + "label": "security", + "description": [], + "signature": [ + { + "pluginId": "@kbn/security-plugin-types-server", + "scope": "server", + "docId": "kibKbnSecurityPluginTypesServerPluginApi", + "section": "def-server.SecurityPluginStart", + "text": "SecurityPluginStart" + }, + " | undefined" + ], + "path": "x-pack/plugins/observability_solution/apm_data_access/server/lib/check_privileges.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "apmDataAccess", + "id": "def-server.ApmDataAccessPrivilegesCheck.getApmIndices", + "type": "Function", + "tags": [], + "label": "getApmIndices", + "description": [], + "signature": [ + "() => Promise>" + ], + "path": "x-pack/plugins/observability_solution/apm_data_access/server/lib/check_privileges.ts", + "deprecated": false, + "trackAdoption": false, + "children": [], + "returnComment": [] + } + ], + "initialIsOpen": false + }, { "parentPluginId": "apmDataAccess", "id": "def-server.ApmDataAccessServicesParams", @@ -2293,12 +2365,42 @@ "label": "getApmIndices", "description": [], "signature": [ - "() => Promise>" + "(soClient: ", + { + "pluginId": "@kbn/core-saved-objects-api-server", + "scope": "server", + "docId": "kibKbnCoreSavedObjectsApiServerPluginApi", + "section": "def-server.SavedObjectsClientContract", + "text": "SavedObjectsClientContract" + }, + ") => Promise>" ], "path": "x-pack/plugins/observability_solution/apm_data_access/server/types.ts", "deprecated": false, "trackAdoption": false, - "children": [], + "children": [ + { + "parentPluginId": "apmDataAccess", + "id": "def-server.ApmDataAccessPluginSetup.getApmIndices.$1", + "type": "Object", + "tags": [], + "label": "soClient", + "description": [], + "signature": [ + { + "pluginId": "@kbn/core-saved-objects-api-server", + "scope": "server", + "docId": "kibKbnCoreSavedObjectsApiServerPluginApi", + "section": "def-server.SavedObjectsClientContract", + "text": "SavedObjectsClientContract" + } + ], + "path": "x-pack/plugins/observability_solution/apm_data_access/server/types.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], "returnComment": [] }, { @@ -2402,7 +2504,56 @@ "path": "x-pack/plugins/observability_solution/apm_data_access/server/types.ts", "deprecated": false, "trackAdoption": false, - "children": [], + "children": [ + { + "parentPluginId": "apmDataAccess", + "id": "def-server.ApmDataAccessPluginStart.hasPrivileges", + "type": "Function", + "tags": [], + "label": "hasPrivileges", + "description": [], + "signature": [ + "(params: Pick<", + { + "pluginId": "apmDataAccess", + "scope": "server", + "docId": "kibApmDataAccessPluginApi", + "section": "def-server.ApmDataAccessPrivilegesCheck", + "text": "ApmDataAccessPrivilegesCheck" + }, + ", \"request\">) => Promise" + ], + "path": "x-pack/plugins/observability_solution/apm_data_access/server/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "apmDataAccess", + "id": "def-server.ApmDataAccessPluginStart.hasPrivileges.$1", + "type": "Object", + "tags": [], + "label": "params", + "description": [], + "signature": [ + "Pick<", + { + "pluginId": "apmDataAccess", + "scope": "server", + "docId": "kibApmDataAccessPluginApi", + "section": "def-server.ApmDataAccessPrivilegesCheck", + "text": "ApmDataAccessPrivilegesCheck" + }, + ", \"request\">" + ], + "path": "x-pack/plugins/observability_solution/apm_data_access/server/types.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] + } + ], "lifecycle": "start", "initialIsOpen": true } diff --git a/api_docs/apm_data_access.mdx b/api_docs/apm_data_access.mdx index f8b6246d9edd1..decef801d061d 100644 --- a/api_docs/apm_data_access.mdx +++ b/api_docs/apm_data_access.mdx @@ -8,20 +8,20 @@ slug: /kibana-dev-docs/api/apmDataAccess title: "apmDataAccess" image: https://source.unsplash.com/400x175/?github description: API docs for the apmDataAccess plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'apmDataAccess'] --- import apmDataAccessObj from './apm_data_access.devdocs.json'; -Contact [@elastic/obs-knowledge-team](https://github.com/orgs/elastic/teams/obs-knowledge-team) for questions regarding this plugin. +Contact [@elastic/obs-ux-infra_services-team](https://github.com/orgs/elastic/teams/obs-ux-infra_services-team) for questions regarding this plugin. **Code health stats** | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 86 | 0 | 86 | 3 | +| 93 | 0 | 93 | 3 | ## Server diff --git a/api_docs/banners.mdx b/api_docs/banners.mdx index 2a688e33c27fe..37f6ffd3c560a 100644 --- a/api_docs/banners.mdx +++ b/api_docs/banners.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/banners title: "banners" image: https://source.unsplash.com/400x175/?github description: API docs for the banners plugin -date: 2024-11-29 +date: 2024-12-03 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 a324a44c1d36c..1574b0899679f 100644 --- a/api_docs/bfetch.mdx +++ b/api_docs/bfetch.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/bfetch title: "bfetch" image: https://source.unsplash.com/400x175/?github description: API docs for the bfetch plugin -date: 2024-11-29 +date: 2024-12-03 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 ea50260b2f792..90d1aa548e6a8 100644 --- a/api_docs/canvas.mdx +++ b/api_docs/canvas.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/canvas title: "canvas" image: https://source.unsplash.com/400x175/?github description: API docs for the canvas plugin -date: 2024-11-29 +date: 2024-12-03 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 02ce325b6d480..601841b63ddc3 100644 --- a/api_docs/cases.mdx +++ b/api_docs/cases.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cases title: "cases" image: https://source.unsplash.com/400x175/?github description: API docs for the cases plugin -date: 2024-11-29 +date: 2024-12-03 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 2eb18f944f003..5d341d4fb0450 100644 --- a/api_docs/charts.mdx +++ b/api_docs/charts.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/charts title: "charts" image: https://source.unsplash.com/400x175/?github description: API docs for the charts plugin -date: 2024-11-29 +date: 2024-12-03 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 bbf4f232b3901..fae98a56939c8 100644 --- a/api_docs/cloud.mdx +++ b/api_docs/cloud.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloud title: "cloud" image: https://source.unsplash.com/400x175/?github description: API docs for the cloud plugin -date: 2024-11-29 +date: 2024-12-03 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 137ab2a465bed..eb5a95b7d2cc8 100644 --- a/api_docs/cloud_data_migration.mdx +++ b/api_docs/cloud_data_migration.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudDataMigration title: "cloudDataMigration" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudDataMigration plugin -date: 2024-11-29 +date: 2024-12-03 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 0356904f91a49..7646521c485d2 100644 --- a/api_docs/cloud_defend.mdx +++ b/api_docs/cloud_defend.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudDefend title: "cloudDefend" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudDefend plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudDefend'] --- import cloudDefendObj from './cloud_defend.devdocs.json'; diff --git a/api_docs/cloud_security_posture.mdx b/api_docs/cloud_security_posture.mdx index acfcbdd033969..dcf110b8af02c 100644 --- a/api_docs/cloud_security_posture.mdx +++ b/api_docs/cloud_security_posture.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudSecurityPosture title: "cloudSecurityPosture" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudSecurityPosture plugin -date: 2024-11-29 +date: 2024-12-03 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 38a36fbec5e1f..ac3593719be3d 100644 --- a/api_docs/console.mdx +++ b/api_docs/console.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/console title: "console" image: https://source.unsplash.com/400x175/?github description: API docs for the console plugin -date: 2024-11-29 +date: 2024-12-03 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 b91f155f2ce01..a6efce141f661 100644 --- a/api_docs/content_management.mdx +++ b/api_docs/content_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/contentManagement title: "contentManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the contentManagement plugin -date: 2024-11-29 +date: 2024-12-03 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 b93a885c1d431..3c954c4b17384 100644 --- a/api_docs/controls.mdx +++ b/api_docs/controls.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/controls title: "controls" image: https://source.unsplash.com/400x175/?github description: API docs for the controls plugin -date: 2024-11-29 +date: 2024-12-03 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 698f5836d32ae..b25d90614eecb 100644 --- a/api_docs/custom_integrations.mdx +++ b/api_docs/custom_integrations.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/customIntegrations title: "customIntegrations" image: https://source.unsplash.com/400x175/?github description: API docs for the customIntegrations plugin -date: 2024-11-29 +date: 2024-12-03 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 000c8009b3d0c..01900e4b0d9c1 100644 --- a/api_docs/dashboard.mdx +++ b/api_docs/dashboard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dashboard title: "dashboard" image: https://source.unsplash.com/400x175/?github description: API docs for the dashboard plugin -date: 2024-11-29 +date: 2024-12-03 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 903919a7f5455..c268fdfdf2193 100644 --- a/api_docs/dashboard_enhanced.mdx +++ b/api_docs/dashboard_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dashboardEnhanced title: "dashboardEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the dashboardEnhanced plugin -date: 2024-11-29 +date: 2024-12-03 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 eb8a4921d88a6..318ea50da0b48 100644 --- a/api_docs/data.mdx +++ b/api_docs/data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/data title: "data" image: https://source.unsplash.com/400x175/?github description: API docs for the data plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data'] --- import dataObj from './data.devdocs.json'; diff --git a/api_docs/data_quality.mdx b/api_docs/data_quality.mdx index fe4b5c8f7e690..f00b1f0ffbedd 100644 --- a/api_docs/data_quality.mdx +++ b/api_docs/data_quality.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataQuality title: "dataQuality" image: https://source.unsplash.com/400x175/?github description: API docs for the dataQuality plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataQuality'] --- import dataQualityObj from './data_quality.devdocs.json'; diff --git a/api_docs/data_query.mdx b/api_docs/data_query.mdx index 06615c0c35754..e6a4c20b9451d 100644 --- a/api_docs/data_query.mdx +++ b/api_docs/data_query.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/data-query title: "data.query" image: https://source.unsplash.com/400x175/?github description: API docs for the data.query plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data.query'] --- import dataQueryObj from './data_query.devdocs.json'; diff --git a/api_docs/data_search.mdx b/api_docs/data_search.mdx index ab4073ec908d9..ace239d289721 100644 --- a/api_docs/data_search.mdx +++ b/api_docs/data_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/data-search title: "data.search" image: https://source.unsplash.com/400x175/?github description: API docs for the data.search plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data.search'] --- import dataSearchObj from './data_search.devdocs.json'; diff --git a/api_docs/data_usage.mdx b/api_docs/data_usage.mdx index a283472021c5c..ecf73aa12a4c4 100644 --- a/api_docs/data_usage.mdx +++ b/api_docs/data_usage.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataUsage title: "dataUsage" image: https://source.unsplash.com/400x175/?github description: API docs for the dataUsage plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataUsage'] --- import dataUsageObj from './data_usage.devdocs.json'; diff --git a/api_docs/data_view_editor.mdx b/api_docs/data_view_editor.mdx index 283f887c3f8db..d6af1159f4d8c 100644 --- a/api_docs/data_view_editor.mdx +++ b/api_docs/data_view_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViewEditor title: "dataViewEditor" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViewEditor plugin -date: 2024-11-29 +date: 2024-12-03 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 1a0a17b458b7b..d7f742560200e 100644 --- a/api_docs/data_view_field_editor.mdx +++ b/api_docs/data_view_field_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViewFieldEditor title: "dataViewFieldEditor" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViewFieldEditor plugin -date: 2024-11-29 +date: 2024-12-03 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 fc3ae0e29deae..0a652e4195687 100644 --- a/api_docs/data_view_management.mdx +++ b/api_docs/data_view_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViewManagement title: "dataViewManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViewManagement plugin -date: 2024-11-29 +date: 2024-12-03 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 1eeae1ab42f1f..16737110a6685 100644 --- a/api_docs/data_views.mdx +++ b/api_docs/data_views.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViews title: "dataViews" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViews plugin -date: 2024-11-29 +date: 2024-12-03 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 e14561b36e851..e6599d0884ebf 100644 --- a/api_docs/data_visualizer.mdx +++ b/api_docs/data_visualizer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataVisualizer title: "dataVisualizer" image: https://source.unsplash.com/400x175/?github description: API docs for the dataVisualizer plugin -date: 2024-11-29 +date: 2024-12-03 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 f6d641e428113..d160859f49a93 100644 --- a/api_docs/dataset_quality.devdocs.json +++ b/api_docs/dataset_quality.devdocs.json @@ -311,6 +311,24 @@ "DatasetQualityRouteHandlerResources", ", { isFieldLimitIssue: boolean; fieldCount: number; totalFieldLimit: number; } & { ignoreMalformed?: boolean | undefined; nestedFieldLimit?: number | undefined; fieldMapping?: { type?: string | undefined; ignore_above?: number | undefined; } | undefined; defaultPipeline?: string | undefined; }, ", "DatasetQualityRouteCreateOptions", + ">; \"GET /internal/dataset_quality/data_streams/{dataStream}/integration/check\": ", + { + "pluginId": "@kbn/server-route-repository-utils", + "scope": "common", + "docId": "kibKbnServerRouteRepositoryUtilsPluginApi", + "section": "def-common.ServerRoute", + "text": "ServerRoute" + }, + "<\"GET /internal/dataset_quality/data_streams/{dataStream}/integration/check\", ", + "TypeC", + "<{ path: ", + "TypeC", + "<{ dataStream: ", + "StringC", + "; }>; }>, ", + "DatasetQualityRouteHandlerResources", + ", { isIntegration: false; areAssetsAvailable: boolean; } | { isIntegration: true; areAssetsAvailable: true; integration: { name: string; } & { title?: string | undefined; version?: string | undefined; icons?: ({ src: string; } & { path?: string | undefined; size?: string | undefined; title?: string | undefined; type?: string | undefined; })[] | undefined; datasets?: { [x: string]: string; } | undefined; }; }, ", + "DatasetQualityRouteCreateOptions", ">; \"GET /internal/dataset_quality/data_streams/{dataStream}/settings\": ", { "pluginId": "@kbn/server-route-repository-utils", @@ -678,6 +696,24 @@ "DatasetQualityRouteHandlerResources", ", { isFieldLimitIssue: boolean; fieldCount: number; totalFieldLimit: number; } & { ignoreMalformed?: boolean | undefined; nestedFieldLimit?: number | undefined; fieldMapping?: { type?: string | undefined; ignore_above?: number | undefined; } | undefined; defaultPipeline?: string | undefined; }, ", "DatasetQualityRouteCreateOptions", + ">; \"GET /internal/dataset_quality/data_streams/{dataStream}/integration/check\": ", + { + "pluginId": "@kbn/server-route-repository-utils", + "scope": "common", + "docId": "kibKbnServerRouteRepositoryUtilsPluginApi", + "section": "def-common.ServerRoute", + "text": "ServerRoute" + }, + "<\"GET /internal/dataset_quality/data_streams/{dataStream}/integration/check\", ", + "TypeC", + "<{ path: ", + "TypeC", + "<{ dataStream: ", + "StringC", + "; }>; }>, ", + "DatasetQualityRouteHandlerResources", + ", { isIntegration: false; areAssetsAvailable: boolean; } | { isIntegration: true; areAssetsAvailable: true; integration: { name: string; } & { title?: string | undefined; version?: string | undefined; icons?: ({ src: string; } & { path?: string | undefined; size?: string | undefined; title?: string | undefined; type?: string | undefined; })[] | undefined; datasets?: { [x: string]: string; } | undefined; }; }, ", + "DatasetQualityRouteCreateOptions", ">; \"GET /internal/dataset_quality/data_streams/{dataStream}/settings\": ", { "pluginId": "@kbn/server-route-repository-utils", diff --git a/api_docs/dataset_quality.mdx b/api_docs/dataset_quality.mdx index 9a669e0c5dc58..c829741bc56c9 100644 --- a/api_docs/dataset_quality.mdx +++ b/api_docs/dataset_quality.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/datasetQuality title: "datasetQuality" image: https://source.unsplash.com/400x175/?github description: API docs for the datasetQuality plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'datasetQuality'] --- import datasetQualityObj from './dataset_quality.devdocs.json'; diff --git a/api_docs/deprecations_by_api.mdx b/api_docs/deprecations_by_api.mdx index 6aa9068d4ff3a..0d4d75b73171e 100644 --- a/api_docs/deprecations_by_api.mdx +++ b/api_docs/deprecations_by_api.mdx @@ -7,7 +7,7 @@ id: kibDevDocsDeprecationsByApi slug: /kibana-dev-docs/api-meta/deprecated-api-list-by-api title: Deprecated API usage by API description: A list of deprecated APIs, which plugins are still referencing them, and when they need to be removed by. -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- @@ -171,7 +171,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | reporting | - | | | reporting | - | | | @kbn/reporting-export-types-pdf | - | -| | security, aiops, licenseManagement, ml, crossClusterReplication, logstash, painlessLab, searchprofiler, watcher, profiling, slo | 8.8.0 | +| | security, aiops, licenseManagement, ml, crossClusterReplication, logstash, painlessLab, searchprofiler, watcher, slo | 8.8.0 | | | spaces, security, actions, alerting, aiops, remoteClusters, ml, graph, indexLifecycleManagement, osquery, securitySolution, painlessLab, rollup, searchprofiler, snapshotRestore, transform, upgradeAssistant | 8.8.0 | | | fleet, apm, security, securitySolution | 8.8.0 | | | fleet, apm, security, securitySolution | 8.8.0 | diff --git a/api_docs/deprecations_by_plugin.mdx b/api_docs/deprecations_by_plugin.mdx index 202ce1fe1c489..d38e73008c019 100644 --- a/api_docs/deprecations_by_plugin.mdx +++ b/api_docs/deprecations_by_plugin.mdx @@ -7,7 +7,7 @@ id: kibDevDocsDeprecationsByPlugin slug: /kibana-dev-docs/api-meta/deprecated-api-list-by-plugin title: Deprecated API usage by plugin description: A list of deprecated APIs, which plugins are still referencing them, and when they need to be removed by. -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- @@ -1163,7 +1163,6 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | Deprecated API | Reference location(s) | Remove By | | ---------------|-----------|-----------| -| | [license_context.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/observability_solution/profiling/public/components/contexts/license/license_context.tsx#:~:text=license%24) | 8.8.0 | | | [get_has_setup_privileges.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/observability_solution/profiling/server/lib/setup/get_has_setup_privileges.ts#:~:text=get), [get_has_setup_privileges.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/observability_solution/profiling/server/lib/setup/get_has_setup_privileges.ts#:~:text=get), [get_has_setup_privileges.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/observability_solution/profiling/server/lib/setup/get_has_setup_privileges.ts#:~:text=get), [get_has_setup_privileges.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/observability_solution/profiling/server/lib/setup/get_has_setup_privileges.ts#:~:text=get) | - | diff --git a/api_docs/deprecations_by_team.mdx b/api_docs/deprecations_by_team.mdx index eb7d933e7731c..c42ccc11a88b8 100644 --- a/api_docs/deprecations_by_team.mdx +++ b/api_docs/deprecations_by_team.mdx @@ -7,7 +7,7 @@ id: kibDevDocsDeprecationsDueByTeam slug: /kibana-dev-docs/api-meta/deprecations-due-by-team title: Deprecated APIs due to be removed, by team description: Lists the teams that are referencing deprecated APIs with a remove by date. -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- @@ -99,7 +99,6 @@ migrates to using the Kibana Privilege model: https://github.com/elastic/kibana/ | --------|-------|-----------|-----------| | apm | | [license_check.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/observability_solution/apm/common/license_check.test.ts#:~:text=mode), [license_check.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/observability_solution/apm/common/license_check.test.ts#:~:text=mode), [license_check.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/observability_solution/apm/common/license_check.test.ts#:~:text=mode), [license_check.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/observability_solution/apm/common/license_check.test.ts#:~:text=mode), [license_check.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/observability_solution/apm/common/license_check.test.ts#:~:text=mode), [license_check.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/observability_solution/apm/common/license_check.test.ts#:~:text=mode), [license_check.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/observability_solution/apm/common/license_check.test.ts#:~:text=mode), [license_check.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/observability_solution/apm/common/license_check.test.ts#:~:text=mode), [license_check.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/observability_solution/apm/common/license_check.test.ts#:~:text=mode), [license_check.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/observability_solution/apm/common/license_check.test.ts#:~:text=mode)+ 2 more | 8.8.0 | | apm | | [license_check.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/observability_solution/apm/common/license_check.test.ts#:~:text=mode), [license_check.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/observability_solution/apm/common/license_check.test.ts#:~:text=mode), [license_check.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/observability_solution/apm/common/license_check.test.ts#:~:text=mode), [license_check.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/observability_solution/apm/common/license_check.test.ts#:~:text=mode), [license_check.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/observability_solution/apm/common/license_check.test.ts#:~:text=mode), [license_check.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/observability_solution/apm/common/license_check.test.ts#:~:text=mode), [license_check.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/observability_solution/apm/common/license_check.test.ts#:~:text=mode), [license_check.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/observability_solution/apm/common/license_check.test.ts#:~:text=mode), [license_check.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/observability_solution/apm/common/license_check.test.ts#:~:text=mode), [license_check.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/observability_solution/apm/common/license_check.test.ts#:~:text=mode)+ 2 more | 8.8.0 | -| profiling | | [license_context.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/observability_solution/profiling/public/components/contexts/license/license_context.tsx#:~:text=license%24) | 8.8.0 | diff --git a/api_docs/dev_tools.mdx b/api_docs/dev_tools.mdx index 60b0b1f6b0efd..0b3e9a7f75b68 100644 --- a/api_docs/dev_tools.mdx +++ b/api_docs/dev_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/devTools title: "devTools" image: https://source.unsplash.com/400x175/?github description: API docs for the devTools plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'devTools'] --- import devToolsObj from './dev_tools.devdocs.json'; diff --git a/api_docs/discover.devdocs.json b/api_docs/discover.devdocs.json index 2eb8c1f28f089..51ca924813168 100644 --- a/api_docs/discover.devdocs.json +++ b/api_docs/discover.devdocs.json @@ -800,6 +800,1449 @@ ], "initialIsOpen": false }, + { + "parentPluginId": "discover", + "id": "def-public.DiscoverServices", + "type": "Interface", + "tags": [], + "label": "DiscoverServices", + "description": [], + "path": "src/plugins/discover/public/build_services.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "discover", + "id": "def-public.DiscoverServices.aiops", + "type": "Object", + "tags": [], + "label": "aiops", + "description": [], + "signature": [ + { + "pluginId": "aiops", + "scope": "public", + "docId": "kibAiopsPluginApi", + "section": "def-public.AiopsPluginStart", + "text": "AiopsPluginStart" + }, + " | undefined" + ], + "path": "src/plugins/discover/public/build_services.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "discover", + "id": "def-public.DiscoverServices.application", + "type": "Object", + "tags": [], + "label": "application", + "description": [], + "signature": [ + { + "pluginId": "@kbn/core-application-browser", + "scope": "public", + "docId": "kibKbnCoreApplicationBrowserPluginApi", + "section": "def-public.ApplicationStart", + "text": "ApplicationStart" + } + ], + "path": "src/plugins/discover/public/build_services.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "discover", + "id": "def-public.DiscoverServices.addBasePath", + "type": "Function", + "tags": [], + "label": "addBasePath", + "description": [], + "signature": [ + "(path: string) => string" + ], + "path": "src/plugins/discover/public/build_services.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "discover", + "id": "def-public.DiscoverServices.addBasePath.$1", + "type": "string", + "tags": [], + "label": "path", + "description": [], + "signature": [ + "string" + ], + "path": "src/plugins/discover/public/build_services.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "discover", + "id": "def-public.DiscoverServices.analytics", + "type": "Object", + "tags": [], + "label": "analytics", + "description": [], + "signature": [ + "{ optIn: (optInConfig: ", + "OptInConfig", + ") => void; reportEvent: (eventType: string, eventData: EventTypeData) => void; readonly telemetryCounter$: ", + "Observable", + "<", + "TelemetryCounter", + ">; }" + ], + "path": "src/plugins/discover/public/build_services.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "discover", + "id": "def-public.DiscoverServices.i18n", + "type": "Object", + "tags": [], + "label": "i18n", + "description": [], + "signature": [ + { + "pluginId": "@kbn/core-i18n-browser", + "scope": "public", + "docId": "kibKbnCoreI18nBrowserPluginApi", + "section": "def-public.I18nStart", + "text": "I18nStart" + } + ], + "path": "src/plugins/discover/public/build_services.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "discover", + "id": "def-public.DiscoverServices.capabilities", + "type": "Object", + "tags": [], + "label": "capabilities", + "description": [], + "signature": [ + { + "pluginId": "@kbn/core-capabilities-common", + "scope": "common", + "docId": "kibKbnCoreCapabilitiesCommonPluginApi", + "section": "def-common.Capabilities", + "text": "Capabilities" + } + ], + "path": "src/plugins/discover/public/build_services.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "discover", + "id": "def-public.DiscoverServices.chrome", + "type": "Object", + "tags": [], + "label": "chrome", + "description": [], + "signature": [ + { + "pluginId": "@kbn/core-chrome-browser", + "scope": "public", + "docId": "kibKbnCoreChromeBrowserPluginApi", + "section": "def-public.ChromeStart", + "text": "ChromeStart" + } + ], + "path": "src/plugins/discover/public/build_services.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "discover", + "id": "def-public.DiscoverServices.core", + "type": "Object", + "tags": [], + "label": "core", + "description": [], + "signature": [ + { + "pluginId": "@kbn/core-lifecycle-browser", + "scope": "public", + "docId": "kibKbnCoreLifecycleBrowserPluginApi", + "section": "def-public.CoreStart", + "text": "CoreStart" + } + ], + "path": "src/plugins/discover/public/build_services.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "discover", + "id": "def-public.DiscoverServices.data", + "type": "Object", + "tags": [], + "label": "data", + "description": [], + "signature": [ + { + "pluginId": "data", + "scope": "public", + "docId": "kibDataPluginApi", + "section": "def-public.DataPublicPluginStart", + "text": "DataPublicPluginStart" + } + ], + "path": "src/plugins/discover/public/build_services.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "discover", + "id": "def-public.DiscoverServices.discoverShared", + "type": "Object", + "tags": [], + "label": "discoverShared", + "description": [], + "signature": [ + { + "pluginId": "discoverShared", + "scope": "public", + "docId": "kibDiscoverSharedPluginApi", + "section": "def-public.DiscoverSharedPublicStart", + "text": "DiscoverSharedPublicStart" + } + ], + "path": "src/plugins/discover/public/build_services.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "discover", + "id": "def-public.DiscoverServices.docLinks", + "type": "Object", + "tags": [], + "label": "docLinks", + "description": [], + "signature": [ + { + "pluginId": "@kbn/core-doc-links-browser", + "scope": "public", + "docId": "kibKbnCoreDocLinksBrowserPluginApi", + "section": "def-public.DocLinksStart", + "text": "DocLinksStart" + } + ], + "path": "src/plugins/discover/public/build_services.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "discover", + "id": "def-public.DiscoverServices.embeddable", + "type": "Object", + "tags": [], + "label": "embeddable", + "description": [], + "signature": [ + { + "pluginId": "embeddable", + "scope": "public", + "docId": "kibEmbeddablePluginApi", + "section": "def-public.EmbeddableStart", + "text": "EmbeddableStart" + } + ], + "path": "src/plugins/discover/public/build_services.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "discover", + "id": "def-public.DiscoverServices.history", + "type": "Object", + "tags": [], + "label": "history", + "description": [], + "signature": [ + "History", + "<", + "HistoryLocationState", + ">" + ], + "path": "src/plugins/discover/public/build_services.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "discover", + "id": "def-public.DiscoverServices.getScopedHistory", + "type": "Function", + "tags": [], + "label": "getScopedHistory", + "description": [], + "signature": [ + "() => ", + { + "pluginId": "@kbn/core-application-browser", + "scope": "public", + "docId": "kibKbnCoreApplicationBrowserPluginApi", + "section": "def-public.ScopedHistory", + "text": "ScopedHistory" + }, + " | undefined" + ], + "path": "src/plugins/discover/public/build_services.ts", + "deprecated": false, + "trackAdoption": false, + "children": [], + "returnComment": [] + }, + { + "parentPluginId": "discover", + "id": "def-public.DiscoverServices.setHeaderActionMenu", + "type": "Function", + "tags": [], + "label": "setHeaderActionMenu", + "description": [], + "signature": [ + "(menuMount: ", + { + "pluginId": "@kbn/core-mount-utils-browser", + "scope": "public", + "docId": "kibKbnCoreMountUtilsBrowserPluginApi", + "section": "def-public.MountPoint", + "text": "MountPoint" + }, + " | undefined) => void" + ], + "path": "src/plugins/discover/public/build_services.ts", + "deprecated": false, + "trackAdoption": false, + "returnComment": [], + "children": [ + { + "parentPluginId": "discover", + "id": "def-public.DiscoverServices.setHeaderActionMenu.$1", + "type": "Function", + "tags": [], + "label": "menuMount", + "description": [], + "signature": [ + { + "pluginId": "@kbn/core-mount-utils-browser", + "scope": "public", + "docId": "kibKbnCoreMountUtilsBrowserPluginApi", + "section": "def-public.MountPoint", + "text": "MountPoint" + }, + " | undefined" + ], + "path": "packages/core/application/core-application-browser/src/app_mount.ts", + "deprecated": false, + "trackAdoption": false + } + ] + }, + { + "parentPluginId": "discover", + "id": "def-public.DiscoverServices.theme", + "type": "Object", + "tags": [], + "label": "theme", + "description": [], + "signature": [ + { + "pluginId": "@kbn/core-theme-browser", + "scope": "public", + "docId": "kibKbnCoreThemeBrowserPluginApi", + "section": "def-public.ThemeServiceSetup", + "text": "ThemeServiceSetup" + } + ], + "path": "src/plugins/discover/public/build_services.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "discover", + "id": "def-public.DiscoverServices.filterManager", + "type": "Object", + "tags": [], + "label": "filterManager", + "description": [], + "signature": [ + { + "pluginId": "data", + "scope": "public", + "docId": "kibDataQueryPluginApi", + "section": "def-public.FilterManager", + "text": "FilterManager" + } + ], + "path": "src/plugins/discover/public/build_services.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "discover", + "id": "def-public.DiscoverServices.fieldFormats", + "type": "CompoundType", + "tags": [], + "label": "fieldFormats", + "description": [], + "signature": [ + "Omit<", + { + "pluginId": "fieldFormats", + "scope": "common", + "docId": "kibFieldFormatsPluginApi", + "section": "def-common.FieldFormatsRegistry", + "text": "FieldFormatsRegistry" + }, + ", \"init\" | \"register\"> & { deserialize: ", + { + "pluginId": "fieldFormats", + "scope": "common", + "docId": "kibFieldFormatsPluginApi", + "section": "def-common.FormatFactory", + "text": "FormatFactory" + }, + "; }" + ], + "path": "src/plugins/discover/public/build_services.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "discover", + "id": "def-public.DiscoverServices.dataViews", + "type": "Object", + "tags": [], + "label": "dataViews", + "description": [], + "signature": [ + { + "pluginId": "dataViews", + "scope": "public", + "docId": "kibDataViewsPluginApi", + "section": "def-public.DataViewsServicePublic", + "text": "DataViewsServicePublic" + } + ], + "path": "src/plugins/discover/public/build_services.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "discover", + "id": "def-public.DiscoverServices.inspector", + "type": "Object", + "tags": [], + "label": "inspector", + "description": [], + "signature": [ + { + "pluginId": "inspector", + "scope": "public", + "docId": "kibInspectorPluginApi", + "section": "def-public.Start", + "text": "Start" + } + ], + "path": "src/plugins/discover/public/build_services.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "discover", + "id": "def-public.DiscoverServices.metadata", + "type": "Object", + "tags": [], + "label": "metadata", + "description": [], + "signature": [ + "{ branch: string; }" + ], + "path": "src/plugins/discover/public/build_services.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "discover", + "id": "def-public.DiscoverServices.navigation", + "type": "Object", + "tags": [], + "label": "navigation", + "description": [], + "signature": [ + { + "pluginId": "navigation", + "scope": "public", + "docId": "kibNavigationPluginApi", + "section": "def-public.NavigationPublicStart", + "text": "NavigationPublicStart" + } + ], + "path": "src/plugins/discover/public/build_services.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "discover", + "id": "def-public.DiscoverServices.share", + "type": "CompoundType", + "tags": [], + "label": "share", + "description": [], + "signature": [ + { + "pluginId": "share", + "scope": "public", + "docId": "kibSharePluginApi", + "section": "def-public.SharePublicStart", + "text": "SharePublicStart" + }, + " | undefined" + ], + "path": "src/plugins/discover/public/build_services.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "discover", + "id": "def-public.DiscoverServices.urlForwarding", + "type": "Object", + "tags": [], + "label": "urlForwarding", + "description": [], + "signature": [ + "{ navigateToLegacyKibanaUrl: (hash: string) => { navigated: boolean; }; getForwards: () => ", + { + "pluginId": "urlForwarding", + "scope": "public", + "docId": "kibUrlForwardingPluginApi", + "section": "def-public.ForwardDefinition", + "text": "ForwardDefinition" + }, + "[]; }" + ], + "path": "src/plugins/discover/public/build_services.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "discover", + "id": "def-public.DiscoverServices.urlTracker", + "type": "Object", + "tags": [], + "label": "urlTracker", + "description": [], + "signature": [ + "UrlTracker" + ], + "path": "src/plugins/discover/public/build_services.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "discover", + "id": "def-public.DiscoverServices.timefilter", + "type": "Object", + "tags": [], + "label": "timefilter", + "description": [], + "signature": [ + "{ isTimeRangeSelectorEnabled: () => boolean; isAutoRefreshSelectorEnabled: () => boolean; isTimeTouched: () => boolean; isRefreshIntervalTouched: () => boolean; getEnabledUpdated$: () => ", + "Observable", + "; getTimeUpdate$: () => ", + "Observable", + "; getRefreshIntervalUpdate$: () => ", + "Observable", + "; getAutoRefreshFetch$: () => ", + "Observable", + "<", + { + "pluginId": "data", + "scope": "public", + "docId": "kibDataQueryPluginApi", + "section": "def-public.AutoRefreshDoneFn", + "text": "AutoRefreshDoneFn" + }, + ">; getFetch$: () => ", + "Observable", + "; getTime: () => ", + { + "pluginId": "@kbn/es-query", + "scope": "common", + "docId": "kibKbnEsQueryPluginApi", + "section": "def-common.TimeRange", + "text": "TimeRange" + }, + "; getAbsoluteTime: () => ", + { + "pluginId": "@kbn/es-query", + "scope": "common", + "docId": "kibKbnEsQueryPluginApi", + "section": "def-common.TimeRange", + "text": "TimeRange" + }, + "; setTime: (time: ", + "InputTimeRange", + ") => void; getRefreshInterval: () => ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataQueryPluginApi", + "section": "def-common.RefreshInterval", + "text": "RefreshInterval" + }, + "; getMinRefreshInterval: () => number; setRefreshInterval: (refreshInterval: Partial<", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataQueryPluginApi", + "section": "def-common.RefreshInterval", + "text": "RefreshInterval" + }, + ">) => void; createFilter: (indexPattern: ", + { + "pluginId": "dataViews", + "scope": "common", + "docId": "kibDataViewsPluginApi", + "section": "def-common.DataView", + "text": "DataView" + }, + ", timeRange?: ", + { + "pluginId": "@kbn/es-query", + "scope": "common", + "docId": "kibKbnEsQueryPluginApi", + "section": "def-common.TimeRange", + "text": "TimeRange" + }, + " | undefined) => ", + { + "pluginId": "@kbn/es-query", + "scope": "common", + "docId": "kibKbnEsQueryPluginApi", + "section": "def-common.RangeFilter", + "text": "RangeFilter" + }, + " | ", + { + "pluginId": "@kbn/es-query", + "scope": "common", + "docId": "kibKbnEsQueryPluginApi", + "section": "def-common.ScriptedRangeFilter", + "text": "ScriptedRangeFilter" + }, + " | ", + "MatchAllRangeFilter", + " | undefined; createRelativeFilter: (indexPattern: ", + { + "pluginId": "dataViews", + "scope": "common", + "docId": "kibDataViewsPluginApi", + "section": "def-common.DataView", + "text": "DataView" + }, + ", timeRange?: ", + { + "pluginId": "@kbn/es-query", + "scope": "common", + "docId": "kibKbnEsQueryPluginApi", + "section": "def-common.TimeRange", + "text": "TimeRange" + }, + " | undefined) => ", + { + "pluginId": "@kbn/es-query", + "scope": "common", + "docId": "kibKbnEsQueryPluginApi", + "section": "def-common.RangeFilter", + "text": "RangeFilter" + }, + " | ", + { + "pluginId": "@kbn/es-query", + "scope": "common", + "docId": "kibKbnEsQueryPluginApi", + "section": "def-common.ScriptedRangeFilter", + "text": "ScriptedRangeFilter" + }, + " | ", + "MatchAllRangeFilter", + " | undefined; getBounds: () => ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataQueryPluginApi", + "section": "def-common.TimeRangeBounds", + "text": "TimeRangeBounds" + }, + "; calculateBounds: (timeRange: ", + { + "pluginId": "@kbn/es-query", + "scope": "common", + "docId": "kibKbnEsQueryPluginApi", + "section": "def-common.TimeRange", + "text": "TimeRange" + }, + ") => ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataQueryPluginApi", + "section": "def-common.TimeRangeBounds", + "text": "TimeRangeBounds" + }, + "; getActiveBounds: () => ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataQueryPluginApi", + "section": "def-common.TimeRangeBounds", + "text": "TimeRangeBounds" + }, + " | undefined; enableTimeRangeSelector: () => void; disableTimeRangeSelector: () => void; enableAutoRefreshSelector: () => void; disableAutoRefreshSelector: () => void; getTimeDefaults: () => ", + { + "pluginId": "@kbn/es-query", + "scope": "common", + "docId": "kibKbnEsQueryPluginApi", + "section": "def-common.TimeRange", + "text": "TimeRange" + }, + "; getRefreshIntervalDefaults: () => ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataQueryPluginApi", + "section": "def-common.RefreshInterval", + "text": "RefreshInterval" + }, + "; }" + ], + "path": "src/plugins/discover/public/build_services.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "discover", + "id": "def-public.DiscoverServices.toastNotifications", + "type": "Object", + "tags": [], + "label": "toastNotifications", + "description": [], + "signature": [ + { + "pluginId": "@kbn/core-notifications-browser", + "scope": "public", + "docId": "kibKbnCoreNotificationsBrowserPluginApi", + "section": "def-public.IToasts", + "text": "IToasts" + } + ], + "path": "src/plugins/discover/public/build_services.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "discover", + "id": "def-public.DiscoverServices.notifications", + "type": "Object", + "tags": [], + "label": "notifications", + "description": [], + "signature": [ + { + "pluginId": "@kbn/core-notifications-browser", + "scope": "public", + "docId": "kibKbnCoreNotificationsBrowserPluginApi", + "section": "def-public.NotificationsStart", + "text": "NotificationsStart" + } + ], + "path": "src/plugins/discover/public/build_services.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "discover", + "id": "def-public.DiscoverServices.uiSettings", + "type": "Object", + "tags": [], + "label": "uiSettings", + "description": [], + "signature": [ + { + "pluginId": "@kbn/core-ui-settings-browser", + "scope": "public", + "docId": "kibKbnCoreUiSettingsBrowserPluginApi", + "section": "def-public.IUiSettingsClient", + "text": "IUiSettingsClient" + } + ], + "path": "src/plugins/discover/public/build_services.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "discover", + "id": "def-public.DiscoverServices.settings", + "type": "Object", + "tags": [], + "label": "settings", + "description": [], + "signature": [ + { + "pluginId": "@kbn/core-ui-settings-browser", + "scope": "public", + "docId": "kibKbnCoreUiSettingsBrowserPluginApi", + "section": "def-public.SettingsStart", + "text": "SettingsStart" + } + ], + "path": "src/plugins/discover/public/build_services.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "discover", + "id": "def-public.DiscoverServices.trackUiMetric", + "type": "Function", + "tags": [], + "label": "trackUiMetric", + "description": [], + "signature": [ + "((metricType: string, eventName: string | string[]) => void) | undefined" + ], + "path": "src/plugins/discover/public/build_services.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "discover", + "id": "def-public.DiscoverServices.trackUiMetric.$1", + "type": "string", + "tags": [], + "label": "metricType", + "description": [], + "signature": [ + "string" + ], + "path": "src/plugins/discover/public/build_services.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "discover", + "id": "def-public.DiscoverServices.trackUiMetric.$2", + "type": "CompoundType", + "tags": [], + "label": "eventName", + "description": [], + "signature": [ + "string | string[]" + ], + "path": "src/plugins/discover/public/build_services.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "discover", + "id": "def-public.DiscoverServices.dataViewFieldEditor", + "type": "Object", + "tags": [], + "label": "dataViewFieldEditor", + "description": [], + "signature": [ + { + "pluginId": "dataViewFieldEditor", + "scope": "public", + "docId": "kibDataViewFieldEditorPluginApi", + "section": "def-public.PluginStart", + "text": "PluginStart" + } + ], + "path": "src/plugins/discover/public/build_services.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "discover", + "id": "def-public.DiscoverServices.dataViewEditor", + "type": "Object", + "tags": [], + "label": "dataViewEditor", + "description": [], + "signature": [ + { + "pluginId": "dataViewEditor", + "scope": "public", + "docId": "kibDataViewEditorPluginApi", + "section": "def-public.PluginStart", + "text": "PluginStart" + } + ], + "path": "src/plugins/discover/public/build_services.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "discover", + "id": "def-public.DiscoverServices.dataVisualizer", + "type": "Object", + "tags": [], + "label": "dataVisualizer", + "description": [], + "signature": [ + "{ getFileDataVisualizerComponent: () => Promise<() => ", + "SpecWithLinks", + ">>; getIndexDataVisualizerComponent: () => Promise<() => React.FC<", + "Props", + ">>; getDataDriftComponent: () => Promise<() => React.FC<", + "DataDriftDetectionAppStateProps", + ">>; getMaxBytesFormatted: () => string; FieldStatsUnavailableMessage: React.ForwardRefExoticComponent<{ id?: string | undefined; title?: string | undefined; } & React.RefAttributes<{}>>; FieldStatisticsTable: React.ForwardRefExoticComponent<", + "FieldStatisticTableEmbeddableProps", + " & React.RefAttributes<{}>>; } | undefined" + ], + "path": "src/plugins/discover/public/build_services.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "discover", + "id": "def-public.DiscoverServices.http", + "type": "Object", + "tags": [], + "label": "http", + "description": [], + "signature": [ + { + "pluginId": "@kbn/core-http-browser", + "scope": "public", + "docId": "kibKbnCoreHttpBrowserPluginApi", + "section": "def-public.HttpSetup", + "text": "HttpSetup" + } + ], + "path": "src/plugins/discover/public/build_services.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "discover", + "id": "def-public.DiscoverServices.storage", + "type": "Object", + "tags": [], + "label": "storage", + "description": [], + "signature": [ + { + "pluginId": "kibanaUtils", + "scope": "public", + "docId": "kibKibanaUtilsPluginApi", + "section": "def-public.Storage", + "text": "Storage" + } + ], + "path": "src/plugins/discover/public/build_services.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "discover", + "id": "def-public.DiscoverServices.spaces", + "type": "Object", + "tags": [], + "label": "spaces", + "description": [], + "signature": [ + { + "pluginId": "spaces", + "scope": "public", + "docId": "kibSpacesPluginApi", + "section": "def-public.SpacesApi", + "text": "SpacesApi" + }, + " | undefined" + ], + "path": "src/plugins/discover/public/build_services.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "discover", + "id": "def-public.DiscoverServices.triggersActionsUi", + "type": "Object", + "tags": [], + "label": "triggersActionsUi", + "description": [], + "signature": [ + { + "pluginId": "triggersActionsUi", + "scope": "public", + "docId": "kibTriggersActionsUiPluginApi", + "section": "def-public.TriggersAndActionsUIPublicPluginStart", + "text": "TriggersAndActionsUIPublicPluginStart" + } + ], + "path": "src/plugins/discover/public/build_services.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "discover", + "id": "def-public.DiscoverServices.locator", + "type": "Object", + "tags": [], + "label": "locator", + "description": [], + "signature": [ + { + "pluginId": "share", + "scope": "common", + "docId": "kibSharePluginApi", + "section": "def-common.LocatorPublic", + "text": "LocatorPublic" + }, + "<", + { + "pluginId": "discover", + "scope": "common", + "docId": "kibDiscoverPluginApi", + "section": "def-common.DiscoverAppLocatorParams", + "text": "DiscoverAppLocatorParams" + }, + ">" + ], + "path": "src/plugins/discover/public/build_services.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "discover", + "id": "def-public.DiscoverServices.contextLocator", + "type": "Object", + "tags": [], + "label": "contextLocator", + "description": [], + "signature": [ + { + "pluginId": "share", + "scope": "common", + "docId": "kibSharePluginApi", + "section": "def-common.LocatorPublic", + "text": "LocatorPublic" + }, + "<", + "DiscoverContextAppLocatorParams", + ">" + ], + "path": "src/plugins/discover/public/build_services.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "discover", + "id": "def-public.DiscoverServices.singleDocLocator", + "type": "Object", + "tags": [], + "label": "singleDocLocator", + "description": [], + "signature": [ + { + "pluginId": "share", + "scope": "common", + "docId": "kibSharePluginApi", + "section": "def-common.LocatorPublic", + "text": "LocatorPublic" + }, + "<", + "DiscoverSingleDocLocatorParams", + ">" + ], + "path": "src/plugins/discover/public/build_services.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "discover", + "id": "def-public.DiscoverServices.expressions", + "type": "Object", + "tags": [], + "label": "expressions", + "description": [], + "signature": [ + { + "pluginId": "expressions", + "scope": "public", + "docId": "kibExpressionsPluginApi", + "section": "def-public.ExpressionsStart", + "text": "ExpressionsStart" + } + ], + "path": "src/plugins/discover/public/build_services.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "discover", + "id": "def-public.DiscoverServices.charts", + "type": "CompoundType", + "tags": [], + "label": "charts", + "description": [], + "signature": [ + { + "pluginId": "charts", + "scope": "public", + "docId": "kibChartsPluginApi", + "section": "def-public.ChartsPluginSetup", + "text": "ChartsPluginSetup" + }, + " & { activeCursor: ", + "ActiveCursor", + "; }" + ], + "path": "src/plugins/discover/public/build_services.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "discover", + "id": "def-public.DiscoverServices.savedObjectsManagement", + "type": "Object", + "tags": [], + "label": "savedObjectsManagement", + "description": [], + "signature": [ + { + "pluginId": "savedObjectsManagement", + "scope": "public", + "docId": "kibSavedObjectsManagementPluginApi", + "section": "def-public.SavedObjectsManagementPluginStart", + "text": "SavedObjectsManagementPluginStart" + } + ], + "path": "src/plugins/discover/public/build_services.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "discover", + "id": "def-public.DiscoverServices.savedObjectsTagging", + "type": "Object", + "tags": [], + "label": "savedObjectsTagging", + "description": [], + "signature": [ + { + "pluginId": "savedObjectsTaggingOss", + "scope": "public", + "docId": "kibSavedObjectsTaggingOssPluginApi", + "section": "def-public.SavedObjectsTaggingApi", + "text": "SavedObjectsTaggingApi" + }, + " | undefined" + ], + "path": "src/plugins/discover/public/build_services.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "discover", + "id": "def-public.DiscoverServices.savedSearch", + "type": "Object", + "tags": [], + "label": "savedSearch", + "description": [], + "signature": [ + { + "pluginId": "savedSearch", + "scope": "public", + "docId": "kibSavedSearchPluginApi", + "section": "def-public.SavedSearchPublicPluginStart", + "text": "SavedSearchPublicPluginStart" + } + ], + "path": "src/plugins/discover/public/build_services.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "discover", + "id": "def-public.DiscoverServices.unifiedSearch", + "type": "Object", + "tags": [], + "label": "unifiedSearch", + "description": [], + "signature": [ + { + "pluginId": "unifiedSearch", + "scope": "public", + "docId": "kibUnifiedSearchPluginApi", + "section": "def-public.UnifiedSearchPublicPluginStart", + "text": "UnifiedSearchPublicPluginStart" + } + ], + "path": "src/plugins/discover/public/build_services.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "discover", + "id": "def-public.DiscoverServices.lens", + "type": "Object", + "tags": [], + "label": "lens", + "description": [], + "signature": [ + { + "pluginId": "lens", + "scope": "public", + "docId": "kibLensPluginApi", + "section": "def-public.LensPublicStart", + "text": "LensPublicStart" + } + ], + "path": "src/plugins/discover/public/build_services.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "discover", + "id": "def-public.DiscoverServices.uiActions", + "type": "Object", + "tags": [], + "label": "uiActions", + "description": [], + "signature": [ + "{ readonly registerTrigger: (trigger: ", + { + "pluginId": "@kbn/ui-actions-browser", + "scope": "common", + "docId": "kibKbnUiActionsBrowserPluginApi", + "section": "def-common.Trigger", + "text": "Trigger" + }, + ") => void; readonly hasTrigger: (triggerId: string) => boolean; readonly getTrigger: (triggerId: string) => ", + "TriggerContract", + "; readonly registerAction: (definition: ", + { + "pluginId": "uiActions", + "scope": "public", + "docId": "kibUiActionsPluginApi", + "section": "def-public.ActionDefinition", + "text": "ActionDefinition" + }, + ") => ", + { + "pluginId": "uiActions", + "scope": "public", + "docId": "kibUiActionsPluginApi", + "section": "def-public.Action", + "text": "Action" + }, + "; 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": "uiActions", + "scope": "public", + "docId": "kibUiActionsPluginApi", + "section": "def-public.ActionDefinition", + "text": "ActionDefinition" + }, + ") => void; readonly getAction: (id: string) => ", + { + "pluginId": "uiActions", + "scope": "public", + "docId": "kibUiActionsPluginApi", + "section": "def-public.Action", + "text": "Action" + }, + "; readonly getTriggerActions: (triggerId: string) => ", + { + "pluginId": "uiActions", + "scope": "public", + "docId": "kibUiActionsPluginApi", + "section": "def-public.Action", + "text": "Action" + }, + "[]; readonly getTriggerCompatibleActions: (triggerId: string, context: object) => Promise<", + { + "pluginId": "uiActions", + "scope": "public", + "docId": "kibUiActionsPluginApi", + "section": "def-public.Action", + "text": "Action" + }, + "[]>; readonly getFrequentlyChangingActionsForTrigger: (triggerId: string, context: object) => ", + { + "pluginId": "uiActions", + "scope": "public", + "docId": "kibUiActionsPluginApi", + "section": "def-public.FrequentCompatibilityChangeAction", + "text": "FrequentCompatibilityChangeAction" + }, + "[]; readonly executeTriggerActions: (triggerId: string, context: object) => Promise; readonly clear: () => void; readonly fork: () => ", + { + "pluginId": "uiActions", + "scope": "public", + "docId": "kibUiActionsPluginApi", + "section": "def-public.UiActionsService", + "text": "UiActionsService" + }, + "; }" + ], + "path": "src/plugins/discover/public/build_services.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "discover", + "id": "def-public.DiscoverServices.contentClient", + "type": "Object", + "tags": [], + "label": "contentClient", + "description": [], + "signature": [ + { + "pluginId": "contentManagement", + "scope": "public", + "docId": "kibContentManagementPluginApi", + "section": "def-public.ContentClient", + "text": "ContentClient" + } + ], + "path": "src/plugins/discover/public/build_services.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "discover", + "id": "def-public.DiscoverServices.noDataPage", + "type": "Object", + "tags": [], + "label": "noDataPage", + "description": [], + "signature": [ + { + "pluginId": "noDataPage", + "scope": "public", + "docId": "kibNoDataPagePluginApi", + "section": "def-public.NoDataPagePublicSetup", + "text": "NoDataPagePublicSetup" + }, + " | undefined" + ], + "path": "src/plugins/discover/public/build_services.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "discover", + "id": "def-public.DiscoverServices.observabilityAIAssistant", + "type": "Object", + "tags": [], + "label": "observabilityAIAssistant", + "description": [], + "signature": [ + { + "pluginId": "observabilityAIAssistant", + "scope": "public", + "docId": "kibObservabilityAIAssistantPluginApi", + "section": "def-public.ObservabilityAIAssistantPublicStart", + "text": "ObservabilityAIAssistantPublicStart" + }, + " | undefined" + ], + "path": "src/plugins/discover/public/build_services.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "discover", + "id": "def-public.DiscoverServices.profilesManager", + "type": "Object", + "tags": [], + "label": "profilesManager", + "description": [], + "signature": [ + "ProfilesManager" + ], + "path": "src/plugins/discover/public/build_services.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "discover", + "id": "def-public.DiscoverServices.ebtManager", + "type": "Object", + "tags": [], + "label": "ebtManager", + "description": [], + "signature": [ + "DiscoverEBTManager" + ], + "path": "src/plugins/discover/public/build_services.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "discover", + "id": "def-public.DiscoverServices.fieldsMetadata", + "type": "Object", + "tags": [], + "label": "fieldsMetadata", + "description": [], + "signature": [ + { + "pluginId": "fieldsMetadata", + "scope": "public", + "docId": "kibFieldsMetadataPluginApi", + "section": "def-public.FieldsMetadataPublicStart", + "text": "FieldsMetadataPublicStart" + }, + " | undefined" + ], + "path": "src/plugins/discover/public/build_services.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "discover", + "id": "def-public.DiscoverServices.logsDataAccess", + "type": "Object", + "tags": [], + "label": "logsDataAccess", + "description": [], + "signature": [ + "{ services: { logSourcesService: ", + "LogSourcesService", + "; }; } | undefined" + ], + "path": "src/plugins/discover/public/build_services.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, { "parentPluginId": "discover", "id": "def-public.DiscoverStateContainer", @@ -1289,6 +2732,48 @@ ], "initialIsOpen": false }, + { + "parentPluginId": "discover", + "id": "def-public.NonPersistedDisplayOptions", + "type": "Interface", + "tags": [], + "label": "NonPersistedDisplayOptions", + "description": [], + "path": "src/plugins/discover/public/embeddable/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "discover", + "id": "def-public.NonPersistedDisplayOptions.enableDocumentViewer", + "type": "CompoundType", + "tags": [], + "label": "enableDocumentViewer", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "src/plugins/discover/public/embeddable/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "discover", + "id": "def-public.NonPersistedDisplayOptions.enableFilters", + "type": "CompoundType", + "tags": [], + "label": "enableFilters", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "src/plugins/discover/public/embeddable/types.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, { "parentPluginId": "discover", "id": "def-public.PublishesSavedSearch", @@ -1871,7 +3356,13 @@ "description": [], "signature": [ "{ isLoading?: boolean | undefined; overrideServices: Partial<", - "DiscoverServices", + { + "pluginId": "discover", + "scope": "public", + "docId": "kibDiscoverPluginApi", + "section": "def-public.DiscoverServices", + "text": "DiscoverServices" + }, ">; scopedHistory: ", { "pluginId": "@kbn/core-application-browser", @@ -1982,6 +3473,239 @@ "trackAdoption": false, "initialIsOpen": false }, + { + "parentPluginId": "discover", + "id": "def-public.SearchEmbeddableApi", + "type": "Type", + "tags": [], + "label": "SearchEmbeddableApi", + "description": [], + "signature": [ + { + "pluginId": "embeddable", + "scope": "public", + "docId": "kibEmbeddablePluginApi", + "section": "def-public.DefaultEmbeddableApi", + "text": "DefaultEmbeddableApi" + }, + "<", + { + "pluginId": "discover", + "scope": "public", + "docId": "kibDiscoverPluginApi", + "section": "def-public.SearchEmbeddableSerializedState", + "text": "SearchEmbeddableSerializedState" + }, + ", ", + { + "pluginId": "discover", + "scope": "public", + "docId": "kibDiscoverPluginApi", + "section": "def-public.SearchEmbeddableRuntimeState", + "text": "SearchEmbeddableRuntimeState" + }, + "> & ", + { + "pluginId": "@kbn/presentation-publishing", + "scope": "public", + "docId": "kibKbnPresentationPublishingPluginApi", + "section": "def-public.PublishesSavedObjectId", + "text": "PublishesSavedObjectId" + }, + " & ", + { + "pluginId": "@kbn/presentation-publishing", + "scope": "public", + "docId": "kibKbnPresentationPublishingPluginApi", + "section": "def-public.PublishesDataLoading", + "text": "PublishesDataLoading" + }, + " & ", + { + "pluginId": "@kbn/presentation-publishing", + "scope": "public", + "docId": "kibKbnPresentationPublishingPluginApi", + "section": "def-public.PublishesBlockingError", + "text": "PublishesBlockingError" + }, + " & ", + { + "pluginId": "@kbn/presentation-publishing", + "scope": "public", + "docId": "kibKbnPresentationPublishingPluginApi", + "section": "def-public.PublishesPanelTitle", + "text": "PublishesPanelTitle" + }, + " & { setPanelTitle: (newTitle: string | undefined) => void; setHidePanelTitle: (hide: boolean | undefined) => void; } & ", + { + "pluginId": "discover", + "scope": "public", + "docId": "kibDiscoverPluginApi", + "section": "def-public.PublishesSavedSearch", + "text": "PublishesSavedSearch" + }, + " & ", + { + "pluginId": "@kbn/presentation-publishing", + "scope": "public", + "docId": "kibKbnPresentationPublishingPluginApi", + "section": "def-public.PublishesDataViews", + "text": "PublishesDataViews" + }, + " & { setDataViews: (dataViews: ", + { + "pluginId": "dataViews", + "scope": "common", + "docId": "kibDataViewsPluginApi", + "section": "def-common.DataView", + "text": "DataView" + }, + "[]) => void; } & ", + { + "pluginId": "@kbn/presentation-publishing", + "scope": "public", + "docId": "kibKbnPresentationPublishingPluginApi", + "section": "def-public.PublishesTimeRange", + "text": "PublishesTimeRange" + }, + " & ", + { + "pluginId": "@kbn/presentation-publishing", + "scope": "public", + "docId": "kibKbnPresentationPublishingPluginApi", + "section": "def-public.PublishesFilters", + "text": "PublishesFilters" + }, + " & { isCompatibleWithUnifiedSearch?: (() => boolean) | undefined; query$: ", + { + "pluginId": "@kbn/presentation-publishing", + "scope": "public", + "docId": "kibKbnPresentationPublishingPluginApi", + "section": "def-public.PublishingSubject", + "text": "PublishingSubject" + }, + "<", + { + "pluginId": "@kbn/es-query", + "scope": "common", + "docId": "kibKbnEsQueryPluginApi", + "section": "def-common.Query", + "text": "Query" + }, + " | ", + { + "pluginId": "@kbn/es-query", + "scope": "common", + "docId": "kibKbnEsQueryPluginApi", + "section": "def-common.AggregateQuery", + "text": "AggregateQuery" + }, + " | undefined>; } & { setTimeRange: (timeRange: ", + { + "pluginId": "@kbn/es-query", + "scope": "common", + "docId": "kibKbnEsQueryPluginApi", + "section": "def-common.TimeRange", + "text": "TimeRange" + }, + " | undefined) => void; } & { setFilters: (filters: ", + { + "pluginId": "@kbn/es-query", + "scope": "common", + "docId": "kibKbnEsQueryPluginApi", + "section": "def-common.Filter", + "text": "Filter" + }, + "[] | undefined) => void; setQuery: (query: ", + { + "pluginId": "@kbn/es-query", + "scope": "common", + "docId": "kibKbnEsQueryPluginApi", + "section": "def-common.Query", + "text": "Query" + }, + " | undefined) => void; } & ", + { + "pluginId": "@kbn/presentation-publishing", + "scope": "public", + "docId": "kibKbnPresentationPublishingPluginApi", + "section": "def-public.HasInPlaceLibraryTransforms", + "text": "HasInPlaceLibraryTransforms" + }, + " & ", + { + "pluginId": "discover", + "scope": "public", + "docId": "kibDiscoverPluginApi", + "section": "def-public.HasTimeRange", + "text": "HasTimeRange" + }, + " & Partial<", + { + "pluginId": "@kbn/presentation-publishing", + "scope": "public", + "docId": "kibKbnPresentationPublishingPluginApi", + "section": "def-public.HasEditCapabilities", + "text": "HasEditCapabilities" + }, + " & ", + { + "pluginId": "@kbn/presentation-publishing", + "scope": "public", + "docId": "kibKbnPresentationPublishingPluginApi", + "section": "def-public.PublishesSavedObjectId", + "text": "PublishesSavedObjectId" + }, + ">" + ], + "path": "src/plugins/discover/public/embeddable/types.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "discover", + "id": "def-public.SearchEmbeddableRuntimeState", + "type": "Type", + "tags": [], + "label": "SearchEmbeddableRuntimeState", + "description": [], + "signature": [ + "Omit<", + "SearchEmbeddableState", + ", \"rows\" | \"searchSource\" | \"columnsMeta\" | \"totalHitCount\"> & Pick<", + "SerializableSavedSearch", + ", \"serializedSearchSource\"> & ", + { + "pluginId": "@kbn/presentation-publishing", + "scope": "public", + "docId": "kibKbnPresentationPublishingPluginApi", + "section": "def-public.SerializedTitles", + "text": "SerializedTitles" + }, + " & ", + { + "pluginId": "@kbn/presentation-publishing", + "scope": "public", + "docId": "kibKbnPresentationPublishingPluginApi", + "section": "def-public.SerializedTimeRange", + "text": "SerializedTimeRange" + }, + " & { savedObjectTitle?: string | undefined; savedObjectId?: string | undefined; savedObjectDescription?: string | undefined; nonPersistedDisplayOptions?: ", + { + "pluginId": "discover", + "scope": "public", + "docId": "kibDiscoverPluginApi", + "section": "def-public.NonPersistedDisplayOptions", + "text": "NonPersistedDisplayOptions" + }, + " | undefined; }" + ], + "path": "src/plugins/discover/public/embeddable/types.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "discover", "id": "def-public.SearchEmbeddableSerializedState", @@ -2019,7 +3743,15 @@ "section": "def-common.SavedObjectReference", "text": "SavedObjectReference" }, - "[] | undefined; }) | undefined; savedObjectId?: string | undefined; }" + "[] | undefined; }) | undefined; savedObjectId?: string | undefined; nonPersistedDisplayOptions?: ", + { + "pluginId": "discover", + "scope": "public", + "docId": "kibDiscoverPluginApi", + "section": "def-public.NonPersistedDisplayOptions", + "text": "NonPersistedDisplayOptions" + }, + " | undefined; }" ], "path": "src/plugins/discover/public/embeddable/types.ts", "deprecated": false, diff --git a/api_docs/discover.mdx b/api_docs/discover.mdx index efbc304eb2fbb..dc4c2a117f6c2 100644 --- a/api_docs/discover.mdx +++ b/api_docs/discover.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/discover title: "discover" image: https://source.unsplash.com/400x175/?github description: API docs for the discover plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'discover'] --- import discoverObj from './discover.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/k | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 148 | 0 | 100 | 24 | +| 214 | 0 | 166 | 30 | ## Client diff --git a/api_docs/discover_enhanced.mdx b/api_docs/discover_enhanced.mdx index e202e2e7bbab7..dd1634e549f7b 100644 --- a/api_docs/discover_enhanced.mdx +++ b/api_docs/discover_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/discoverEnhanced title: "discoverEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the discoverEnhanced plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'discoverEnhanced'] --- import discoverEnhancedObj from './discover_enhanced.devdocs.json'; diff --git a/api_docs/discover_shared.devdocs.json b/api_docs/discover_shared.devdocs.json index bc05a07a26fee..39dc71aa37b16 100644 --- a/api_docs/discover_shared.devdocs.json +++ b/api_docs/discover_shared.devdocs.json @@ -4,6 +4,94 @@ "classes": [], "functions": [], "interfaces": [ + { + "parentPluginId": "discoverShared", + "id": "def-public.DiscoverFeaturesServiceSetup", + "type": "Interface", + "tags": [], + "label": "DiscoverFeaturesServiceSetup", + "description": [ + "\nService types" + ], + "path": "src/plugins/discover_shared/public/services/discover_features/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "discoverShared", + "id": "def-public.DiscoverFeaturesServiceSetup.registry", + "type": "Object", + "tags": [], + "label": "registry", + "description": [], + "signature": [ + { + "pluginId": "discoverShared", + "scope": "common", + "docId": "kibDiscoverSharedPluginApi", + "section": "def-common.FeaturesRegistry", + "text": "FeaturesRegistry" + }, + "<", + { + "pluginId": "discoverShared", + "scope": "public", + "docId": "kibDiscoverSharedPluginApi", + "section": "def-public.DiscoverFeature", + "text": "DiscoverFeature" + }, + ">" + ], + "path": "src/plugins/discover_shared/public/services/discover_features/types.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "discoverShared", + "id": "def-public.DiscoverFeaturesServiceStart", + "type": "Interface", + "tags": [], + "label": "DiscoverFeaturesServiceStart", + "description": [], + "path": "src/plugins/discover_shared/public/services/discover_features/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "discoverShared", + "id": "def-public.DiscoverFeaturesServiceStart.registry", + "type": "Object", + "tags": [], + "label": "registry", + "description": [], + "signature": [ + { + "pluginId": "discoverShared", + "scope": "common", + "docId": "kibDiscoverSharedPluginApi", + "section": "def-common.FeaturesRegistry", + "text": "FeaturesRegistry" + }, + "<", + { + "pluginId": "discoverShared", + "scope": "public", + "docId": "kibDiscoverSharedPluginApi", + "section": "def-public.DiscoverFeature", + "text": "DiscoverFeature" + }, + ">" + ], + "path": "src/plugins/discover_shared/public/services/discover_features/types.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, { "parentPluginId": "discoverShared", "id": "def-public.ObservabilityLogsAIAssistantFeature", @@ -113,6 +201,104 @@ } ], "initialIsOpen": false + }, + { + "parentPluginId": "discoverShared", + "id": "def-public.SecuritySolutionAppWrapperFeature", + "type": "Interface", + "tags": [], + "label": "SecuritySolutionAppWrapperFeature", + "description": [], + "path": "src/plugins/discover_shared/public/services/discover_features/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "discoverShared", + "id": "def-public.SecuritySolutionAppWrapperFeature.id", + "type": "string", + "tags": [], + "label": "id", + "description": [], + "signature": [ + "\"security-solution-app-wrapper\"" + ], + "path": "src/plugins/discover_shared/public/services/discover_features/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "discoverShared", + "id": "def-public.SecuritySolutionAppWrapperFeature.getWrapper", + "type": "Function", + "tags": [], + "label": "getWrapper", + "description": [], + "signature": [ + "() => Promise<() => React.FunctionComponent<{ children?: React.ReactNode; }>>" + ], + "path": "src/plugins/discover_shared/public/services/discover_features/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [], + "returnComment": [] + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "discoverShared", + "id": "def-public.SecuritySolutionCellRendererFeature", + "type": "Interface", + "tags": [], + "label": "SecuritySolutionCellRendererFeature", + "description": [ + "*************** Security Solution" + ], + "path": "src/plugins/discover_shared/public/services/discover_features/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "discoverShared", + "id": "def-public.SecuritySolutionCellRendererFeature.id", + "type": "string", + "tags": [], + "label": "id", + "description": [], + "signature": [ + "\"security-solution-cell-renderer\"" + ], + "path": "src/plugins/discover_shared/public/services/discover_features/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "discoverShared", + "id": "def-public.SecuritySolutionCellRendererFeature.getRenderer", + "type": "Function", + "tags": [], + "label": "getRenderer", + "description": [], + "signature": [ + "() => Promise<(fieldName: string) => React.FunctionComponent<", + { + "pluginId": "@kbn/unified-data-table", + "scope": "public", + "docId": "kibKbnUnifiedDataTablePluginApi", + "section": "def-public.DataGridCellValueElementProps", + "text": "DataGridCellValueElementProps" + }, + "> | undefined>" + ], + "path": "src/plugins/discover_shared/public/services/discover_features/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [], + "returnComment": [] + } + ], + "initialIsOpen": false } ], "enums": [], @@ -133,7 +319,9 @@ "text": "ObservabilityLogsAIAssistantFeature" }, " | ", - "ObservabilityCreateSLOFeature" + "ObservabilityCreateSLOFeature", + " | ", + "SecuritySolutionFeature" ], "path": "src/plugins/discover_shared/public/services/discover_features/types.ts", "deprecated": false, @@ -161,7 +349,13 @@ "label": "features", "description": [], "signature": [ - "DiscoverFeaturesServiceSetup" + { + "pluginId": "discoverShared", + "scope": "public", + "docId": "kibDiscoverSharedPluginApi", + "section": "def-public.DiscoverFeaturesServiceSetup", + "text": "DiscoverFeaturesServiceSetup" + } ], "path": "src/plugins/discover_shared/public/types.ts", "deprecated": false, @@ -190,7 +384,13 @@ "label": "features", "description": [], "signature": [ - "DiscoverFeaturesServiceStart" + { + "pluginId": "discoverShared", + "scope": "public", + "docId": "kibDiscoverSharedPluginApi", + "section": "def-public.DiscoverFeaturesServiceStart", + "text": "DiscoverFeaturesServiceStart" + } ], "path": "src/plugins/discover_shared/public/types.ts", "deprecated": false, diff --git a/api_docs/discover_shared.mdx b/api_docs/discover_shared.mdx index f030d0aa5699a..0f6288b8ea946 100644 --- a/api_docs/discover_shared.mdx +++ b/api_docs/discover_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/discoverShared title: "discoverShared" image: https://source.unsplash.com/400x175/?github description: API docs for the discoverShared plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'discoverShared'] --- import discoverSharedObj from './discover_shared.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/k | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 16 | 0 | 15 | 3 | +| 26 | 0 | 23 | 2 | ## Client diff --git a/api_docs/ecs_data_quality_dashboard.mdx b/api_docs/ecs_data_quality_dashboard.mdx index db27b40664534..98377a0807c98 100644 --- a/api_docs/ecs_data_quality_dashboard.mdx +++ b/api_docs/ecs_data_quality_dashboard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ecsDataQualityDashboard title: "ecsDataQualityDashboard" image: https://source.unsplash.com/400x175/?github description: API docs for the ecsDataQualityDashboard plugin -date: 2024-11-29 +date: 2024-12-03 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 c120084027e48..7a0831a5debfe 100644 --- a/api_docs/elastic_assistant.mdx +++ b/api_docs/elastic_assistant.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/elasticAssistant title: "elasticAssistant" image: https://source.unsplash.com/400x175/?github description: API docs for the elasticAssistant plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'elasticAssistant'] --- import elasticAssistantObj from './elastic_assistant.devdocs.json'; diff --git a/api_docs/embeddable.mdx b/api_docs/embeddable.mdx index 783c859f605ad..7774b8b0a3c5d 100644 --- a/api_docs/embeddable.mdx +++ b/api_docs/embeddable.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/embeddable title: "embeddable" image: https://source.unsplash.com/400x175/?github description: API docs for the embeddable plugin -date: 2024-11-29 +date: 2024-12-03 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 9a9fc42763269..2439bde8e99de 100644 --- a/api_docs/embeddable_enhanced.mdx +++ b/api_docs/embeddable_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/embeddableEnhanced title: "embeddableEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the embeddableEnhanced plugin -date: 2024-11-29 +date: 2024-12-03 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 c805e89949c26..32a3d89f65a24 100644 --- a/api_docs/encrypted_saved_objects.mdx +++ b/api_docs/encrypted_saved_objects.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/encryptedSavedObjects title: "encryptedSavedObjects" image: https://source.unsplash.com/400x175/?github description: API docs for the encryptedSavedObjects plugin -date: 2024-11-29 +date: 2024-12-03 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 d88cb8d19f086..230c232342c75 100644 --- a/api_docs/enterprise_search.mdx +++ b/api_docs/enterprise_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/enterpriseSearch title: "enterpriseSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the enterpriseSearch plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'enterpriseSearch'] --- import enterpriseSearchObj from './enterprise_search.devdocs.json'; diff --git a/api_docs/entities_data_access.mdx b/api_docs/entities_data_access.mdx index 0fe6c6463a591..fb7b4c912b45e 100644 --- a/api_docs/entities_data_access.mdx +++ b/api_docs/entities_data_access.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/entitiesDataAccess title: "entitiesDataAccess" image: https://source.unsplash.com/400x175/?github description: API docs for the entitiesDataAccess plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'entitiesDataAccess'] --- import entitiesDataAccessObj from './entities_data_access.devdocs.json'; diff --git a/api_docs/entity_manager.devdocs.json b/api_docs/entity_manager.devdocs.json index 618f1a4d59319..fb4d3e8050c6f 100644 --- a/api_docs/entity_manager.devdocs.json +++ b/api_docs/entity_manager.devdocs.json @@ -37,7 +37,7 @@ "section": "def-common.ServerRoute", "text": "ServerRoute" }, - "<\"POST /internal/entities/v2/_search/preview\", Zod.ZodObject<{ body: Zod.ZodObject<{ sources: Zod.ZodArray>; index_patterns: Zod.ZodArray; identity_fields: Zod.ZodArray; metadata_fields: Zod.ZodArray; filters: Zod.ZodArray; }, \"strip\", Zod.ZodTypeAny, { type: string; filters: string[]; timestamp_field: string; metadata_fields: string[]; index_patterns: string[]; identity_fields: string[]; }, { type: string; filters: string[]; metadata_fields: string[]; index_patterns: string[]; identity_fields: string[]; timestamp_field?: string | undefined; }>, \"many\">; start: Zod.ZodEffects>, string, string | undefined>; end: Zod.ZodEffects>, string, string | undefined>; limit: Zod.ZodDefault>; }, \"strip\", Zod.ZodTypeAny, { start: string; end: string; sources: { type: string; filters: string[]; timestamp_field: string; metadata_fields: string[]; index_patterns: string[]; identity_fields: string[]; }[]; limit: number; }, { sources: { type: string; filters: string[]; metadata_fields: string[]; index_patterns: string[]; identity_fields: string[]; timestamp_field?: string | undefined; }[]; start?: string | undefined; end?: string | undefined; limit?: number | undefined; }>; }, \"strip\", Zod.ZodTypeAny, { body: { start: string; end: string; sources: { type: string; filters: string[]; timestamp_field: string; metadata_fields: string[]; index_patterns: string[]; identity_fields: string[]; }[]; limit: number; }; }, { body: { sources: { type: string; filters: string[]; metadata_fields: string[]; index_patterns: string[]; identity_fields: string[]; timestamp_field?: string | undefined; }[]; start?: string | undefined; end?: string | undefined; limit?: number | undefined; }; }>, ", + "<\"POST /internal/entities/v2/_search/preview\", Zod.ZodObject<{ body: Zod.ZodObject<{ sources: Zod.ZodArray; index_patterns: Zod.ZodArray; identity_fields: Zod.ZodArray; metadata_fields: Zod.ZodArray; filters: Zod.ZodArray; display_name: Zod.ZodOptional; }, \"strip\", Zod.ZodTypeAny, { type: string; filters: string[]; metadata_fields: string[]; index_patterns: string[]; identity_fields: string[]; timestamp_field?: string | undefined; display_name?: string | undefined; }, { type: string; filters: string[]; metadata_fields: string[]; index_patterns: string[]; identity_fields: string[]; timestamp_field?: string | undefined; display_name?: string | undefined; }>, \"many\">; start: Zod.ZodEffects>, string, string | undefined>; end: Zod.ZodEffects>, string, string | undefined>; sort: Zod.ZodOptional; }, \"strip\", Zod.ZodTypeAny, { field: string; direction: \"ASC\" | \"DESC\"; }, { field: string; direction: \"ASC\" | \"DESC\"; }>>; limit: Zod.ZodDefault>; }, \"strip\", Zod.ZodTypeAny, { start: string; end: string; sources: { type: string; filters: string[]; metadata_fields: string[]; index_patterns: string[]; identity_fields: string[]; timestamp_field?: string | undefined; display_name?: string | undefined; }[]; limit: number; sort?: { field: string; direction: \"ASC\" | \"DESC\"; } | undefined; }, { sources: { type: string; filters: string[]; metadata_fields: string[]; index_patterns: string[]; identity_fields: string[]; timestamp_field?: string | undefined; display_name?: string | undefined; }[]; start?: string | undefined; end?: string | undefined; sort?: { field: string; direction: \"ASC\" | \"DESC\"; } | undefined; limit?: number | undefined; }>; }, \"strip\", Zod.ZodTypeAny, { body: { start: string; end: string; sources: { type: string; filters: string[]; metadata_fields: string[]; index_patterns: string[]; identity_fields: string[]; timestamp_field?: string | undefined; display_name?: string | undefined; }[]; limit: number; sort?: { field: string; direction: \"ASC\" | \"DESC\"; } | undefined; }; }, { body: { sources: { type: string; filters: string[]; metadata_fields: string[]; index_patterns: string[]; identity_fields: string[]; timestamp_field?: string | undefined; display_name?: string | undefined; }[]; start?: string | undefined; end?: string | undefined; sort?: { field: string; direction: \"ASC\" | \"DESC\"; } | undefined; limit?: number | undefined; }; }>, ", "EntityManagerRouteHandlerResources", ", ", { @@ -63,7 +63,7 @@ "section": "def-common.ServerRoute", "text": "ServerRoute" }, - "<\"POST /internal/entities/v2/_search\", Zod.ZodObject<{ body: Zod.ZodObject<{ type: Zod.ZodString; metadata_fields: Zod.ZodDefault>>; filters: Zod.ZodDefault>>; start: Zod.ZodEffects>, string, string | undefined>; end: Zod.ZodEffects>, string, string | undefined>; limit: Zod.ZodDefault>; }, \"strip\", Zod.ZodTypeAny, { type: string; start: string; end: string; filters: string[]; limit: number; metadata_fields: string[]; }, { type: string; start?: string | undefined; end?: string | undefined; filters?: string[] | undefined; limit?: number | undefined; metadata_fields?: string[] | undefined; }>; }, \"strip\", Zod.ZodTypeAny, { body: { type: string; start: string; end: string; filters: string[]; limit: number; metadata_fields: string[]; }; }, { body: { type: string; start?: string | undefined; end?: string | undefined; filters?: string[] | undefined; limit?: number | undefined; metadata_fields?: string[] | undefined; }; }>, ", + "<\"POST /internal/entities/v2/_search\", Zod.ZodObject<{ body: Zod.ZodObject<{ type: Zod.ZodString; metadata_fields: Zod.ZodDefault>>; filters: Zod.ZodDefault>>; start: Zod.ZodEffects>, string, string | undefined>; end: Zod.ZodEffects>, string, string | undefined>; sort: Zod.ZodOptional; }, \"strip\", Zod.ZodTypeAny, { field: string; direction: \"ASC\" | \"DESC\"; }, { field: string; direction: \"ASC\" | \"DESC\"; }>>; limit: Zod.ZodDefault>; }, \"strip\", Zod.ZodTypeAny, { type: string; start: string; end: string; filters: string[]; limit: number; metadata_fields: string[]; sort?: { field: string; direction: \"ASC\" | \"DESC\"; } | undefined; }, { type: string; start?: string | undefined; end?: string | undefined; sort?: { field: string; direction: \"ASC\" | \"DESC\"; } | undefined; filters?: string[] | undefined; limit?: number | undefined; metadata_fields?: string[] | undefined; }>; }, \"strip\", Zod.ZodTypeAny, { body: { type: string; start: string; end: string; filters: string[]; limit: number; metadata_fields: string[]; sort?: { field: string; direction: \"ASC\" | \"DESC\"; } | undefined; }; }, { body: { type: string; start?: string | undefined; end?: string | undefined; sort?: { field: string; direction: \"ASC\" | \"DESC\"; } | undefined; filters?: string[] | undefined; limit?: number | undefined; metadata_fields?: string[] | undefined; }; }>, ", "EntityManagerRouteHandlerResources", ", ", { @@ -385,7 +385,7 @@ "section": "def-common.ServerRoute", "text": "ServerRoute" }, - "<\"POST /internal/entities/v2/_search/preview\", Zod.ZodObject<{ body: Zod.ZodObject<{ sources: Zod.ZodArray>; index_patterns: Zod.ZodArray; identity_fields: Zod.ZodArray; metadata_fields: Zod.ZodArray; filters: Zod.ZodArray; }, \"strip\", Zod.ZodTypeAny, { type: string; filters: string[]; timestamp_field: string; metadata_fields: string[]; index_patterns: string[]; identity_fields: string[]; }, { type: string; filters: string[]; metadata_fields: string[]; index_patterns: string[]; identity_fields: string[]; timestamp_field?: string | undefined; }>, \"many\">; start: Zod.ZodEffects>, string, string | undefined>; end: Zod.ZodEffects>, string, string | undefined>; limit: Zod.ZodDefault>; }, \"strip\", Zod.ZodTypeAny, { start: string; end: string; sources: { type: string; filters: string[]; timestamp_field: string; metadata_fields: string[]; index_patterns: string[]; identity_fields: string[]; }[]; limit: number; }, { sources: { type: string; filters: string[]; metadata_fields: string[]; index_patterns: string[]; identity_fields: string[]; timestamp_field?: string | undefined; }[]; start?: string | undefined; end?: string | undefined; limit?: number | undefined; }>; }, \"strip\", Zod.ZodTypeAny, { body: { start: string; end: string; sources: { type: string; filters: string[]; timestamp_field: string; metadata_fields: string[]; index_patterns: string[]; identity_fields: string[]; }[]; limit: number; }; }, { body: { sources: { type: string; filters: string[]; metadata_fields: string[]; index_patterns: string[]; identity_fields: string[]; timestamp_field?: string | undefined; }[]; start?: string | undefined; end?: string | undefined; limit?: number | undefined; }; }>, ", + "<\"POST /internal/entities/v2/_search/preview\", Zod.ZodObject<{ body: Zod.ZodObject<{ sources: Zod.ZodArray; index_patterns: Zod.ZodArray; identity_fields: Zod.ZodArray; metadata_fields: Zod.ZodArray; filters: Zod.ZodArray; display_name: Zod.ZodOptional; }, \"strip\", Zod.ZodTypeAny, { type: string; filters: string[]; metadata_fields: string[]; index_patterns: string[]; identity_fields: string[]; timestamp_field?: string | undefined; display_name?: string | undefined; }, { type: string; filters: string[]; metadata_fields: string[]; index_patterns: string[]; identity_fields: string[]; timestamp_field?: string | undefined; display_name?: string | undefined; }>, \"many\">; start: Zod.ZodEffects>, string, string | undefined>; end: Zod.ZodEffects>, string, string | undefined>; sort: Zod.ZodOptional; }, \"strip\", Zod.ZodTypeAny, { field: string; direction: \"ASC\" | \"DESC\"; }, { field: string; direction: \"ASC\" | \"DESC\"; }>>; limit: Zod.ZodDefault>; }, \"strip\", Zod.ZodTypeAny, { start: string; end: string; sources: { type: string; filters: string[]; metadata_fields: string[]; index_patterns: string[]; identity_fields: string[]; timestamp_field?: string | undefined; display_name?: string | undefined; }[]; limit: number; sort?: { field: string; direction: \"ASC\" | \"DESC\"; } | undefined; }, { sources: { type: string; filters: string[]; metadata_fields: string[]; index_patterns: string[]; identity_fields: string[]; timestamp_field?: string | undefined; display_name?: string | undefined; }[]; start?: string | undefined; end?: string | undefined; sort?: { field: string; direction: \"ASC\" | \"DESC\"; } | undefined; limit?: number | undefined; }>; }, \"strip\", Zod.ZodTypeAny, { body: { start: string; end: string; sources: { type: string; filters: string[]; metadata_fields: string[]; index_patterns: string[]; identity_fields: string[]; timestamp_field?: string | undefined; display_name?: string | undefined; }[]; limit: number; sort?: { field: string; direction: \"ASC\" | \"DESC\"; } | undefined; }; }, { body: { sources: { type: string; filters: string[]; metadata_fields: string[]; index_patterns: string[]; identity_fields: string[]; timestamp_field?: string | undefined; display_name?: string | undefined; }[]; start?: string | undefined; end?: string | undefined; sort?: { field: string; direction: \"ASC\" | \"DESC\"; } | undefined; limit?: number | undefined; }; }>, ", "EntityManagerRouteHandlerResources", ", ", { @@ -411,7 +411,7 @@ "section": "def-common.ServerRoute", "text": "ServerRoute" }, - "<\"POST /internal/entities/v2/_search\", Zod.ZodObject<{ body: Zod.ZodObject<{ type: Zod.ZodString; metadata_fields: Zod.ZodDefault>>; filters: Zod.ZodDefault>>; start: Zod.ZodEffects>, string, string | undefined>; end: Zod.ZodEffects>, string, string | undefined>; limit: Zod.ZodDefault>; }, \"strip\", Zod.ZodTypeAny, { type: string; start: string; end: string; filters: string[]; limit: number; metadata_fields: string[]; }, { type: string; start?: string | undefined; end?: string | undefined; filters?: string[] | undefined; limit?: number | undefined; metadata_fields?: string[] | undefined; }>; }, \"strip\", Zod.ZodTypeAny, { body: { type: string; start: string; end: string; filters: string[]; limit: number; metadata_fields: string[]; }; }, { body: { type: string; start?: string | undefined; end?: string | undefined; filters?: string[] | undefined; limit?: number | undefined; metadata_fields?: string[] | undefined; }; }>, ", + "<\"POST /internal/entities/v2/_search\", Zod.ZodObject<{ body: Zod.ZodObject<{ type: Zod.ZodString; metadata_fields: Zod.ZodDefault>>; filters: Zod.ZodDefault>>; start: Zod.ZodEffects>, string, string | undefined>; end: Zod.ZodEffects>, string, string | undefined>; sort: Zod.ZodOptional; }, \"strip\", Zod.ZodTypeAny, { field: string; direction: \"ASC\" | \"DESC\"; }, { field: string; direction: \"ASC\" | \"DESC\"; }>>; limit: Zod.ZodDefault>; }, \"strip\", Zod.ZodTypeAny, { type: string; start: string; end: string; filters: string[]; limit: number; metadata_fields: string[]; sort?: { field: string; direction: \"ASC\" | \"DESC\"; } | undefined; }, { type: string; start?: string | undefined; end?: string | undefined; sort?: { field: string; direction: \"ASC\" | \"DESC\"; } | undefined; filters?: string[] | undefined; limit?: number | undefined; metadata_fields?: string[] | undefined; }>; }, \"strip\", Zod.ZodTypeAny, { body: { type: string; start: string; end: string; filters: string[]; limit: number; metadata_fields: string[]; sort?: { field: string; direction: \"ASC\" | \"DESC\"; } | undefined; }; }, { body: { type: string; start?: string | undefined; end?: string | undefined; sort?: { field: string; direction: \"ASC\" | \"DESC\"; } | undefined; filters?: string[] | undefined; limit?: number | undefined; metadata_fields?: string[] | undefined; }; }>, ", "EntityManagerRouteHandlerResources", ", ", { @@ -1292,7 +1292,7 @@ "section": "def-common.ServerRoute", "text": "ServerRoute" }, - "<\"POST /internal/entities/v2/_search/preview\", Zod.ZodObject<{ body: Zod.ZodObject<{ sources: Zod.ZodArray>; index_patterns: Zod.ZodArray; identity_fields: Zod.ZodArray; metadata_fields: Zod.ZodArray; filters: Zod.ZodArray; }, \"strip\", Zod.ZodTypeAny, { type: string; filters: string[]; timestamp_field: string; metadata_fields: string[]; index_patterns: string[]; identity_fields: string[]; }, { type: string; filters: string[]; metadata_fields: string[]; index_patterns: string[]; identity_fields: string[]; timestamp_field?: string | undefined; }>, \"many\">; start: Zod.ZodEffects>, string, string | undefined>; end: Zod.ZodEffects>, string, string | undefined>; limit: Zod.ZodDefault>; }, \"strip\", Zod.ZodTypeAny, { start: string; end: string; sources: { type: string; filters: string[]; timestamp_field: string; metadata_fields: string[]; index_patterns: string[]; identity_fields: string[]; }[]; limit: number; }, { sources: { type: string; filters: string[]; metadata_fields: string[]; index_patterns: string[]; identity_fields: string[]; timestamp_field?: string | undefined; }[]; start?: string | undefined; end?: string | undefined; limit?: number | undefined; }>; }, \"strip\", Zod.ZodTypeAny, { body: { start: string; end: string; sources: { type: string; filters: string[]; timestamp_field: string; metadata_fields: string[]; index_patterns: string[]; identity_fields: string[]; }[]; limit: number; }; }, { body: { sources: { type: string; filters: string[]; metadata_fields: string[]; index_patterns: string[]; identity_fields: string[]; timestamp_field?: string | undefined; }[]; start?: string | undefined; end?: string | undefined; limit?: number | undefined; }; }>, ", + "<\"POST /internal/entities/v2/_search/preview\", Zod.ZodObject<{ body: Zod.ZodObject<{ sources: Zod.ZodArray; index_patterns: Zod.ZodArray; identity_fields: Zod.ZodArray; metadata_fields: Zod.ZodArray; filters: Zod.ZodArray; display_name: Zod.ZodOptional; }, \"strip\", Zod.ZodTypeAny, { type: string; filters: string[]; metadata_fields: string[]; index_patterns: string[]; identity_fields: string[]; timestamp_field?: string | undefined; display_name?: string | undefined; }, { type: string; filters: string[]; metadata_fields: string[]; index_patterns: string[]; identity_fields: string[]; timestamp_field?: string | undefined; display_name?: string | undefined; }>, \"many\">; start: Zod.ZodEffects>, string, string | undefined>; end: Zod.ZodEffects>, string, string | undefined>; sort: Zod.ZodOptional; }, \"strip\", Zod.ZodTypeAny, { field: string; direction: \"ASC\" | \"DESC\"; }, { field: string; direction: \"ASC\" | \"DESC\"; }>>; limit: Zod.ZodDefault>; }, \"strip\", Zod.ZodTypeAny, { start: string; end: string; sources: { type: string; filters: string[]; metadata_fields: string[]; index_patterns: string[]; identity_fields: string[]; timestamp_field?: string | undefined; display_name?: string | undefined; }[]; limit: number; sort?: { field: string; direction: \"ASC\" | \"DESC\"; } | undefined; }, { sources: { type: string; filters: string[]; metadata_fields: string[]; index_patterns: string[]; identity_fields: string[]; timestamp_field?: string | undefined; display_name?: string | undefined; }[]; start?: string | undefined; end?: string | undefined; sort?: { field: string; direction: \"ASC\" | \"DESC\"; } | undefined; limit?: number | undefined; }>; }, \"strip\", Zod.ZodTypeAny, { body: { start: string; end: string; sources: { type: string; filters: string[]; metadata_fields: string[]; index_patterns: string[]; identity_fields: string[]; timestamp_field?: string | undefined; display_name?: string | undefined; }[]; limit: number; sort?: { field: string; direction: \"ASC\" | \"DESC\"; } | undefined; }; }, { body: { sources: { type: string; filters: string[]; metadata_fields: string[]; index_patterns: string[]; identity_fields: string[]; timestamp_field?: string | undefined; display_name?: string | undefined; }[]; start?: string | undefined; end?: string | undefined; sort?: { field: string; direction: \"ASC\" | \"DESC\"; } | undefined; limit?: number | undefined; }; }>, ", "EntityManagerRouteHandlerResources", ", ", { @@ -1318,7 +1318,7 @@ "section": "def-common.ServerRoute", "text": "ServerRoute" }, - "<\"POST /internal/entities/v2/_search\", Zod.ZodObject<{ body: Zod.ZodObject<{ type: Zod.ZodString; metadata_fields: Zod.ZodDefault>>; filters: Zod.ZodDefault>>; start: Zod.ZodEffects>, string, string | undefined>; end: Zod.ZodEffects>, string, string | undefined>; limit: Zod.ZodDefault>; }, \"strip\", Zod.ZodTypeAny, { type: string; start: string; end: string; filters: string[]; limit: number; metadata_fields: string[]; }, { type: string; start?: string | undefined; end?: string | undefined; filters?: string[] | undefined; limit?: number | undefined; metadata_fields?: string[] | undefined; }>; }, \"strip\", Zod.ZodTypeAny, { body: { type: string; start: string; end: string; filters: string[]; limit: number; metadata_fields: string[]; }; }, { body: { type: string; start?: string | undefined; end?: string | undefined; filters?: string[] | undefined; limit?: number | undefined; metadata_fields?: string[] | undefined; }; }>, ", + "<\"POST /internal/entities/v2/_search\", Zod.ZodObject<{ body: Zod.ZodObject<{ type: Zod.ZodString; metadata_fields: Zod.ZodDefault>>; filters: Zod.ZodDefault>>; start: Zod.ZodEffects>, string, string | undefined>; end: Zod.ZodEffects>, string, string | undefined>; sort: Zod.ZodOptional; }, \"strip\", Zod.ZodTypeAny, { field: string; direction: \"ASC\" | \"DESC\"; }, { field: string; direction: \"ASC\" | \"DESC\"; }>>; limit: Zod.ZodDefault>; }, \"strip\", Zod.ZodTypeAny, { type: string; start: string; end: string; filters: string[]; limit: number; metadata_fields: string[]; sort?: { field: string; direction: \"ASC\" | \"DESC\"; } | undefined; }, { type: string; start?: string | undefined; end?: string | undefined; sort?: { field: string; direction: \"ASC\" | \"DESC\"; } | undefined; filters?: string[] | undefined; limit?: number | undefined; metadata_fields?: string[] | undefined; }>; }, \"strip\", Zod.ZodTypeAny, { body: { type: string; start: string; end: string; filters: string[]; limit: number; metadata_fields: string[]; sort?: { field: string; direction: \"ASC\" | \"DESC\"; } | undefined; }; }, { body: { type: string; start?: string | undefined; end?: string | undefined; sort?: { field: string; direction: \"ASC\" | \"DESC\"; } | undefined; filters?: string[] | undefined; limit?: number | undefined; metadata_fields?: string[] | undefined; }; }>, ", "EntityManagerRouteHandlerResources", ", ", { diff --git a/api_docs/entity_manager.mdx b/api_docs/entity_manager.mdx index 0c6df394edb22..3711c94ed9ba3 100644 --- a/api_docs/entity_manager.mdx +++ b/api_docs/entity_manager.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/entityManager title: "entityManager" image: https://source.unsplash.com/400x175/?github description: API docs for the entityManager plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'entityManager'] --- import entityManagerObj from './entity_manager.devdocs.json'; diff --git a/api_docs/es_ui_shared.mdx b/api_docs/es_ui_shared.mdx index 764743db4d221..1d5cd9990b9db 100644 --- a/api_docs/es_ui_shared.mdx +++ b/api_docs/es_ui_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/esUiShared title: "esUiShared" image: https://source.unsplash.com/400x175/?github description: API docs for the esUiShared plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'esUiShared'] --- import esUiSharedObj from './es_ui_shared.devdocs.json'; diff --git a/api_docs/esql.mdx b/api_docs/esql.mdx index 9c14eba456df2..d026d789d73ae 100644 --- a/api_docs/esql.mdx +++ b/api_docs/esql.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/esql title: "esql" image: https://source.unsplash.com/400x175/?github description: API docs for the esql plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'esql'] --- import esqlObj from './esql.devdocs.json'; diff --git a/api_docs/esql_data_grid.mdx b/api_docs/esql_data_grid.mdx index c495614af9a9b..4cd5976f886ca 100644 --- a/api_docs/esql_data_grid.mdx +++ b/api_docs/esql_data_grid.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/esqlDataGrid title: "esqlDataGrid" image: https://source.unsplash.com/400x175/?github description: API docs for the esqlDataGrid plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'esqlDataGrid'] --- import esqlDataGridObj from './esql_data_grid.devdocs.json'; diff --git a/api_docs/event_annotation.mdx b/api_docs/event_annotation.mdx index c5e8c2f097401..60c63d315f8f7 100644 --- a/api_docs/event_annotation.mdx +++ b/api_docs/event_annotation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/eventAnnotation title: "eventAnnotation" image: https://source.unsplash.com/400x175/?github description: API docs for the eventAnnotation plugin -date: 2024-11-29 +date: 2024-12-03 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 39ec0f63163b8..006a0ad52e329 100644 --- a/api_docs/event_annotation_listing.mdx +++ b/api_docs/event_annotation_listing.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/eventAnnotationListing title: "eventAnnotationListing" image: https://source.unsplash.com/400x175/?github description: API docs for the eventAnnotationListing plugin -date: 2024-11-29 +date: 2024-12-03 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 acacd1b4be569..90bed851be237 100644 --- a/api_docs/event_log.mdx +++ b/api_docs/event_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/eventLog title: "eventLog" image: https://source.unsplash.com/400x175/?github description: API docs for the eventLog plugin -date: 2024-11-29 +date: 2024-12-03 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 2fa1a873ebe6b..d226a1207d3fc 100644 --- a/api_docs/exploratory_view.mdx +++ b/api_docs/exploratory_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/exploratoryView title: "exploratoryView" image: https://source.unsplash.com/400x175/?github description: API docs for the exploratoryView plugin -date: 2024-11-29 +date: 2024-12-03 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 ac36131346603..5412c012dccf0 100644 --- a/api_docs/expression_error.mdx +++ b/api_docs/expression_error.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionError title: "expressionError" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionError plugin -date: 2024-11-29 +date: 2024-12-03 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 611d4fd4061cb..0be715deea203 100644 --- a/api_docs/expression_gauge.mdx +++ b/api_docs/expression_gauge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionGauge title: "expressionGauge" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionGauge plugin -date: 2024-11-29 +date: 2024-12-03 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 dfd66c88febe4..c7882909785de 100644 --- a/api_docs/expression_heatmap.mdx +++ b/api_docs/expression_heatmap.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionHeatmap title: "expressionHeatmap" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionHeatmap plugin -date: 2024-11-29 +date: 2024-12-03 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 aeed9970b5e2a..c9332d0b0ff68 100644 --- a/api_docs/expression_image.mdx +++ b/api_docs/expression_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionImage title: "expressionImage" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionImage plugin -date: 2024-11-29 +date: 2024-12-03 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 3f791bb8ddd8e..e83cea3de90cb 100644 --- a/api_docs/expression_legacy_metric_vis.mdx +++ b/api_docs/expression_legacy_metric_vis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionLegacyMetricVis title: "expressionLegacyMetricVis" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionLegacyMetricVis plugin -date: 2024-11-29 +date: 2024-12-03 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 5e45e5b46873c..872ef40b76e34 100644 --- a/api_docs/expression_metric.mdx +++ b/api_docs/expression_metric.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionMetric title: "expressionMetric" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionMetric plugin -date: 2024-11-29 +date: 2024-12-03 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 7181cb04259d2..b3c82de9aaed6 100644 --- a/api_docs/expression_metric_vis.mdx +++ b/api_docs/expression_metric_vis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionMetricVis title: "expressionMetricVis" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionMetricVis plugin -date: 2024-11-29 +date: 2024-12-03 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 78a52dfb840c3..8c1e1462e9ee5 100644 --- a/api_docs/expression_partition_vis.mdx +++ b/api_docs/expression_partition_vis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionPartitionVis title: "expressionPartitionVis" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionPartitionVis plugin -date: 2024-11-29 +date: 2024-12-03 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 2e14f3be7cf4d..fe3383781dd3c 100644 --- a/api_docs/expression_repeat_image.mdx +++ b/api_docs/expression_repeat_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionRepeatImage title: "expressionRepeatImage" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionRepeatImage plugin -date: 2024-11-29 +date: 2024-12-03 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 4d6d1869e8618..585fdceb1ae5a 100644 --- a/api_docs/expression_reveal_image.mdx +++ b/api_docs/expression_reveal_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionRevealImage title: "expressionRevealImage" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionRevealImage plugin -date: 2024-11-29 +date: 2024-12-03 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 86555f0edcc27..3c46e5108b05f 100644 --- a/api_docs/expression_shape.mdx +++ b/api_docs/expression_shape.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionShape title: "expressionShape" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionShape plugin -date: 2024-11-29 +date: 2024-12-03 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 a513cecf01629..1ab84e554d867 100644 --- a/api_docs/expression_tagcloud.mdx +++ b/api_docs/expression_tagcloud.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionTagcloud title: "expressionTagcloud" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionTagcloud plugin -date: 2024-11-29 +date: 2024-12-03 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 9c6ea7e15ff8a..c63d33f62a1cb 100644 --- a/api_docs/expression_x_y.mdx +++ b/api_docs/expression_x_y.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionXY title: "expressionXY" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionXY plugin -date: 2024-11-29 +date: 2024-12-03 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 9f92bdcd68d0b..f7433b89be8a4 100644 --- a/api_docs/expressions.mdx +++ b/api_docs/expressions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressions title: "expressions" image: https://source.unsplash.com/400x175/?github description: API docs for the expressions plugin -date: 2024-11-29 +date: 2024-12-03 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 644379faf921a..b4cab32461bd3 100644 --- a/api_docs/features.mdx +++ b/api_docs/features.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/features title: "features" image: https://source.unsplash.com/400x175/?github description: API docs for the features plugin -date: 2024-11-29 +date: 2024-12-03 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 3e245ced7750b..d3a77744d9383 100644 --- a/api_docs/field_formats.mdx +++ b/api_docs/field_formats.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fieldFormats title: "fieldFormats" image: https://source.unsplash.com/400x175/?github description: API docs for the fieldFormats plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fieldFormats'] --- import fieldFormatsObj from './field_formats.devdocs.json'; diff --git a/api_docs/fields_metadata.mdx b/api_docs/fields_metadata.mdx index 914e949fcf168..7700b42a9da68 100644 --- a/api_docs/fields_metadata.mdx +++ b/api_docs/fields_metadata.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fieldsMetadata title: "fieldsMetadata" image: https://source.unsplash.com/400x175/?github description: API docs for the fieldsMetadata plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fieldsMetadata'] --- import fieldsMetadataObj from './fields_metadata.devdocs.json'; diff --git a/api_docs/file_upload.mdx b/api_docs/file_upload.mdx index b2cc27daed4ce..2169567dd27db 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: 2024-11-29 +date: 2024-12-03 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 6a83c6bf0d072..c7568eef46d7f 100644 --- a/api_docs/files.mdx +++ b/api_docs/files.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/files title: "files" image: https://source.unsplash.com/400x175/?github description: API docs for the files plugin -date: 2024-11-29 +date: 2024-12-03 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 dc34d1cb01fb6..ebcc2d578f6ca 100644 --- a/api_docs/files_management.mdx +++ b/api_docs/files_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/filesManagement title: "filesManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the filesManagement plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'filesManagement'] --- import filesManagementObj from './files_management.devdocs.json'; diff --git a/api_docs/fleet.devdocs.json b/api_docs/fleet.devdocs.json index 670bd13f2f0c9..9abcedefd3043 100644 --- a/api_docs/fleet.devdocs.json +++ b/api_docs/fleet.devdocs.json @@ -9243,6 +9243,61 @@ ], "returnComment": [] }, + { + "parentPluginId": "fleet", + "id": "def-server.PackageClient.getLatestPackageInfo", + "type": "Function", + "tags": [], + "label": "getLatestPackageInfo", + "description": [], + "signature": [ + "(packageName: string, prerelease?: boolean | undefined) => Promise<", + { + "pluginId": "fleet", + "scope": "common", + "docId": "kibFleetPluginApi", + "section": "def-common.PackageInfo", + "text": "PackageInfo" + }, + ">" + ], + "path": "x-pack/plugins/fleet/server/services/epm/package_service.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "fleet", + "id": "def-server.PackageClient.getLatestPackageInfo.$1", + "type": "string", + "tags": [], + "label": "packageName", + "description": [], + "signature": [ + "string" + ], + "path": "x-pack/plugins/fleet/server/services/epm/package_service.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "fleet", + "id": "def-server.PackageClient.getLatestPackageInfo.$2", + "type": "CompoundType", + "tags": [], + "label": "prerelease", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "x-pack/plugins/fleet/server/services/epm/package_service.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": false + } + ], + "returnComment": [] + }, { "parentPluginId": "fleet", "id": "def-server.PackageClient.getPackages", diff --git a/api_docs/fleet.mdx b/api_docs/fleet.mdx index 0df9f88139772..1c4db3adeae7d 100644 --- a/api_docs/fleet.mdx +++ b/api_docs/fleet.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fleet title: "fleet" image: https://source.unsplash.com/400x175/?github description: API docs for the fleet plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fleet'] --- import fleetObj from './fleet.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/fleet](https://github.com/orgs/elastic/teams/fleet) for questi | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 1432 | 5 | 1306 | 82 | +| 1435 | 5 | 1309 | 82 | ## Client diff --git a/api_docs/global_search.mdx b/api_docs/global_search.mdx index 717f10211b731..229d3a9e4bbb7 100644 --- a/api_docs/global_search.mdx +++ b/api_docs/global_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/globalSearch title: "globalSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the globalSearch plugin -date: 2024-11-29 +date: 2024-12-03 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 6c330c5661e2e..7824e377774e3 100644 --- a/api_docs/guided_onboarding.mdx +++ b/api_docs/guided_onboarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/guidedOnboarding title: "guidedOnboarding" image: https://source.unsplash.com/400x175/?github description: API docs for the guidedOnboarding plugin -date: 2024-11-29 +date: 2024-12-03 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 af8613352837b..7dc920164d8d1 100644 --- a/api_docs/home.mdx +++ b/api_docs/home.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/home title: "home" image: https://source.unsplash.com/400x175/?github description: API docs for the home plugin -date: 2024-11-29 +date: 2024-12-03 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 c6f92a9361d77..67b9a220830bd 100644 --- a/api_docs/image_embeddable.mdx +++ b/api_docs/image_embeddable.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/imageEmbeddable title: "imageEmbeddable" image: https://source.unsplash.com/400x175/?github description: API docs for the imageEmbeddable plugin -date: 2024-11-29 +date: 2024-12-03 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 861a7096199dd..56da4fb40641c 100644 --- a/api_docs/index_lifecycle_management.mdx +++ b/api_docs/index_lifecycle_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/indexLifecycleManagement title: "indexLifecycleManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the indexLifecycleManagement plugin -date: 2024-11-29 +date: 2024-12-03 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 87b7f68015aa5..2e82880526e59 100644 --- a/api_docs/index_management.mdx +++ b/api_docs/index_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/indexManagement title: "indexManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the indexManagement plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'indexManagement'] --- import indexManagementObj from './index_management.devdocs.json'; diff --git a/api_docs/inference.devdocs.json b/api_docs/inference.devdocs.json index 340b5e87d7f0d..4cf16dcfec9bf 100644 --- a/api_docs/inference.devdocs.json +++ b/api_docs/inference.devdocs.json @@ -738,11 +738,13 @@ "type": "Function", "tags": [], "label": "correctCommonEsqlMistakes", - "description": [], + "description": [ + "\nCorrect some common ES|QL syntax and grammar mistakes that LLM can potentially do.\n\nCorrecting the query is done in two steps:\n1. we try to correct the *syntax*, without AST (given it requires a valid syntax)\n2. we try to correct the *grammar*, using AST this time." + ], "signature": [ - "(query: string) => { isCorrection: boolean; input: string; output: string; }" + "(query: string) => { input: string; output: string; isCorrection: boolean; }" ], - "path": "x-pack/plugins/inference/common/tasks/nl_to_esql/correct_common_esql_mistakes.ts", + "path": "x-pack/plugins/inference/common/tasks/nl_to_esql/correct_esql_query.ts", "deprecated": false, "trackAdoption": false, "children": [ @@ -756,7 +758,7 @@ "signature": [ "string" ], - "path": "x-pack/plugins/inference/common/tasks/nl_to_esql/correct_common_esql_mistakes.ts", + "path": "x-pack/plugins/inference/common/tasks/nl_to_esql/correct_esql_query.ts", "deprecated": false, "trackAdoption": false, "isRequired": true @@ -929,7 +931,7 @@ "signature": [ "(query: string) => { name: string | undefined; command: string; }[]" ], - "path": "x-pack/plugins/inference/common/tasks/nl_to_esql/correct_common_esql_mistakes.ts", + "path": "x-pack/plugins/inference/common/tasks/nl_to_esql/non_ast/correct_common_esql_mistakes.ts", "deprecated": false, "trackAdoption": false, "children": [ @@ -943,7 +945,7 @@ "signature": [ "string" ], - "path": "x-pack/plugins/inference/common/tasks/nl_to_esql/correct_common_esql_mistakes.ts", + "path": "x-pack/plugins/inference/common/tasks/nl_to_esql/non_ast/correct_common_esql_mistakes.ts", "deprecated": false, "trackAdoption": false, "isRequired": true diff --git a/api_docs/inference.mdx b/api_docs/inference.mdx index 8be0084fae82c..ec0fa9af52514 100644 --- a/api_docs/inference.mdx +++ b/api_docs/inference.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/inference title: "inference" image: https://source.unsplash.com/400x175/?github description: API docs for the inference plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'inference'] --- import inferenceObj from './inference.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/appex-ai-infra](https://github.com/orgs/elastic/teams/appex-ai | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 40 | 0 | 29 | 6 | +| 40 | 0 | 28 | 6 | ## Client diff --git a/api_docs/infra.mdx b/api_docs/infra.mdx index 3eb3d78458d98..76d0e667edacf 100644 --- a/api_docs/infra.mdx +++ b/api_docs/infra.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/infra title: "infra" image: https://source.unsplash.com/400x175/?github description: API docs for the infra plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'infra'] --- import infraObj from './infra.devdocs.json'; diff --git a/api_docs/ingest_pipelines.mdx b/api_docs/ingest_pipelines.mdx index 650a4c9fbd2a8..7c385f03d849f 100644 --- a/api_docs/ingest_pipelines.mdx +++ b/api_docs/ingest_pipelines.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ingestPipelines title: "ingestPipelines" image: https://source.unsplash.com/400x175/?github description: API docs for the ingestPipelines plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ingestPipelines'] --- import ingestPipelinesObj from './ingest_pipelines.devdocs.json'; diff --git a/api_docs/inspector.mdx b/api_docs/inspector.mdx index bc948766fe34a..453e6fba686db 100644 --- a/api_docs/inspector.mdx +++ b/api_docs/inspector.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/inspector title: "inspector" image: https://source.unsplash.com/400x175/?github description: API docs for the inspector plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'inspector'] --- import inspectorObj from './inspector.devdocs.json'; diff --git a/api_docs/integration_assistant.devdocs.json b/api_docs/integration_assistant.devdocs.json index 37870e95e8e94..3c6f41d4c4c03 100644 --- a/api_docs/integration_assistant.devdocs.json +++ b/api_docs/integration_assistant.devdocs.json @@ -318,7 +318,7 @@ "label": "AnalyzeLogsResponse", "description": [], "signature": [ - "{ results: { samplesFormat: { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }; parsedSamples: string[]; }; additionalProcessors?: ", + "{ results: { samplesFormat: { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\" | \"cef\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }; parsedSamples: string[]; }; additionalProcessors?: ", { "pluginId": "integrationAssistant", "scope": "common", @@ -357,7 +357,7 @@ "section": "def-common.ESProcessorItem", "text": "ESProcessorItem" }, - "[] | undefined; }; docs: Zod.objectOutputType<{}, Zod.ZodUnknown, \"strip\">[]; samplesFormat: { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }; celInput?: { program: string; stateSettings: {} & { [k: string]: unknown; }; redactVars: string[]; } | undefined; }[]; logo?: string | undefined; }; }" + "[] | undefined; }; docs: Zod.objectOutputType<{}, Zod.ZodUnknown, \"strip\">[]; samplesFormat: { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\" | \"cef\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }; celInput?: { program: string; stateSettings: {} & { [k: string]: unknown; }; redactVars: string[]; } | undefined; }[]; logo?: string | undefined; }; }" ], "path": "x-pack/plugins/integration_assistant/common/api/build_integration/build_integration.gen.ts", "deprecated": false, @@ -384,7 +384,7 @@ "label": "CategorizationRequestBody", "description": [], "signature": [ - "{ connectorId: string; packageName: string; rawSamples: string[]; samplesFormat: { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }; dataStreamName: string; currentPipeline: { processors: ", + "{ connectorId: string; packageName: string; rawSamples: string[]; samplesFormat: { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\" | \"cef\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }; dataStreamName: string; currentPipeline: { processors: ", { "pluginId": "integrationAssistant", "scope": "common", @@ -581,7 +581,7 @@ "section": "def-common.ESProcessorItem", "text": "ESProcessorItem" }, - "[] | undefined; }; docs: Zod.objectOutputType<{}, Zod.ZodUnknown, \"strip\">[]; samplesFormat: { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }; celInput?: { program: string; stateSettings: {} & { [k: string]: unknown; }; redactVars: string[]; } | undefined; }" + "[] | undefined; }; docs: Zod.objectOutputType<{}, Zod.ZodUnknown, \"strip\">[]; samplesFormat: { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\" | \"cef\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }; celInput?: { program: string; stateSettings: {} & { [k: string]: unknown; }; redactVars: string[]; } | undefined; }" ], "path": "x-pack/plugins/integration_assistant/common/api/model/common_attributes.gen.ts", "deprecated": false, @@ -625,7 +625,7 @@ "label": "EcsMappingRequestBody", "description": [], "signature": [ - "{ connectorId: string; packageName: string; rawSamples: string[]; samplesFormat: { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }; dataStreamName: string; langSmithOptions?: { apiKey: string; projectName: string; } | undefined; mapping?: Zod.objectOutputType<{}, Zod.ZodUnknown, \"strip\"> | undefined; additionalProcessors?: ", + "{ connectorId: string; packageName: string; rawSamples: string[]; samplesFormat: { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\" | \"cef\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }; dataStreamName: string; langSmithOptions?: { apiKey: string; projectName: string; } | undefined; mapping?: Zod.objectOutputType<{}, Zod.ZodUnknown, \"strip\"> | undefined; additionalProcessors?: ", { "pluginId": "integrationAssistant", "scope": "common", @@ -714,7 +714,7 @@ "section": "def-common.ESProcessorItem", "text": "ESProcessorItem" }, - "[] | undefined; }; docs: Zod.objectOutputType<{}, Zod.ZodUnknown, \"strip\">[]; samplesFormat: { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }; celInput?: { program: string; stateSettings: {} & { [k: string]: unknown; }; redactVars: string[]; } | undefined; }[]; logo?: string | undefined; }" + "[] | undefined; }; docs: Zod.objectOutputType<{}, Zod.ZodUnknown, \"strip\">[]; samplesFormat: { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\" | \"cef\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }; celInput?: { program: string; stateSettings: {} & { [k: string]: unknown; }; redactVars: string[]; } | undefined; }[]; logo?: string | undefined; }" ], "path": "x-pack/plugins/integration_assistant/common/api/model/common_attributes.gen.ts", "deprecated": false, @@ -848,7 +848,7 @@ "label": "RelatedRequestBody", "description": [], "signature": [ - "{ connectorId: string; packageName: string; rawSamples: string[]; samplesFormat: { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }; dataStreamName: string; currentPipeline: { processors: ", + "{ connectorId: string; packageName: string; rawSamples: string[]; samplesFormat: { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\" | \"cef\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }; dataStreamName: string; currentPipeline: { processors: ", { "pluginId": "integrationAssistant", "scope": "common", @@ -912,7 +912,7 @@ "\nFormat of the provided log samples." ], "signature": [ - "{ name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }" + "{ name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\" | \"cef\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }" ], "path": "x-pack/plugins/integration_assistant/common/api/model/common_attributes.gen.ts", "deprecated": false, @@ -929,7 +929,7 @@ "\nThe name of the log samples format." ], "signature": [ - "\"ndjson\" | \"json\" | \"csv\" | \"structured\" | \"unstructured\" | \"unsupported\"" + "\"ndjson\" | \"json\" | \"csv\" | \"structured\" | \"unstructured\" | \"unsupported\" | \"cef\"" ], "path": "x-pack/plugins/integration_assistant/common/api/model/common_attributes.gen.ts", "deprecated": false, @@ -971,7 +971,7 @@ }, ", Zod.ZodTypeDef, ", "ESProcessorItemInput", - ">, \"many\">>; results: Zod.ZodObject<{ samplesFormat: Zod.ZodObject<{ name: Zod.ZodEnum<[\"ndjson\", \"json\", \"csv\", \"structured\", \"unstructured\", \"unsupported\"]>; multiline: Zod.ZodOptional; header: Zod.ZodOptional; columns: Zod.ZodOptional>; json_path: Zod.ZodOptional>; }, \"strip\", Zod.ZodTypeAny, { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }, { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }>; parsedSamples: Zod.ZodArray; }, \"strip\", Zod.ZodTypeAny, { samplesFormat: { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }; parsedSamples: string[]; }, { samplesFormat: { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }; parsedSamples: string[]; }>; }, \"strip\", Zod.ZodTypeAny, { results: { samplesFormat: { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }; parsedSamples: string[]; }; additionalProcessors?: ", + ">, \"many\">>; results: Zod.ZodObject<{ samplesFormat: Zod.ZodObject<{ name: Zod.ZodEnum<[\"ndjson\", \"json\", \"csv\", \"structured\", \"unstructured\", \"unsupported\", \"cef\"]>; multiline: Zod.ZodOptional; header: Zod.ZodOptional; columns: Zod.ZodOptional>; json_path: Zod.ZodOptional>; }, \"strip\", Zod.ZodTypeAny, { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\" | \"cef\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }, { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\" | \"cef\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }>; parsedSamples: Zod.ZodArray; }, \"strip\", Zod.ZodTypeAny, { samplesFormat: { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\" | \"cef\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }; parsedSamples: string[]; }, { samplesFormat: { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\" | \"cef\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }; parsedSamples: string[]; }>; }, \"strip\", Zod.ZodTypeAny, { results: { samplesFormat: { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\" | \"cef\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }; parsedSamples: string[]; }; additionalProcessors?: ", { "pluginId": "integrationAssistant", "scope": "common", @@ -979,7 +979,7 @@ "section": "def-common.ESProcessorItem", "text": "ESProcessorItem" }, - "[] | undefined; }, { results: { samplesFormat: { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }; parsedSamples: string[]; }; additionalProcessors?: ", + "[] | undefined; }, { results: { samplesFormat: { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\" | \"cef\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }; parsedSamples: string[]; }; additionalProcessors?: ", "ESProcessorItemInput", "[] | undefined; }>" ], @@ -1036,7 +1036,7 @@ "ESProcessorItemInput", "[]; version?: number | undefined; name?: string | undefined; description?: string | undefined; on_failure?: ", "ESProcessorItemInput", - "[] | undefined; }>; docs: Zod.ZodArray, Zod.objectInputType<{}, Zod.ZodUnknown, \"strip\">>, \"many\">; samplesFormat: Zod.ZodObject<{ name: Zod.ZodEnum<[\"ndjson\", \"json\", \"csv\", \"structured\", \"unstructured\", \"unsupported\"]>; multiline: Zod.ZodOptional; header: Zod.ZodOptional; columns: Zod.ZodOptional>; json_path: Zod.ZodOptional>; }, \"strip\", Zod.ZodTypeAny, { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }, { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }>; celInput: Zod.ZodOptional, Zod.objectInputType<{}, Zod.ZodUnknown, \"strip\">>; redactVars: Zod.ZodArray; }, \"strip\", Zod.ZodTypeAny, { program: string; stateSettings: {} & { [k: string]: unknown; }; redactVars: string[]; }, { program: string; stateSettings: {} & { [k: string]: unknown; }; redactVars: string[]; }>>; }, \"strip\", Zod.ZodTypeAny, { name: string; title: string; description: string; inputTypes: (\"kafka\" | \"aws-cloudwatch\" | \"aws-s3\" | \"azure-blob-storage\" | \"azure-eventhub\" | \"cel\" | \"cloudfoundry\" | \"filestream\" | \"gcp-pubsub\" | \"gcs\" | \"http_endpoint\" | \"journald\" | \"tcp\" | \"udp\")[]; rawSamples: string[]; pipeline: { processors: ", + "[] | undefined; }>; docs: Zod.ZodArray, Zod.objectInputType<{}, Zod.ZodUnknown, \"strip\">>, \"many\">; samplesFormat: Zod.ZodObject<{ name: Zod.ZodEnum<[\"ndjson\", \"json\", \"csv\", \"structured\", \"unstructured\", \"unsupported\", \"cef\"]>; multiline: Zod.ZodOptional; header: Zod.ZodOptional; columns: Zod.ZodOptional>; json_path: Zod.ZodOptional>; }, \"strip\", Zod.ZodTypeAny, { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\" | \"cef\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }, { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\" | \"cef\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }>; celInput: Zod.ZodOptional, Zod.objectInputType<{}, Zod.ZodUnknown, \"strip\">>; redactVars: Zod.ZodArray; }, \"strip\", Zod.ZodTypeAny, { program: string; stateSettings: {} & { [k: string]: unknown; }; redactVars: string[]; }, { program: string; stateSettings: {} & { [k: string]: unknown; }; redactVars: string[]; }>>; }, \"strip\", Zod.ZodTypeAny, { name: string; title: string; description: string; inputTypes: (\"kafka\" | \"aws-cloudwatch\" | \"aws-s3\" | \"azure-blob-storage\" | \"azure-eventhub\" | \"cel\" | \"cloudfoundry\" | \"filestream\" | \"gcp-pubsub\" | \"gcs\" | \"http_endpoint\" | \"journald\" | \"tcp\" | \"udp\")[]; rawSamples: string[]; pipeline: { processors: ", { "pluginId": "integrationAssistant", "scope": "common", @@ -1052,11 +1052,11 @@ "section": "def-common.ESProcessorItem", "text": "ESProcessorItem" }, - "[] | undefined; }; docs: Zod.objectOutputType<{}, Zod.ZodUnknown, \"strip\">[]; samplesFormat: { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }; celInput?: { program: string; stateSettings: {} & { [k: string]: unknown; }; redactVars: string[]; } | undefined; }, { name: string; title: string; description: string; inputTypes: (\"kafka\" | \"aws-cloudwatch\" | \"aws-s3\" | \"azure-blob-storage\" | \"azure-eventhub\" | \"cel\" | \"cloudfoundry\" | \"filestream\" | \"gcp-pubsub\" | \"gcs\" | \"http_endpoint\" | \"journald\" | \"tcp\" | \"udp\")[]; rawSamples: string[]; pipeline: { processors: ", + "[] | undefined; }; docs: Zod.objectOutputType<{}, Zod.ZodUnknown, \"strip\">[]; samplesFormat: { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\" | \"cef\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }; celInput?: { program: string; stateSettings: {} & { [k: string]: unknown; }; redactVars: string[]; } | undefined; }, { name: string; title: string; description: string; inputTypes: (\"kafka\" | \"aws-cloudwatch\" | \"aws-s3\" | \"azure-blob-storage\" | \"azure-eventhub\" | \"cel\" | \"cloudfoundry\" | \"filestream\" | \"gcp-pubsub\" | \"gcs\" | \"http_endpoint\" | \"journald\" | \"tcp\" | \"udp\")[]; rawSamples: string[]; pipeline: { processors: ", "ESProcessorItemInput", "[]; version?: number | undefined; name?: string | undefined; description?: string | undefined; on_failure?: ", "ESProcessorItemInput", - "[] | undefined; }; docs: Zod.objectInputType<{}, Zod.ZodUnknown, \"strip\">[]; samplesFormat: { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }; celInput?: { program: string; stateSettings: {} & { [k: string]: unknown; }; redactVars: string[]; } | undefined; }>, \"many\">; logo: Zod.ZodOptional; }, \"strip\", Zod.ZodTypeAny, { name: string; title: string; description: string; dataStreams: { name: string; title: string; description: string; inputTypes: (\"kafka\" | \"aws-cloudwatch\" | \"aws-s3\" | \"azure-blob-storage\" | \"azure-eventhub\" | \"cel\" | \"cloudfoundry\" | \"filestream\" | \"gcp-pubsub\" | \"gcs\" | \"http_endpoint\" | \"journald\" | \"tcp\" | \"udp\")[]; rawSamples: string[]; pipeline: { processors: ", + "[] | undefined; }; docs: Zod.objectInputType<{}, Zod.ZodUnknown, \"strip\">[]; samplesFormat: { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\" | \"cef\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }; celInput?: { program: string; stateSettings: {} & { [k: string]: unknown; }; redactVars: string[]; } | undefined; }>, \"many\">; logo: Zod.ZodOptional; }, \"strip\", Zod.ZodTypeAny, { name: string; title: string; description: string; dataStreams: { name: string; title: string; description: string; inputTypes: (\"kafka\" | \"aws-cloudwatch\" | \"aws-s3\" | \"azure-blob-storage\" | \"azure-eventhub\" | \"cel\" | \"cloudfoundry\" | \"filestream\" | \"gcp-pubsub\" | \"gcs\" | \"http_endpoint\" | \"journald\" | \"tcp\" | \"udp\")[]; rawSamples: string[]; pipeline: { processors: ", { "pluginId": "integrationAssistant", "scope": "common", @@ -1072,11 +1072,11 @@ "section": "def-common.ESProcessorItem", "text": "ESProcessorItem" }, - "[] | undefined; }; docs: Zod.objectOutputType<{}, Zod.ZodUnknown, \"strip\">[]; samplesFormat: { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }; celInput?: { program: string; stateSettings: {} & { [k: string]: unknown; }; redactVars: string[]; } | undefined; }[]; logo?: string | undefined; }, { name: string; title: string; description: string; dataStreams: { name: string; title: string; description: string; inputTypes: (\"kafka\" | \"aws-cloudwatch\" | \"aws-s3\" | \"azure-blob-storage\" | \"azure-eventhub\" | \"cel\" | \"cloudfoundry\" | \"filestream\" | \"gcp-pubsub\" | \"gcs\" | \"http_endpoint\" | \"journald\" | \"tcp\" | \"udp\")[]; rawSamples: string[]; pipeline: { processors: ", + "[] | undefined; }; docs: Zod.objectOutputType<{}, Zod.ZodUnknown, \"strip\">[]; samplesFormat: { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\" | \"cef\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }; celInput?: { program: string; stateSettings: {} & { [k: string]: unknown; }; redactVars: string[]; } | undefined; }[]; logo?: string | undefined; }, { name: string; title: string; description: string; dataStreams: { name: string; title: string; description: string; inputTypes: (\"kafka\" | \"aws-cloudwatch\" | \"aws-s3\" | \"azure-blob-storage\" | \"azure-eventhub\" | \"cel\" | \"cloudfoundry\" | \"filestream\" | \"gcp-pubsub\" | \"gcs\" | \"http_endpoint\" | \"journald\" | \"tcp\" | \"udp\")[]; rawSamples: string[]; pipeline: { processors: ", "ESProcessorItemInput", "[]; version?: number | undefined; name?: string | undefined; description?: string | undefined; on_failure?: ", "ESProcessorItemInput", - "[] | undefined; }; docs: Zod.objectInputType<{}, Zod.ZodUnknown, \"strip\">[]; samplesFormat: { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }; celInput?: { program: string; stateSettings: {} & { [k: string]: unknown; }; redactVars: string[]; } | undefined; }[]; logo?: string | undefined; }>; }, \"strip\", Zod.ZodTypeAny, { integration: { name: string; title: string; description: string; dataStreams: { name: string; title: string; description: string; inputTypes: (\"kafka\" | \"aws-cloudwatch\" | \"aws-s3\" | \"azure-blob-storage\" | \"azure-eventhub\" | \"cel\" | \"cloudfoundry\" | \"filestream\" | \"gcp-pubsub\" | \"gcs\" | \"http_endpoint\" | \"journald\" | \"tcp\" | \"udp\")[]; rawSamples: string[]; pipeline: { processors: ", + "[] | undefined; }; docs: Zod.objectInputType<{}, Zod.ZodUnknown, \"strip\">[]; samplesFormat: { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\" | \"cef\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }; celInput?: { program: string; stateSettings: {} & { [k: string]: unknown; }; redactVars: string[]; } | undefined; }[]; logo?: string | undefined; }>; }, \"strip\", Zod.ZodTypeAny, { integration: { name: string; title: string; description: string; dataStreams: { name: string; title: string; description: string; inputTypes: (\"kafka\" | \"aws-cloudwatch\" | \"aws-s3\" | \"azure-blob-storage\" | \"azure-eventhub\" | \"cel\" | \"cloudfoundry\" | \"filestream\" | \"gcp-pubsub\" | \"gcs\" | \"http_endpoint\" | \"journald\" | \"tcp\" | \"udp\")[]; rawSamples: string[]; pipeline: { processors: ", { "pluginId": "integrationAssistant", "scope": "common", @@ -1092,11 +1092,11 @@ "section": "def-common.ESProcessorItem", "text": "ESProcessorItem" }, - "[] | undefined; }; docs: Zod.objectOutputType<{}, Zod.ZodUnknown, \"strip\">[]; samplesFormat: { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }; celInput?: { program: string; stateSettings: {} & { [k: string]: unknown; }; redactVars: string[]; } | undefined; }[]; logo?: string | undefined; }; }, { integration: { name: string; title: string; description: string; dataStreams: { name: string; title: string; description: string; inputTypes: (\"kafka\" | \"aws-cloudwatch\" | \"aws-s3\" | \"azure-blob-storage\" | \"azure-eventhub\" | \"cel\" | \"cloudfoundry\" | \"filestream\" | \"gcp-pubsub\" | \"gcs\" | \"http_endpoint\" | \"journald\" | \"tcp\" | \"udp\")[]; rawSamples: string[]; pipeline: { processors: ", + "[] | undefined; }; docs: Zod.objectOutputType<{}, Zod.ZodUnknown, \"strip\">[]; samplesFormat: { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\" | \"cef\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }; celInput?: { program: string; stateSettings: {} & { [k: string]: unknown; }; redactVars: string[]; } | undefined; }[]; logo?: string | undefined; }; }, { integration: { name: string; title: string; description: string; dataStreams: { name: string; title: string; description: string; inputTypes: (\"kafka\" | \"aws-cloudwatch\" | \"aws-s3\" | \"azure-blob-storage\" | \"azure-eventhub\" | \"cel\" | \"cloudfoundry\" | \"filestream\" | \"gcp-pubsub\" | \"gcs\" | \"http_endpoint\" | \"journald\" | \"tcp\" | \"udp\")[]; rawSamples: string[]; pipeline: { processors: ", "ESProcessorItemInput", "[]; version?: number | undefined; name?: string | undefined; description?: string | undefined; on_failure?: ", "ESProcessorItemInput", - "[] | undefined; }; docs: Zod.objectInputType<{}, Zod.ZodUnknown, \"strip\">[]; samplesFormat: { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }; celInput?: { program: string; stateSettings: {} & { [k: string]: unknown; }; redactVars: string[]; } | undefined; }[]; logo?: string | undefined; }; }>" + "[] | undefined; }; docs: Zod.objectInputType<{}, Zod.ZodUnknown, \"strip\">[]; samplesFormat: { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\" | \"cef\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }; celInput?: { program: string; stateSettings: {} & { [k: string]: unknown; }; redactVars: string[]; } | undefined; }[]; logo?: string | undefined; }; }>" ], "path": "x-pack/plugins/integration_assistant/common/api/build_integration/build_integration.gen.ts", "deprecated": false, @@ -1151,7 +1151,7 @@ "ESProcessorItemInput", "[]; version?: number | undefined; name?: string | undefined; description?: string | undefined; on_failure?: ", "ESProcessorItemInput", - "[] | undefined; }>; connectorId: Zod.ZodString; samplesFormat: Zod.ZodObject<{ name: Zod.ZodEnum<[\"ndjson\", \"json\", \"csv\", \"structured\", \"unstructured\", \"unsupported\"]>; multiline: Zod.ZodOptional; header: Zod.ZodOptional; columns: Zod.ZodOptional>; json_path: Zod.ZodOptional>; }, \"strip\", Zod.ZodTypeAny, { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }, { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }>; langSmithOptions: Zod.ZodOptional>; }, \"strip\", Zod.ZodTypeAny, { connectorId: string; packageName: string; rawSamples: string[]; samplesFormat: { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }; dataStreamName: string; currentPipeline: { processors: ", + "[] | undefined; }>; connectorId: Zod.ZodString; samplesFormat: Zod.ZodObject<{ name: Zod.ZodEnum<[\"ndjson\", \"json\", \"csv\", \"structured\", \"unstructured\", \"unsupported\", \"cef\"]>; multiline: Zod.ZodOptional; header: Zod.ZodOptional; columns: Zod.ZodOptional>; json_path: Zod.ZodOptional>; }, \"strip\", Zod.ZodTypeAny, { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\" | \"cef\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }, { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\" | \"cef\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }>; langSmithOptions: Zod.ZodOptional>; }, \"strip\", Zod.ZodTypeAny, { connectorId: string; packageName: string; rawSamples: string[]; samplesFormat: { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\" | \"cef\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }; dataStreamName: string; currentPipeline: { processors: ", { "pluginId": "integrationAssistant", "scope": "common", @@ -1167,7 +1167,7 @@ "section": "def-common.ESProcessorItem", "text": "ESProcessorItem" }, - "[] | undefined; }; langSmithOptions?: { apiKey: string; projectName: string; } | undefined; }, { connectorId: string; packageName: string; rawSamples: string[]; samplesFormat: { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }; dataStreamName: string; currentPipeline: { processors: ", + "[] | undefined; }; langSmithOptions?: { apiKey: string; projectName: string; } | undefined; }, { connectorId: string; packageName: string; rawSamples: string[]; samplesFormat: { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\" | \"cef\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }; dataStreamName: string; currentPipeline: { processors: ", "ESProcessorItemInput", "[]; version?: number | undefined; name?: string | undefined; description?: string | undefined; on_failure?: ", "ESProcessorItemInput", @@ -1456,7 +1456,7 @@ "ESProcessorItemInput", "[]; version?: number | undefined; name?: string | undefined; description?: string | undefined; on_failure?: ", "ESProcessorItemInput", - "[] | undefined; }>; docs: Zod.ZodArray, Zod.objectInputType<{}, Zod.ZodUnknown, \"strip\">>, \"many\">; samplesFormat: Zod.ZodObject<{ name: Zod.ZodEnum<[\"ndjson\", \"json\", \"csv\", \"structured\", \"unstructured\", \"unsupported\"]>; multiline: Zod.ZodOptional; header: Zod.ZodOptional; columns: Zod.ZodOptional>; json_path: Zod.ZodOptional>; }, \"strip\", Zod.ZodTypeAny, { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }, { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }>; celInput: Zod.ZodOptional, Zod.objectInputType<{}, Zod.ZodUnknown, \"strip\">>; redactVars: Zod.ZodArray; }, \"strip\", Zod.ZodTypeAny, { program: string; stateSettings: {} & { [k: string]: unknown; }; redactVars: string[]; }, { program: string; stateSettings: {} & { [k: string]: unknown; }; redactVars: string[]; }>>; }, \"strip\", Zod.ZodTypeAny, { name: string; title: string; description: string; inputTypes: (\"kafka\" | \"aws-cloudwatch\" | \"aws-s3\" | \"azure-blob-storage\" | \"azure-eventhub\" | \"cel\" | \"cloudfoundry\" | \"filestream\" | \"gcp-pubsub\" | \"gcs\" | \"http_endpoint\" | \"journald\" | \"tcp\" | \"udp\")[]; rawSamples: string[]; pipeline: { processors: ", + "[] | undefined; }>; docs: Zod.ZodArray, Zod.objectInputType<{}, Zod.ZodUnknown, \"strip\">>, \"many\">; samplesFormat: Zod.ZodObject<{ name: Zod.ZodEnum<[\"ndjson\", \"json\", \"csv\", \"structured\", \"unstructured\", \"unsupported\", \"cef\"]>; multiline: Zod.ZodOptional; header: Zod.ZodOptional; columns: Zod.ZodOptional>; json_path: Zod.ZodOptional>; }, \"strip\", Zod.ZodTypeAny, { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\" | \"cef\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }, { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\" | \"cef\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }>; celInput: Zod.ZodOptional, Zod.objectInputType<{}, Zod.ZodUnknown, \"strip\">>; redactVars: Zod.ZodArray; }, \"strip\", Zod.ZodTypeAny, { program: string; stateSettings: {} & { [k: string]: unknown; }; redactVars: string[]; }, { program: string; stateSettings: {} & { [k: string]: unknown; }; redactVars: string[]; }>>; }, \"strip\", Zod.ZodTypeAny, { name: string; title: string; description: string; inputTypes: (\"kafka\" | \"aws-cloudwatch\" | \"aws-s3\" | \"azure-blob-storage\" | \"azure-eventhub\" | \"cel\" | \"cloudfoundry\" | \"filestream\" | \"gcp-pubsub\" | \"gcs\" | \"http_endpoint\" | \"journald\" | \"tcp\" | \"udp\")[]; rawSamples: string[]; pipeline: { processors: ", { "pluginId": "integrationAssistant", "scope": "common", @@ -1472,11 +1472,11 @@ "section": "def-common.ESProcessorItem", "text": "ESProcessorItem" }, - "[] | undefined; }; docs: Zod.objectOutputType<{}, Zod.ZodUnknown, \"strip\">[]; samplesFormat: { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }; celInput?: { program: string; stateSettings: {} & { [k: string]: unknown; }; redactVars: string[]; } | undefined; }, { name: string; title: string; description: string; inputTypes: (\"kafka\" | \"aws-cloudwatch\" | \"aws-s3\" | \"azure-blob-storage\" | \"azure-eventhub\" | \"cel\" | \"cloudfoundry\" | \"filestream\" | \"gcp-pubsub\" | \"gcs\" | \"http_endpoint\" | \"journald\" | \"tcp\" | \"udp\")[]; rawSamples: string[]; pipeline: { processors: ", + "[] | undefined; }; docs: Zod.objectOutputType<{}, Zod.ZodUnknown, \"strip\">[]; samplesFormat: { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\" | \"cef\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }; celInput?: { program: string; stateSettings: {} & { [k: string]: unknown; }; redactVars: string[]; } | undefined; }, { name: string; title: string; description: string; inputTypes: (\"kafka\" | \"aws-cloudwatch\" | \"aws-s3\" | \"azure-blob-storage\" | \"azure-eventhub\" | \"cel\" | \"cloudfoundry\" | \"filestream\" | \"gcp-pubsub\" | \"gcs\" | \"http_endpoint\" | \"journald\" | \"tcp\" | \"udp\")[]; rawSamples: string[]; pipeline: { processors: ", "ESProcessorItemInput", "[]; version?: number | undefined; name?: string | undefined; description?: string | undefined; on_failure?: ", "ESProcessorItemInput", - "[] | undefined; }; docs: Zod.objectInputType<{}, Zod.ZodUnknown, \"strip\">[]; samplesFormat: { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }; celInput?: { program: string; stateSettings: {} & { [k: string]: unknown; }; redactVars: string[]; } | undefined; }>" + "[] | undefined; }; docs: Zod.objectInputType<{}, Zod.ZodUnknown, \"strip\">[]; samplesFormat: { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\" | \"cef\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }; celInput?: { program: string; stateSettings: {} & { [k: string]: unknown; }; redactVars: string[]; } | undefined; }>" ], "path": "x-pack/plugins/integration_assistant/common/api/model/common_attributes.gen.ts", "deprecated": false, @@ -1506,7 +1506,7 @@ "label": "EcsMappingRequestBody", "description": [], "signature": [ - "Zod.ZodObject<{ packageName: Zod.ZodString; dataStreamName: Zod.ZodString; rawSamples: Zod.ZodArray; samplesFormat: Zod.ZodObject<{ name: Zod.ZodEnum<[\"ndjson\", \"json\", \"csv\", \"structured\", \"unstructured\", \"unsupported\"]>; multiline: Zod.ZodOptional; header: Zod.ZodOptional; columns: Zod.ZodOptional>; json_path: Zod.ZodOptional>; }, \"strip\", Zod.ZodTypeAny, { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }, { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }>; mapping: Zod.ZodOptional, Zod.objectInputType<{}, Zod.ZodUnknown, \"strip\">>>; additionalProcessors: Zod.ZodOptional; samplesFormat: Zod.ZodObject<{ name: Zod.ZodEnum<[\"ndjson\", \"json\", \"csv\", \"structured\", \"unstructured\", \"unsupported\", \"cef\"]>; multiline: Zod.ZodOptional; header: Zod.ZodOptional; columns: Zod.ZodOptional>; json_path: Zod.ZodOptional>; }, \"strip\", Zod.ZodTypeAny, { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\" | \"cef\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }, { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\" | \"cef\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }>; mapping: Zod.ZodOptional, Zod.objectInputType<{}, Zod.ZodUnknown, \"strip\">>>; additionalProcessors: Zod.ZodOptional, \"many\">>; connectorId: Zod.ZodString; langSmithOptions: Zod.ZodOptional>; }, \"strip\", Zod.ZodTypeAny, { connectorId: string; packageName: string; rawSamples: string[]; samplesFormat: { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }; dataStreamName: string; langSmithOptions?: { apiKey: string; projectName: string; } | undefined; mapping?: Zod.objectOutputType<{}, Zod.ZodUnknown, \"strip\"> | undefined; additionalProcessors?: ", + ">, \"many\">>; connectorId: Zod.ZodString; langSmithOptions: Zod.ZodOptional>; }, \"strip\", Zod.ZodTypeAny, { connectorId: string; packageName: string; rawSamples: string[]; samplesFormat: { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\" | \"cef\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }; dataStreamName: string; langSmithOptions?: { apiKey: string; projectName: string; } | undefined; mapping?: Zod.objectOutputType<{}, Zod.ZodUnknown, \"strip\"> | undefined; additionalProcessors?: ", { "pluginId": "integrationAssistant", "scope": "common", @@ -1524,7 +1524,7 @@ "section": "def-common.ESProcessorItem", "text": "ESProcessorItem" }, - "[] | undefined; }, { connectorId: string; packageName: string; rawSamples: string[]; samplesFormat: { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }; dataStreamName: string; langSmithOptions?: { apiKey: string; projectName: string; } | undefined; mapping?: Zod.objectInputType<{}, Zod.ZodUnknown, \"strip\"> | undefined; additionalProcessors?: ", + "[] | undefined; }, { connectorId: string; packageName: string; rawSamples: string[]; samplesFormat: { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\" | \"cef\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }; dataStreamName: string; langSmithOptions?: { apiKey: string; projectName: string; } | undefined; mapping?: Zod.objectInputType<{}, Zod.ZodUnknown, \"strip\"> | undefined; additionalProcessors?: ", "ESProcessorItemInput", "[] | undefined; }>" ], @@ -1716,7 +1716,7 @@ "ESProcessorItemInput", "[]; version?: number | undefined; name?: string | undefined; description?: string | undefined; on_failure?: ", "ESProcessorItemInput", - "[] | undefined; }>; docs: Zod.ZodArray, Zod.objectInputType<{}, Zod.ZodUnknown, \"strip\">>, \"many\">; samplesFormat: Zod.ZodObject<{ name: Zod.ZodEnum<[\"ndjson\", \"json\", \"csv\", \"structured\", \"unstructured\", \"unsupported\"]>; multiline: Zod.ZodOptional; header: Zod.ZodOptional; columns: Zod.ZodOptional>; json_path: Zod.ZodOptional>; }, \"strip\", Zod.ZodTypeAny, { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }, { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }>; celInput: Zod.ZodOptional, Zod.objectInputType<{}, Zod.ZodUnknown, \"strip\">>; redactVars: Zod.ZodArray; }, \"strip\", Zod.ZodTypeAny, { program: string; stateSettings: {} & { [k: string]: unknown; }; redactVars: string[]; }, { program: string; stateSettings: {} & { [k: string]: unknown; }; redactVars: string[]; }>>; }, \"strip\", Zod.ZodTypeAny, { name: string; title: string; description: string; inputTypes: (\"kafka\" | \"aws-cloudwatch\" | \"aws-s3\" | \"azure-blob-storage\" | \"azure-eventhub\" | \"cel\" | \"cloudfoundry\" | \"filestream\" | \"gcp-pubsub\" | \"gcs\" | \"http_endpoint\" | \"journald\" | \"tcp\" | \"udp\")[]; rawSamples: string[]; pipeline: { processors: ", + "[] | undefined; }>; docs: Zod.ZodArray, Zod.objectInputType<{}, Zod.ZodUnknown, \"strip\">>, \"many\">; samplesFormat: Zod.ZodObject<{ name: Zod.ZodEnum<[\"ndjson\", \"json\", \"csv\", \"structured\", \"unstructured\", \"unsupported\", \"cef\"]>; multiline: Zod.ZodOptional; header: Zod.ZodOptional; columns: Zod.ZodOptional>; json_path: Zod.ZodOptional>; }, \"strip\", Zod.ZodTypeAny, { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\" | \"cef\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }, { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\" | \"cef\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }>; celInput: Zod.ZodOptional, Zod.objectInputType<{}, Zod.ZodUnknown, \"strip\">>; redactVars: Zod.ZodArray; }, \"strip\", Zod.ZodTypeAny, { program: string; stateSettings: {} & { [k: string]: unknown; }; redactVars: string[]; }, { program: string; stateSettings: {} & { [k: string]: unknown; }; redactVars: string[]; }>>; }, \"strip\", Zod.ZodTypeAny, { name: string; title: string; description: string; inputTypes: (\"kafka\" | \"aws-cloudwatch\" | \"aws-s3\" | \"azure-blob-storage\" | \"azure-eventhub\" | \"cel\" | \"cloudfoundry\" | \"filestream\" | \"gcp-pubsub\" | \"gcs\" | \"http_endpoint\" | \"journald\" | \"tcp\" | \"udp\")[]; rawSamples: string[]; pipeline: { processors: ", { "pluginId": "integrationAssistant", "scope": "common", @@ -1732,11 +1732,11 @@ "section": "def-common.ESProcessorItem", "text": "ESProcessorItem" }, - "[] | undefined; }; docs: Zod.objectOutputType<{}, Zod.ZodUnknown, \"strip\">[]; samplesFormat: { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }; celInput?: { program: string; stateSettings: {} & { [k: string]: unknown; }; redactVars: string[]; } | undefined; }, { name: string; title: string; description: string; inputTypes: (\"kafka\" | \"aws-cloudwatch\" | \"aws-s3\" | \"azure-blob-storage\" | \"azure-eventhub\" | \"cel\" | \"cloudfoundry\" | \"filestream\" | \"gcp-pubsub\" | \"gcs\" | \"http_endpoint\" | \"journald\" | \"tcp\" | \"udp\")[]; rawSamples: string[]; pipeline: { processors: ", + "[] | undefined; }; docs: Zod.objectOutputType<{}, Zod.ZodUnknown, \"strip\">[]; samplesFormat: { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\" | \"cef\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }; celInput?: { program: string; stateSettings: {} & { [k: string]: unknown; }; redactVars: string[]; } | undefined; }, { name: string; title: string; description: string; inputTypes: (\"kafka\" | \"aws-cloudwatch\" | \"aws-s3\" | \"azure-blob-storage\" | \"azure-eventhub\" | \"cel\" | \"cloudfoundry\" | \"filestream\" | \"gcp-pubsub\" | \"gcs\" | \"http_endpoint\" | \"journald\" | \"tcp\" | \"udp\")[]; rawSamples: string[]; pipeline: { processors: ", "ESProcessorItemInput", "[]; version?: number | undefined; name?: string | undefined; description?: string | undefined; on_failure?: ", "ESProcessorItemInput", - "[] | undefined; }; docs: Zod.objectInputType<{}, Zod.ZodUnknown, \"strip\">[]; samplesFormat: { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }; celInput?: { program: string; stateSettings: {} & { [k: string]: unknown; }; redactVars: string[]; } | undefined; }>, \"many\">; logo: Zod.ZodOptional; }, \"strip\", Zod.ZodTypeAny, { name: string; title: string; description: string; dataStreams: { name: string; title: string; description: string; inputTypes: (\"kafka\" | \"aws-cloudwatch\" | \"aws-s3\" | \"azure-blob-storage\" | \"azure-eventhub\" | \"cel\" | \"cloudfoundry\" | \"filestream\" | \"gcp-pubsub\" | \"gcs\" | \"http_endpoint\" | \"journald\" | \"tcp\" | \"udp\")[]; rawSamples: string[]; pipeline: { processors: ", + "[] | undefined; }; docs: Zod.objectInputType<{}, Zod.ZodUnknown, \"strip\">[]; samplesFormat: { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\" | \"cef\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }; celInput?: { program: string; stateSettings: {} & { [k: string]: unknown; }; redactVars: string[]; } | undefined; }>, \"many\">; logo: Zod.ZodOptional; }, \"strip\", Zod.ZodTypeAny, { name: string; title: string; description: string; dataStreams: { name: string; title: string; description: string; inputTypes: (\"kafka\" | \"aws-cloudwatch\" | \"aws-s3\" | \"azure-blob-storage\" | \"azure-eventhub\" | \"cel\" | \"cloudfoundry\" | \"filestream\" | \"gcp-pubsub\" | \"gcs\" | \"http_endpoint\" | \"journald\" | \"tcp\" | \"udp\")[]; rawSamples: string[]; pipeline: { processors: ", { "pluginId": "integrationAssistant", "scope": "common", @@ -1752,11 +1752,11 @@ "section": "def-common.ESProcessorItem", "text": "ESProcessorItem" }, - "[] | undefined; }; docs: Zod.objectOutputType<{}, Zod.ZodUnknown, \"strip\">[]; samplesFormat: { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }; celInput?: { program: string; stateSettings: {} & { [k: string]: unknown; }; redactVars: string[]; } | undefined; }[]; logo?: string | undefined; }, { name: string; title: string; description: string; dataStreams: { name: string; title: string; description: string; inputTypes: (\"kafka\" | \"aws-cloudwatch\" | \"aws-s3\" | \"azure-blob-storage\" | \"azure-eventhub\" | \"cel\" | \"cloudfoundry\" | \"filestream\" | \"gcp-pubsub\" | \"gcs\" | \"http_endpoint\" | \"journald\" | \"tcp\" | \"udp\")[]; rawSamples: string[]; pipeline: { processors: ", + "[] | undefined; }; docs: Zod.objectOutputType<{}, Zod.ZodUnknown, \"strip\">[]; samplesFormat: { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\" | \"cef\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }; celInput?: { program: string; stateSettings: {} & { [k: string]: unknown; }; redactVars: string[]; } | undefined; }[]; logo?: string | undefined; }, { name: string; title: string; description: string; dataStreams: { name: string; title: string; description: string; inputTypes: (\"kafka\" | \"aws-cloudwatch\" | \"aws-s3\" | \"azure-blob-storage\" | \"azure-eventhub\" | \"cel\" | \"cloudfoundry\" | \"filestream\" | \"gcp-pubsub\" | \"gcs\" | \"http_endpoint\" | \"journald\" | \"tcp\" | \"udp\")[]; rawSamples: string[]; pipeline: { processors: ", "ESProcessorItemInput", "[]; version?: number | undefined; name?: string | undefined; description?: string | undefined; on_failure?: ", "ESProcessorItemInput", - "[] | undefined; }; docs: Zod.objectInputType<{}, Zod.ZodUnknown, \"strip\">[]; samplesFormat: { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }; celInput?: { program: string; stateSettings: {} & { [k: string]: unknown; }; redactVars: string[]; } | undefined; }[]; logo?: string | undefined; }>" + "[] | undefined; }; docs: Zod.objectInputType<{}, Zod.ZodUnknown, \"strip\">[]; samplesFormat: { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\" | \"cef\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }; celInput?: { program: string; stateSettings: {} & { [k: string]: unknown; }; redactVars: string[]; } | undefined; }[]; logo?: string | undefined; }>" ], "path": "x-pack/plugins/integration_assistant/common/api/model/common_attributes.gen.ts", "deprecated": false, @@ -1881,7 +1881,7 @@ "ESProcessorItemInput", "[]; version?: number | undefined; name?: string | undefined; description?: string | undefined; on_failure?: ", "ESProcessorItemInput", - "[] | undefined; }>; connectorId: Zod.ZodString; samplesFormat: Zod.ZodObject<{ name: Zod.ZodEnum<[\"ndjson\", \"json\", \"csv\", \"structured\", \"unstructured\", \"unsupported\"]>; multiline: Zod.ZodOptional; header: Zod.ZodOptional; columns: Zod.ZodOptional>; json_path: Zod.ZodOptional>; }, \"strip\", Zod.ZodTypeAny, { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }, { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }>; langSmithOptions: Zod.ZodOptional>; }, \"strip\", Zod.ZodTypeAny, { connectorId: string; packageName: string; rawSamples: string[]; samplesFormat: { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }; dataStreamName: string; currentPipeline: { processors: ", + "[] | undefined; }>; connectorId: Zod.ZodString; samplesFormat: Zod.ZodObject<{ name: Zod.ZodEnum<[\"ndjson\", \"json\", \"csv\", \"structured\", \"unstructured\", \"unsupported\", \"cef\"]>; multiline: Zod.ZodOptional; header: Zod.ZodOptional; columns: Zod.ZodOptional>; json_path: Zod.ZodOptional>; }, \"strip\", Zod.ZodTypeAny, { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\" | \"cef\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }, { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\" | \"cef\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }>; langSmithOptions: Zod.ZodOptional>; }, \"strip\", Zod.ZodTypeAny, { connectorId: string; packageName: string; rawSamples: string[]; samplesFormat: { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\" | \"cef\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }; dataStreamName: string; currentPipeline: { processors: ", { "pluginId": "integrationAssistant", "scope": "common", @@ -1897,7 +1897,7 @@ "section": "def-common.ESProcessorItem", "text": "ESProcessorItem" }, - "[] | undefined; }; langSmithOptions?: { apiKey: string; projectName: string; } | undefined; }, { connectorId: string; packageName: string; rawSamples: string[]; samplesFormat: { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }; dataStreamName: string; currentPipeline: { processors: ", + "[] | undefined; }; langSmithOptions?: { apiKey: string; projectName: string; } | undefined; }, { connectorId: string; packageName: string; rawSamples: string[]; samplesFormat: { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\" | \"cef\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }; dataStreamName: string; currentPipeline: { processors: ", "ESProcessorItemInput", "[]; version?: number | undefined; name?: string | undefined; description?: string | undefined; on_failure?: ", "ESProcessorItemInput", @@ -2011,7 +2011,7 @@ "label": "SamplesFormat", "description": [], "signature": [ - "Zod.ZodObject<{ name: Zod.ZodEnum<[\"ndjson\", \"json\", \"csv\", \"structured\", \"unstructured\", \"unsupported\"]>; multiline: Zod.ZodOptional; header: Zod.ZodOptional; columns: Zod.ZodOptional>; json_path: Zod.ZodOptional>; }, \"strip\", Zod.ZodTypeAny, { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }, { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }>" + "Zod.ZodObject<{ name: Zod.ZodEnum<[\"ndjson\", \"json\", \"csv\", \"structured\", \"unstructured\", \"unsupported\", \"cef\"]>; multiline: Zod.ZodOptional; header: Zod.ZodOptional; columns: Zod.ZodOptional>; json_path: Zod.ZodOptional>; }, \"strip\", Zod.ZodTypeAny, { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\" | \"cef\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }, { name: \"unsupported\" | \"json\" | \"ndjson\" | \"csv\" | \"structured\" | \"unstructured\" | \"cef\"; columns?: string[] | undefined; header?: boolean | undefined; multiline?: boolean | undefined; json_path?: string[] | undefined; }>" ], "path": "x-pack/plugins/integration_assistant/common/api/model/common_attributes.gen.ts", "deprecated": false, @@ -2026,7 +2026,7 @@ "label": "SamplesFormatName", "description": [], "signature": [ - "Zod.ZodEnum<[\"ndjson\", \"json\", \"csv\", \"structured\", \"unstructured\", \"unsupported\"]>" + "Zod.ZodEnum<[\"ndjson\", \"json\", \"csv\", \"structured\", \"unstructured\", \"unsupported\", \"cef\"]>" ], "path": "x-pack/plugins/integration_assistant/common/api/model/common_attributes.gen.ts", "deprecated": false, diff --git a/api_docs/integration_assistant.mdx b/api_docs/integration_assistant.mdx index c35088a6aeb3f..8d8a9090a8272 100644 --- a/api_docs/integration_assistant.mdx +++ b/api_docs/integration_assistant.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/integrationAssistant title: "integrationAssistant" image: https://source.unsplash.com/400x175/?github description: API docs for the integrationAssistant plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'integrationAssistant'] --- import integrationAssistantObj from './integration_assistant.devdocs.json'; diff --git a/api_docs/interactive_setup.mdx b/api_docs/interactive_setup.mdx index 47019babbdf07..8a5c806b2c6a6 100644 --- a/api_docs/interactive_setup.mdx +++ b/api_docs/interactive_setup.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/interactiveSetup title: "interactiveSetup" image: https://source.unsplash.com/400x175/?github description: API docs for the interactiveSetup plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'interactiveSetup'] --- import interactiveSetupObj from './interactive_setup.devdocs.json'; diff --git a/api_docs/inventory.devdocs.json b/api_docs/inventory.devdocs.json index 00f3e7b5b9b81..39c0d7b7c7b69 100644 --- a/api_docs/inventory.devdocs.json +++ b/api_docs/inventory.devdocs.json @@ -82,9 +82,13 @@ "PartialC", "<{ query: ", "PartialC", - "<{ esQuery: ", + "<{ includeEntityTypes: ", "Type", - "<{ [key: string]: unknown; }, string, unknown>; }>; }>]>, ", + "; excludeEntityTypes: ", + "Type", + "; kuery: ", + "StringC", + "; }>; }>]>, ", "InventoryRouteHandlerResources", ", { groupBy: \"entity.type\"; groups: ", "EntityGroup", @@ -136,9 +140,9 @@ "LiteralC", "<\"desc\">]>; }>, ", "PartialC", - "<{ esQuery: ", - "Type", - "<{ [key: string]: unknown; }, string, unknown>; entityTypes: ", + "<{ kuery: ", + "StringC", + "; entityTypes: ", "Type", "; }>]>; }>, ", "InventoryRouteHandlerResources", diff --git a/api_docs/inventory.mdx b/api_docs/inventory.mdx index 9e92b64c29eda..aadd2ea61f55f 100644 --- a/api_docs/inventory.mdx +++ b/api_docs/inventory.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/inventory title: "inventory" image: https://source.unsplash.com/400x175/?github description: API docs for the inventory plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'inventory'] --- import inventoryObj from './inventory.devdocs.json'; diff --git a/api_docs/investigate.mdx b/api_docs/investigate.mdx index fc5d4930d0e87..655656d8e900c 100644 --- a/api_docs/investigate.mdx +++ b/api_docs/investigate.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/investigate title: "investigate" image: https://source.unsplash.com/400x175/?github description: API docs for the investigate plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'investigate'] --- import investigateObj from './investigate.devdocs.json'; diff --git a/api_docs/investigate_app.mdx b/api_docs/investigate_app.mdx index d6ab7d9695e52..8d11653091be4 100644 --- a/api_docs/investigate_app.mdx +++ b/api_docs/investigate_app.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/investigateApp title: "investigateApp" image: https://source.unsplash.com/400x175/?github description: API docs for the investigateApp plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'investigateApp'] --- import investigateAppObj from './investigate_app.devdocs.json'; diff --git a/api_docs/kbn_actions_types.mdx b/api_docs/kbn_actions_types.mdx index c4c44a6ecf0e2..bc6e94cfac6eb 100644 --- a/api_docs/kbn_actions_types.mdx +++ b/api_docs/kbn_actions_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-actions-types title: "@kbn/actions-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/actions-types plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/actions-types'] --- import kbnActionsTypesObj from './kbn_actions_types.devdocs.json'; diff --git a/api_docs/kbn_ai_assistant.mdx b/api_docs/kbn_ai_assistant.mdx index 51085ff3d9ebd..c683aeba68730 100644 --- a/api_docs/kbn_ai_assistant.mdx +++ b/api_docs/kbn_ai_assistant.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ai-assistant title: "@kbn/ai-assistant" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ai-assistant plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ai-assistant'] --- import kbnAiAssistantObj from './kbn_ai_assistant.devdocs.json'; diff --git a/api_docs/kbn_ai_assistant_common.mdx b/api_docs/kbn_ai_assistant_common.mdx index 2c33acd3843dd..f19f97a4449f4 100644 --- a/api_docs/kbn_ai_assistant_common.mdx +++ b/api_docs/kbn_ai_assistant_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ai-assistant-common title: "@kbn/ai-assistant-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ai-assistant-common plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ai-assistant-common'] --- import kbnAiAssistantCommonObj from './kbn_ai_assistant_common.devdocs.json'; diff --git a/api_docs/kbn_aiops_components.devdocs.json b/api_docs/kbn_aiops_components.devdocs.json index 90b929e81e677..fc526124b270a 100644 --- a/api_docs/kbn_aiops_components.devdocs.json +++ b/api_docs/kbn_aiops_components.devdocs.json @@ -703,6 +703,22 @@ "path": "x-pack/packages/ml/aiops_components/src/document_count_chart/document_count_chart.tsx", "deprecated": false, "trackAdoption": false + }, + { + "parentPluginId": "@kbn/aiops-components", + "id": "def-common.DocumentCountChartProps.nonInteractive", + "type": "CompoundType", + "tags": [], + "label": "nonInteractive", + "description": [ + "Whether the brush should be non-interactive" + ], + "signature": [ + "boolean | undefined" + ], + "path": "x-pack/packages/ml/aiops_components/src/document_count_chart/document_count_chart.tsx", + "deprecated": false, + "trackAdoption": false } ], "initialIsOpen": false diff --git a/api_docs/kbn_aiops_components.mdx b/api_docs/kbn_aiops_components.mdx index 610032407e0a1..f97b1a673f4e3 100644 --- a/api_docs/kbn_aiops_components.mdx +++ b/api_docs/kbn_aiops_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-aiops-components title: "@kbn/aiops-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/aiops-components plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/aiops-components'] --- import kbnAiopsComponentsObj from './kbn_aiops_components.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 | |-------------------|-----------|------------------------|-----------------| -| 36 | 0 | 0 | 0 | +| 37 | 0 | 0 | 0 | ## Common diff --git a/api_docs/kbn_aiops_log_pattern_analysis.mdx b/api_docs/kbn_aiops_log_pattern_analysis.mdx index e651323c3ffcc..fbac611741b86 100644 --- a/api_docs/kbn_aiops_log_pattern_analysis.mdx +++ b/api_docs/kbn_aiops_log_pattern_analysis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-aiops-log-pattern-analysis title: "@kbn/aiops-log-pattern-analysis" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/aiops-log-pattern-analysis plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/aiops-log-pattern-analysis'] --- import kbnAiopsLogPatternAnalysisObj from './kbn_aiops_log_pattern_analysis.devdocs.json'; diff --git a/api_docs/kbn_aiops_log_rate_analysis.mdx b/api_docs/kbn_aiops_log_rate_analysis.mdx index 27562cf8c2ffb..3dd810cf505b6 100644 --- a/api_docs/kbn_aiops_log_rate_analysis.mdx +++ b/api_docs/kbn_aiops_log_rate_analysis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-aiops-log-rate-analysis title: "@kbn/aiops-log-rate-analysis" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/aiops-log-rate-analysis plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/aiops-log-rate-analysis'] --- import kbnAiopsLogRateAnalysisObj from './kbn_aiops_log_rate_analysis.devdocs.json'; diff --git a/api_docs/kbn_alerting_api_integration_helpers.mdx b/api_docs/kbn_alerting_api_integration_helpers.mdx index 7cb5266ffbd28..55bf830ff7842 100644 --- a/api_docs/kbn_alerting_api_integration_helpers.mdx +++ b/api_docs/kbn_alerting_api_integration_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerting-api-integration-helpers title: "@kbn/alerting-api-integration-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerting-api-integration-helpers plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerting-api-integration-helpers'] --- import kbnAlertingApiIntegrationHelpersObj from './kbn_alerting_api_integration_helpers.devdocs.json'; diff --git a/api_docs/kbn_alerting_comparators.mdx b/api_docs/kbn_alerting_comparators.mdx index f77435d287e0b..4accc32a4deb3 100644 --- a/api_docs/kbn_alerting_comparators.mdx +++ b/api_docs/kbn_alerting_comparators.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerting-comparators title: "@kbn/alerting-comparators" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerting-comparators plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerting-comparators'] --- import kbnAlertingComparatorsObj from './kbn_alerting_comparators.devdocs.json'; diff --git a/api_docs/kbn_alerting_state_types.mdx b/api_docs/kbn_alerting_state_types.mdx index 3ef42d652a37f..44f688a7bb5da 100644 --- a/api_docs/kbn_alerting_state_types.mdx +++ b/api_docs/kbn_alerting_state_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerting-state-types title: "@kbn/alerting-state-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerting-state-types plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerting-state-types'] --- import kbnAlertingStateTypesObj from './kbn_alerting_state_types.devdocs.json'; diff --git a/api_docs/kbn_alerting_types.mdx b/api_docs/kbn_alerting_types.mdx index c0e1d8b01353c..e086a27730597 100644 --- a/api_docs/kbn_alerting_types.mdx +++ b/api_docs/kbn_alerting_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerting-types title: "@kbn/alerting-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerting-types plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerting-types'] --- import kbnAlertingTypesObj from './kbn_alerting_types.devdocs.json'; diff --git a/api_docs/kbn_alerts_as_data_utils.mdx b/api_docs/kbn_alerts_as_data_utils.mdx index 62ce8814a97a0..5e51f13103f95 100644 --- a/api_docs/kbn_alerts_as_data_utils.mdx +++ b/api_docs/kbn_alerts_as_data_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerts-as-data-utils title: "@kbn/alerts-as-data-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerts-as-data-utils plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerts-as-data-utils'] --- import kbnAlertsAsDataUtilsObj from './kbn_alerts_as_data_utils.devdocs.json'; diff --git a/api_docs/kbn_alerts_grouping.mdx b/api_docs/kbn_alerts_grouping.mdx index 05777fd3b6f08..2e75a8a1181f0 100644 --- a/api_docs/kbn_alerts_grouping.mdx +++ b/api_docs/kbn_alerts_grouping.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerts-grouping title: "@kbn/alerts-grouping" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerts-grouping plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerts-grouping'] --- import kbnAlertsGroupingObj from './kbn_alerts_grouping.devdocs.json'; diff --git a/api_docs/kbn_alerts_ui_shared.mdx b/api_docs/kbn_alerts_ui_shared.mdx index a93c8cd5865bf..9e573d9868d5b 100644 --- a/api_docs/kbn_alerts_ui_shared.mdx +++ b/api_docs/kbn_alerts_ui_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerts-ui-shared title: "@kbn/alerts-ui-shared" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerts-ui-shared plugin -date: 2024-11-29 +date: 2024-12-03 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 812bb84759958..4920c2b74d82b 100644 --- a/api_docs/kbn_analytics.mdx +++ b/api_docs/kbn_analytics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics title: "@kbn/analytics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics'] --- import kbnAnalyticsObj from './kbn_analytics.devdocs.json'; diff --git a/api_docs/kbn_analytics_collection_utils.mdx b/api_docs/kbn_analytics_collection_utils.mdx index a6f2884c2c572..e31437c87d60f 100644 --- a/api_docs/kbn_analytics_collection_utils.mdx +++ b/api_docs/kbn_analytics_collection_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-collection-utils title: "@kbn/analytics-collection-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-collection-utils plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-collection-utils'] --- import kbnAnalyticsCollectionUtilsObj from './kbn_analytics_collection_utils.devdocs.json'; diff --git a/api_docs/kbn_apm_config_loader.mdx b/api_docs/kbn_apm_config_loader.mdx index 38b36ff195f86..6f3489930119d 100644 --- a/api_docs/kbn_apm_config_loader.mdx +++ b/api_docs/kbn_apm_config_loader.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-config-loader title: "@kbn/apm-config-loader" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-config-loader plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-config-loader'] --- import kbnApmConfigLoaderObj from './kbn_apm_config_loader.devdocs.json'; diff --git a/api_docs/kbn_apm_data_view.mdx b/api_docs/kbn_apm_data_view.mdx index f980a996865a5..11f911917bf01 100644 --- a/api_docs/kbn_apm_data_view.mdx +++ b/api_docs/kbn_apm_data_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-data-view title: "@kbn/apm-data-view" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-data-view plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-data-view'] --- import kbnApmDataViewObj from './kbn_apm_data_view.devdocs.json'; diff --git a/api_docs/kbn_apm_synthtrace.mdx b/api_docs/kbn_apm_synthtrace.mdx index 5398be7b70825..77ca49ee9a36a 100644 --- a/api_docs/kbn_apm_synthtrace.mdx +++ b/api_docs/kbn_apm_synthtrace.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-synthtrace title: "@kbn/apm-synthtrace" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-synthtrace plugin -date: 2024-11-29 +date: 2024-12-03 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 be13ebbffe749..41bd4c9ae2481 100644 --- a/api_docs/kbn_apm_synthtrace_client.mdx +++ b/api_docs/kbn_apm_synthtrace_client.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-synthtrace-client title: "@kbn/apm-synthtrace-client" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-synthtrace-client plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-synthtrace-client'] --- import kbnApmSynthtraceClientObj from './kbn_apm_synthtrace_client.devdocs.json'; diff --git a/api_docs/kbn_apm_types.mdx b/api_docs/kbn_apm_types.mdx index 94f70270c5577..55b6b16418ba0 100644 --- a/api_docs/kbn_apm_types.mdx +++ b/api_docs/kbn_apm_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-types title: "@kbn/apm-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-types plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-types'] --- import kbnApmTypesObj from './kbn_apm_types.devdocs.json'; diff --git a/api_docs/kbn_apm_utils.mdx b/api_docs/kbn_apm_utils.mdx index dd0e269fd435d..4075db91aeeb5 100644 --- a/api_docs/kbn_apm_utils.mdx +++ b/api_docs/kbn_apm_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-utils title: "@kbn/apm-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-utils plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-utils'] --- import kbnApmUtilsObj from './kbn_apm_utils.devdocs.json'; diff --git a/api_docs/kbn_avc_banner.mdx b/api_docs/kbn_avc_banner.mdx index 515616f67664e..b601c38a6b6f2 100644 --- a/api_docs/kbn_avc_banner.mdx +++ b/api_docs/kbn_avc_banner.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-avc-banner title: "@kbn/avc-banner" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/avc-banner plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/avc-banner'] --- import kbnAvcBannerObj from './kbn_avc_banner.devdocs.json'; diff --git a/api_docs/kbn_axe_config.mdx b/api_docs/kbn_axe_config.mdx index 593ce8d0059aa..015b7e6fc4655 100644 --- a/api_docs/kbn_axe_config.mdx +++ b/api_docs/kbn_axe_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-axe-config title: "@kbn/axe-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/axe-config plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/axe-config'] --- import kbnAxeConfigObj from './kbn_axe_config.devdocs.json'; diff --git a/api_docs/kbn_bfetch_error.mdx b/api_docs/kbn_bfetch_error.mdx index 5dce9f97a803a..b1f7af0142da9 100644 --- a/api_docs/kbn_bfetch_error.mdx +++ b/api_docs/kbn_bfetch_error.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-bfetch-error title: "@kbn/bfetch-error" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/bfetch-error plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/bfetch-error'] --- import kbnBfetchErrorObj from './kbn_bfetch_error.devdocs.json'; diff --git a/api_docs/kbn_calculate_auto.mdx b/api_docs/kbn_calculate_auto.mdx index 2ef3b6b42a5b2..9aee2ea98ae3c 100644 --- a/api_docs/kbn_calculate_auto.mdx +++ b/api_docs/kbn_calculate_auto.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-calculate-auto title: "@kbn/calculate-auto" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/calculate-auto plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/calculate-auto'] --- import kbnCalculateAutoObj from './kbn_calculate_auto.devdocs.json'; diff --git a/api_docs/kbn_calculate_width_from_char_count.mdx b/api_docs/kbn_calculate_width_from_char_count.mdx index 78526665dc38a..773c0ec8ab72b 100644 --- a/api_docs/kbn_calculate_width_from_char_count.mdx +++ b/api_docs/kbn_calculate_width_from_char_count.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-calculate-width-from-char-count title: "@kbn/calculate-width-from-char-count" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/calculate-width-from-char-count plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/calculate-width-from-char-count'] --- import kbnCalculateWidthFromCharCountObj from './kbn_calculate_width_from_char_count.devdocs.json'; diff --git a/api_docs/kbn_cases_components.mdx b/api_docs/kbn_cases_components.mdx index 71a727fa95dcf..8b250e1427d25 100644 --- a/api_docs/kbn_cases_components.mdx +++ b/api_docs/kbn_cases_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cases-components title: "@kbn/cases-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cases-components plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cases-components'] --- import kbnCasesComponentsObj from './kbn_cases_components.devdocs.json'; diff --git a/api_docs/kbn_cbor.mdx b/api_docs/kbn_cbor.mdx index 805c846c294f7..f4d4502cdc37b 100644 --- a/api_docs/kbn_cbor.mdx +++ b/api_docs/kbn_cbor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cbor title: "@kbn/cbor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cbor plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cbor'] --- import kbnCborObj from './kbn_cbor.devdocs.json'; diff --git a/api_docs/kbn_cell_actions.mdx b/api_docs/kbn_cell_actions.mdx index 4949d3c62eedb..0e297dede197c 100644 --- a/api_docs/kbn_cell_actions.mdx +++ b/api_docs/kbn_cell_actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cell-actions title: "@kbn/cell-actions" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cell-actions plugin -date: 2024-11-29 +date: 2024-12-03 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 7defc11ab65b3..a5e272dd9b74d 100644 --- a/api_docs/kbn_chart_expressions_common.mdx +++ b/api_docs/kbn_chart_expressions_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-chart-expressions-common title: "@kbn/chart-expressions-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/chart-expressions-common plugin -date: 2024-11-29 +date: 2024-12-03 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 91bfa18883151..8d943b0d72a6a 100644 --- a/api_docs/kbn_chart_icons.mdx +++ b/api_docs/kbn_chart_icons.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-chart-icons title: "@kbn/chart-icons" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/chart-icons plugin -date: 2024-11-29 +date: 2024-12-03 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 a027c16039fb2..41b41e8befbf2 100644 --- a/api_docs/kbn_ci_stats_core.mdx +++ b/api_docs/kbn_ci_stats_core.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-core title: "@kbn/ci-stats-core" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ci-stats-core plugin -date: 2024-11-29 +date: 2024-12-03 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 47dc5b9013c0b..31077f7f51401 100644 --- a/api_docs/kbn_ci_stats_performance_metrics.mdx +++ b/api_docs/kbn_ci_stats_performance_metrics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-performance-metrics title: "@kbn/ci-stats-performance-metrics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ci-stats-performance-metrics plugin -date: 2024-11-29 +date: 2024-12-03 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 354ee15ca495e..043bf8e005c29 100644 --- a/api_docs/kbn_ci_stats_reporter.mdx +++ b/api_docs/kbn_ci_stats_reporter.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-reporter title: "@kbn/ci-stats-reporter" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ci-stats-reporter plugin -date: 2024-11-29 +date: 2024-12-03 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 feedb272256f9..aa15347482fc0 100644 --- a/api_docs/kbn_cli_dev_mode.mdx +++ b/api_docs/kbn_cli_dev_mode.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cli-dev-mode title: "@kbn/cli-dev-mode" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cli-dev-mode plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cli-dev-mode'] --- import kbnCliDevModeObj from './kbn_cli_dev_mode.devdocs.json'; diff --git a/api_docs/kbn_cloud_security_posture.devdocs.json b/api_docs/kbn_cloud_security_posture.devdocs.json index 37cc79e0d28b8..62f5fce1db937 100644 --- a/api_docs/kbn_cloud_security_posture.devdocs.json +++ b/api_docs/kbn_cloud_security_posture.devdocs.json @@ -270,7 +270,7 @@ "label": "getVulnerabilityStats", "description": [], "signature": [ - "(counts: VulnerabilityCounts) => VulnerabilitiesDistributionBarProps[]" + "(counts: VulnerabilityCounts, filterFunction?: ((filter: string) => void) | undefined, currentFilter?: string | undefined) => VulnerabilitiesDistributionBarProps[]" ], "path": "x-pack/packages/kbn-cloud-security-posture/public/src/utils/vulnerability_helpers.ts", "deprecated": false, @@ -290,6 +290,36 @@ "deprecated": false, "trackAdoption": false, "isRequired": true + }, + { + "parentPluginId": "@kbn/cloud-security-posture", + "id": "def-public.getVulnerabilityStats.$2", + "type": "Function", + "tags": [], + "label": "filterFunction", + "description": [], + "signature": [ + "((filter: string) => void) | undefined" + ], + "path": "x-pack/packages/kbn-cloud-security-posture/public/src/utils/vulnerability_helpers.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": false + }, + { + "parentPluginId": "@kbn/cloud-security-posture", + "id": "def-public.getVulnerabilityStats.$3", + "type": "string", + "tags": [], + "label": "currentFilter", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "x-pack/packages/kbn-cloud-security-posture/public/src/utils/vulnerability_helpers.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": false } ], "returnComment": [], @@ -444,9 +474,9 @@ "label": "query", "description": [], "signature": [ - "{ bool: { filter: ", + "{ bool: { filter: (", "QueryDslQueryContainer", - "[]; }; } | undefined" + " | undefined)[] | undefined; }; } | undefined" ], "path": "x-pack/packages/kbn-cloud-security-posture/public/src/types.ts", "deprecated": false, @@ -1042,6 +1072,21 @@ ], "enums": [], "misc": [ + { + "parentPluginId": "@kbn/cloud-security-posture", + "id": "def-public.HOST_NAME", + "type": "string", + "tags": [], + "label": "HOST_NAME", + "description": [], + "signature": [ + "\"host.name\"" + ], + "path": "x-pack/packages/kbn-cloud-security-posture/public/src/constants/component_constants.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "@kbn/cloud-security-posture", "id": "def-public.LatestFindingsRequest", @@ -1120,6 +1165,21 @@ "deprecated": false, "trackAdoption": false, "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/cloud-security-posture", + "id": "def-public.USER_NAME", + "type": "string", + "tags": [], + "label": "USER_NAME", + "description": [], + "signature": [ + "\"user.name\"" + ], + "path": "x-pack/packages/kbn-cloud-security-posture/public/src/constants/component_constants.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false } ], "objects": [ diff --git a/api_docs/kbn_cloud_security_posture.mdx b/api_docs/kbn_cloud_security_posture.mdx index 542c1dbca78b3..9a9ebb3ed96a5 100644 --- a/api_docs/kbn_cloud_security_posture.mdx +++ b/api_docs/kbn_cloud_security_posture.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cloud-security-posture title: "@kbn/cloud-security-posture" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cloud-security-posture plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cloud-security-posture'] --- import kbnCloudSecurityPostureObj from './kbn_cloud_security_posture.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-cloud-security-posture](https://github.com/orgs/elastic | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 89 | 1 | 89 | 0 | +| 93 | 1 | 93 | 0 | ## Client diff --git a/api_docs/kbn_cloud_security_posture_common.devdocs.json b/api_docs/kbn_cloud_security_posture_common.devdocs.json index 6c0ae2a2db8aa..5e993b4e3c1f3 100644 --- a/api_docs/kbn_cloud_security_posture_common.devdocs.json +++ b/api_docs/kbn_cloud_security_posture_common.devdocs.json @@ -129,13 +129,13 @@ "functions": [ { "parentPluginId": "@kbn/cloud-security-posture-common", - "id": "def-common.buildEntityFlyoutPreviewQuery", + "id": "def-common.buildGenericEntityFlyoutPreviewQuery", "type": "Function", "tags": [], - "label": "buildEntityFlyoutPreviewQuery", + "label": "buildGenericEntityFlyoutPreviewQuery", "description": [], "signature": [ - "(field: string, queryValue?: string | undefined) => { bool: { filter: { bool: { should: { term: { [x: string]: string; }; }[]; minimum_should_match: number; }; }[]; }; }" + "(field: string, queryValue?: string | undefined, status?: string | undefined, queryField?: string | undefined) => { bool: { filter: ({ bool: { should: { term: { [x: string]: string; }; }[]; minimum_should_match: number; }; } | undefined)[]; }; }" ], "path": "x-pack/packages/kbn-cloud-security-posture/common/utils/helpers.ts", "deprecated": false, @@ -143,7 +143,7 @@ "children": [ { "parentPluginId": "@kbn/cloud-security-posture-common", - "id": "def-common.buildEntityFlyoutPreviewQuery.$1", + "id": "def-common.buildGenericEntityFlyoutPreviewQuery.$1", "type": "string", "tags": [], "label": "field", @@ -158,7 +158,7 @@ }, { "parentPluginId": "@kbn/cloud-security-posture-common", - "id": "def-common.buildEntityFlyoutPreviewQuery.$2", + "id": "def-common.buildGenericEntityFlyoutPreviewQuery.$2", "type": "string", "tags": [], "label": "queryValue", @@ -170,6 +170,99 @@ "deprecated": false, "trackAdoption": false, "isRequired": false + }, + { + "parentPluginId": "@kbn/cloud-security-posture-common", + "id": "def-common.buildGenericEntityFlyoutPreviewQuery.$3", + "type": "string", + "tags": [], + "label": "status", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "x-pack/packages/kbn-cloud-security-posture/common/utils/helpers.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": false + }, + { + "parentPluginId": "@kbn/cloud-security-posture-common", + "id": "def-common.buildGenericEntityFlyoutPreviewQuery.$4", + "type": "string", + "tags": [], + "label": "queryField", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "x-pack/packages/kbn-cloud-security-posture/common/utils/helpers.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": false + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/cloud-security-posture-common", + "id": "def-common.buildMisconfigurationEntityFlyoutPreviewQuery", + "type": "Function", + "tags": [], + "label": "buildMisconfigurationEntityFlyoutPreviewQuery", + "description": [], + "signature": [ + "(field: string, queryValue?: string | undefined, status?: string | undefined) => { bool: { filter: ({ bool: { should: { term: { [x: string]: string; }; }[]; minimum_should_match: number; }; } | undefined)[]; }; }" + ], + "path": "x-pack/packages/kbn-cloud-security-posture/common/utils/helpers.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/cloud-security-posture-common", + "id": "def-common.buildMisconfigurationEntityFlyoutPreviewQuery.$1", + "type": "string", + "tags": [], + "label": "field", + "description": [], + "signature": [ + "string" + ], + "path": "x-pack/packages/kbn-cloud-security-posture/common/utils/helpers.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/cloud-security-posture-common", + "id": "def-common.buildMisconfigurationEntityFlyoutPreviewQuery.$2", + "type": "string", + "tags": [], + "label": "queryValue", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "x-pack/packages/kbn-cloud-security-posture/common/utils/helpers.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": false + }, + { + "parentPluginId": "@kbn/cloud-security-posture-common", + "id": "def-common.buildMisconfigurationEntityFlyoutPreviewQuery.$3", + "type": "string", + "tags": [], + "label": "status", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "x-pack/packages/kbn-cloud-security-posture/common/utils/helpers.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": false } ], "returnComment": [], @@ -210,6 +303,69 @@ "returnComment": [], "initialIsOpen": false }, + { + "parentPluginId": "@kbn/cloud-security-posture-common", + "id": "def-common.buildVulnerabilityEntityFlyoutPreviewQuery", + "type": "Function", + "tags": [], + "label": "buildVulnerabilityEntityFlyoutPreviewQuery", + "description": [], + "signature": [ + "(field: string, queryValue?: string | undefined, status?: string | undefined) => { bool: { filter: ({ bool: { should: { term: { [x: string]: string; }; }[]; minimum_should_match: number; }; } | undefined)[]; }; }" + ], + "path": "x-pack/packages/kbn-cloud-security-posture/common/utils/helpers.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/cloud-security-posture-common", + "id": "def-common.buildVulnerabilityEntityFlyoutPreviewQuery.$1", + "type": "string", + "tags": [], + "label": "field", + "description": [], + "signature": [ + "string" + ], + "path": "x-pack/packages/kbn-cloud-security-posture/common/utils/helpers.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/cloud-security-posture-common", + "id": "def-common.buildVulnerabilityEntityFlyoutPreviewQuery.$2", + "type": "string", + "tags": [], + "label": "queryValue", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "x-pack/packages/kbn-cloud-security-posture/common/utils/helpers.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": false + }, + { + "parentPluginId": "@kbn/cloud-security-posture-common", + "id": "def-common.buildVulnerabilityEntityFlyoutPreviewQuery.$3", + "type": "string", + "tags": [], + "label": "status", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "x-pack/packages/kbn-cloud-security-posture/common/utils/helpers.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": false + } + ], + "returnComment": [], + "initialIsOpen": false + }, { "parentPluginId": "@kbn/cloud-security-posture-common", "id": "def-common.extractErrorMessage", @@ -1556,6 +1712,42 @@ } ], "objects": [ + { + "parentPluginId": "@kbn/cloud-security-posture-common", + "id": "def-common.MISCONFIGURATION_STATUS", + "type": "Object", + "tags": [], + "label": "MISCONFIGURATION_STATUS", + "description": [], + "path": "x-pack/packages/kbn-cloud-security-posture/common/constants.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/cloud-security-posture-common", + "id": "def-common.MISCONFIGURATION_STATUS.PASSED", + "type": "string", + "tags": [], + "label": "PASSED", + "description": [], + "path": "x-pack/packages/kbn-cloud-security-posture/common/constants.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/cloud-security-posture-common", + "id": "def-common.MISCONFIGURATION_STATUS.FAILED", + "type": "string", + "tags": [], + "label": "FAILED", + "description": [], + "path": "x-pack/packages/kbn-cloud-security-posture/common/constants.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, { "parentPluginId": "@kbn/cloud-security-posture-common", "id": "def-common.VULNERABILITIES_SEVERITY", diff --git a/api_docs/kbn_cloud_security_posture_common.mdx b/api_docs/kbn_cloud_security_posture_common.mdx index bfde5286edc6b..0c9d0ce05e98f 100644 --- a/api_docs/kbn_cloud_security_posture_common.mdx +++ b/api_docs/kbn_cloud_security_posture_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cloud-security-posture-common title: "@kbn/cloud-security-posture-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cloud-security-posture-common plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cloud-security-posture-common'] --- import kbnCloudSecurityPostureCommonObj from './kbn_cloud_security_posture_common.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-cloud-security-posture](https://github.com/orgs/elastic | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 109 | 0 | 107 | 1 | +| 122 | 0 | 120 | 1 | ## Common diff --git a/api_docs/kbn_cloud_security_posture_graph.mdx b/api_docs/kbn_cloud_security_posture_graph.mdx index a01f5c58af883..5bdb2f2922367 100644 --- a/api_docs/kbn_cloud_security_posture_graph.mdx +++ b/api_docs/kbn_cloud_security_posture_graph.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cloud-security-posture-graph title: "@kbn/cloud-security-posture-graph" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cloud-security-posture-graph plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cloud-security-posture-graph'] --- import kbnCloudSecurityPostureGraphObj from './kbn_cloud_security_posture_graph.devdocs.json'; diff --git a/api_docs/kbn_code_editor.mdx b/api_docs/kbn_code_editor.mdx index 6a95eb61edb64..5f2d76f06ed33 100644 --- a/api_docs/kbn_code_editor.mdx +++ b/api_docs/kbn_code_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-code-editor title: "@kbn/code-editor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/code-editor plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/code-editor'] --- import kbnCodeEditorObj from './kbn_code_editor.devdocs.json'; diff --git a/api_docs/kbn_code_editor_mock.mdx b/api_docs/kbn_code_editor_mock.mdx index 909ad7427930d..4dfe3de38b27e 100644 --- a/api_docs/kbn_code_editor_mock.mdx +++ b/api_docs/kbn_code_editor_mock.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-code-editor-mock title: "@kbn/code-editor-mock" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/code-editor-mock plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/code-editor-mock'] --- import kbnCodeEditorMockObj from './kbn_code_editor_mock.devdocs.json'; diff --git a/api_docs/kbn_code_owners.mdx b/api_docs/kbn_code_owners.mdx index 6e7260352d886..77f579431d482 100644 --- a/api_docs/kbn_code_owners.mdx +++ b/api_docs/kbn_code_owners.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-code-owners title: "@kbn/code-owners" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/code-owners plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/code-owners'] --- import kbnCodeOwnersObj from './kbn_code_owners.devdocs.json'; diff --git a/api_docs/kbn_coloring.mdx b/api_docs/kbn_coloring.mdx index 6fe32a7a09690..040e0b7ca3ef8 100644 --- a/api_docs/kbn_coloring.mdx +++ b/api_docs/kbn_coloring.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-coloring title: "@kbn/coloring" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/coloring plugin -date: 2024-11-29 +date: 2024-12-03 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 3c1f76976d045..34eb1c16afdf9 100644 --- a/api_docs/kbn_config.mdx +++ b/api_docs/kbn_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-config title: "@kbn/config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/config plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/config'] --- import kbnConfigObj from './kbn_config.devdocs.json'; diff --git a/api_docs/kbn_config_mocks.mdx b/api_docs/kbn_config_mocks.mdx index a8a2f14e1c53e..afdf13e4fd5b1 100644 --- a/api_docs/kbn_config_mocks.mdx +++ b/api_docs/kbn_config_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-config-mocks title: "@kbn/config-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/config-mocks plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/config-mocks'] --- import kbnConfigMocksObj from './kbn_config_mocks.devdocs.json'; diff --git a/api_docs/kbn_config_schema.mdx b/api_docs/kbn_config_schema.mdx index db7abd1e2d173..b7f38ac879ff8 100644 --- a/api_docs/kbn_config_schema.mdx +++ b/api_docs/kbn_config_schema.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-config-schema title: "@kbn/config-schema" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/config-schema plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/config-schema'] --- import kbnConfigSchemaObj from './kbn_config_schema.devdocs.json'; diff --git a/api_docs/kbn_content_management_content_editor.mdx b/api_docs/kbn_content_management_content_editor.mdx index 12fd35a6fea4b..7cc97347d0956 100644 --- a/api_docs/kbn_content_management_content_editor.mdx +++ b/api_docs/kbn_content_management_content_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-content-editor title: "@kbn/content-management-content-editor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-content-editor plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-content-editor'] --- import kbnContentManagementContentEditorObj from './kbn_content_management_content_editor.devdocs.json'; diff --git a/api_docs/kbn_content_management_content_insights_public.mdx b/api_docs/kbn_content_management_content_insights_public.mdx index d7dec1f860545..1c4b45969fae3 100644 --- a/api_docs/kbn_content_management_content_insights_public.mdx +++ b/api_docs/kbn_content_management_content_insights_public.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-content-insights-public title: "@kbn/content-management-content-insights-public" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-content-insights-public plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-content-insights-public'] --- import kbnContentManagementContentInsightsPublicObj from './kbn_content_management_content_insights_public.devdocs.json'; diff --git a/api_docs/kbn_content_management_content_insights_server.mdx b/api_docs/kbn_content_management_content_insights_server.mdx index 664f5c143d272..314fa216d2a1c 100644 --- a/api_docs/kbn_content_management_content_insights_server.mdx +++ b/api_docs/kbn_content_management_content_insights_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-content-insights-server title: "@kbn/content-management-content-insights-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-content-insights-server plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-content-insights-server'] --- import kbnContentManagementContentInsightsServerObj from './kbn_content_management_content_insights_server.devdocs.json'; diff --git a/api_docs/kbn_content_management_favorites_common.mdx b/api_docs/kbn_content_management_favorites_common.mdx index a8c857e6aee8f..0d3aa9f0fb62a 100644 --- a/api_docs/kbn_content_management_favorites_common.mdx +++ b/api_docs/kbn_content_management_favorites_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-favorites-common title: "@kbn/content-management-favorites-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-favorites-common plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-favorites-common'] --- import kbnContentManagementFavoritesCommonObj from './kbn_content_management_favorites_common.devdocs.json'; diff --git a/api_docs/kbn_content_management_favorites_public.mdx b/api_docs/kbn_content_management_favorites_public.mdx index 23f9ef645c9de..7e40607b21faa 100644 --- a/api_docs/kbn_content_management_favorites_public.mdx +++ b/api_docs/kbn_content_management_favorites_public.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-favorites-public title: "@kbn/content-management-favorites-public" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-favorites-public plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-favorites-public'] --- import kbnContentManagementFavoritesPublicObj from './kbn_content_management_favorites_public.devdocs.json'; diff --git a/api_docs/kbn_content_management_favorites_server.mdx b/api_docs/kbn_content_management_favorites_server.mdx index 8d766eb9a64a8..052d931d97f90 100644 --- a/api_docs/kbn_content_management_favorites_server.mdx +++ b/api_docs/kbn_content_management_favorites_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-favorites-server title: "@kbn/content-management-favorites-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-favorites-server plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-favorites-server'] --- import kbnContentManagementFavoritesServerObj from './kbn_content_management_favorites_server.devdocs.json'; diff --git a/api_docs/kbn_content_management_tabbed_table_list_view.mdx b/api_docs/kbn_content_management_tabbed_table_list_view.mdx index 7446365b66543..95a87f1b9637e 100644 --- a/api_docs/kbn_content_management_tabbed_table_list_view.mdx +++ b/api_docs/kbn_content_management_tabbed_table_list_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-tabbed-table-list-view title: "@kbn/content-management-tabbed-table-list-view" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-tabbed-table-list-view plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-tabbed-table-list-view'] --- import kbnContentManagementTabbedTableListViewObj from './kbn_content_management_tabbed_table_list_view.devdocs.json'; diff --git a/api_docs/kbn_content_management_table_list_view.mdx b/api_docs/kbn_content_management_table_list_view.mdx index b9a02339cbec1..ade0488c06679 100644 --- a/api_docs/kbn_content_management_table_list_view.mdx +++ b/api_docs/kbn_content_management_table_list_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-table-list-view title: "@kbn/content-management-table-list-view" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-table-list-view plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-table-list-view'] --- import kbnContentManagementTableListViewObj from './kbn_content_management_table_list_view.devdocs.json'; diff --git a/api_docs/kbn_content_management_table_list_view_common.mdx b/api_docs/kbn_content_management_table_list_view_common.mdx index 23c48d7e3ccac..824bf9224c814 100644 --- a/api_docs/kbn_content_management_table_list_view_common.mdx +++ b/api_docs/kbn_content_management_table_list_view_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-table-list-view-common title: "@kbn/content-management-table-list-view-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-table-list-view-common plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-table-list-view-common'] --- import kbnContentManagementTableListViewCommonObj from './kbn_content_management_table_list_view_common.devdocs.json'; diff --git a/api_docs/kbn_content_management_table_list_view_table.mdx b/api_docs/kbn_content_management_table_list_view_table.mdx index edf73e10cea5c..25ecb50b36872 100644 --- a/api_docs/kbn_content_management_table_list_view_table.mdx +++ b/api_docs/kbn_content_management_table_list_view_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-table-list-view-table title: "@kbn/content-management-table-list-view-table" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-table-list-view-table plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-table-list-view-table'] --- import kbnContentManagementTableListViewTableObj from './kbn_content_management_table_list_view_table.devdocs.json'; diff --git a/api_docs/kbn_content_management_user_profiles.mdx b/api_docs/kbn_content_management_user_profiles.mdx index 8291bfab17b60..f1aaaeba258f8 100644 --- a/api_docs/kbn_content_management_user_profiles.mdx +++ b/api_docs/kbn_content_management_user_profiles.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-user-profiles title: "@kbn/content-management-user-profiles" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-user-profiles plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-user-profiles'] --- import kbnContentManagementUserProfilesObj from './kbn_content_management_user_profiles.devdocs.json'; diff --git a/api_docs/kbn_content_management_utils.mdx b/api_docs/kbn_content_management_utils.mdx index bc250ebe3048c..658e6502f3e51 100644 --- a/api_docs/kbn_content_management_utils.mdx +++ b/api_docs/kbn_content_management_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-utils title: "@kbn/content-management-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-utils plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-utils'] --- import kbnContentManagementUtilsObj from './kbn_content_management_utils.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_browser.devdocs.json b/api_docs/kbn_core_analytics_browser.devdocs.json index 2f2c5fc3f3d9f..d9e9918f342d9 100644 --- a/api_docs/kbn_core_analytics_browser.devdocs.json +++ b/api_docs/kbn_core_analytics_browser.devdocs.json @@ -942,6 +942,10 @@ "plugin": "inventory", "path": "x-pack/plugins/observability_solution/inventory/public/services/telemetry/telemetry_client.ts" }, + { + "plugin": "inventory", + "path": "x-pack/plugins/observability_solution/inventory/public/services/telemetry/telemetry_client.ts" + }, { "plugin": "observabilityLogsExplorer", "path": "x-pack/plugins/observability_solution/observability_logs_explorer/public/state_machines/observability_logs_explorer/src/telemetry_events.ts" @@ -1398,6 +1402,14 @@ "plugin": "inventory", "path": "x-pack/plugins/observability_solution/inventory/public/services/telemetry/telemetry_service.test.ts" }, + { + "plugin": "inventory", + "path": "x-pack/plugins/observability_solution/inventory/public/services/telemetry/telemetry_service.test.ts" + }, + { + "plugin": "inventory", + "path": "x-pack/plugins/observability_solution/inventory/public/services/telemetry/telemetry_service.test.ts" + }, { "plugin": "securitySolution", "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_service.test.ts" diff --git a/api_docs/kbn_core_analytics_browser.mdx b/api_docs/kbn_core_analytics_browser.mdx index 07b4693c38be0..bb1cb25cb2211 100644 --- a/api_docs/kbn_core_analytics_browser.mdx +++ b/api_docs/kbn_core_analytics_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser title: "@kbn/core-analytics-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-browser plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-browser'] --- import kbnCoreAnalyticsBrowserObj from './kbn_core_analytics_browser.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_browser_internal.mdx b/api_docs/kbn_core_analytics_browser_internal.mdx index 4c5daa0064189..1b61f04d13f19 100644 --- a/api_docs/kbn_core_analytics_browser_internal.mdx +++ b/api_docs/kbn_core_analytics_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser-internal title: "@kbn/core-analytics-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-browser-internal plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-browser-internal'] --- import kbnCoreAnalyticsBrowserInternalObj from './kbn_core_analytics_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_browser_mocks.mdx b/api_docs/kbn_core_analytics_browser_mocks.mdx index 6641aeb5f72dd..bdc4764b131bd 100644 --- a/api_docs/kbn_core_analytics_browser_mocks.mdx +++ b/api_docs/kbn_core_analytics_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser-mocks title: "@kbn/core-analytics-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-browser-mocks plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-browser-mocks'] --- import kbnCoreAnalyticsBrowserMocksObj from './kbn_core_analytics_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_server.devdocs.json b/api_docs/kbn_core_analytics_server.devdocs.json index fe50bcb0679dd..f551b259301d1 100644 --- a/api_docs/kbn_core_analytics_server.devdocs.json +++ b/api_docs/kbn_core_analytics_server.devdocs.json @@ -950,6 +950,10 @@ "plugin": "inventory", "path": "x-pack/plugins/observability_solution/inventory/public/services/telemetry/telemetry_client.ts" }, + { + "plugin": "inventory", + "path": "x-pack/plugins/observability_solution/inventory/public/services/telemetry/telemetry_client.ts" + }, { "plugin": "observabilityLogsExplorer", "path": "x-pack/plugins/observability_solution/observability_logs_explorer/public/state_machines/observability_logs_explorer/src/telemetry_events.ts" @@ -1406,6 +1410,14 @@ "plugin": "inventory", "path": "x-pack/plugins/observability_solution/inventory/public/services/telemetry/telemetry_service.test.ts" }, + { + "plugin": "inventory", + "path": "x-pack/plugins/observability_solution/inventory/public/services/telemetry/telemetry_service.test.ts" + }, + { + "plugin": "inventory", + "path": "x-pack/plugins/observability_solution/inventory/public/services/telemetry/telemetry_service.test.ts" + }, { "plugin": "securitySolution", "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_service.test.ts" diff --git a/api_docs/kbn_core_analytics_server.mdx b/api_docs/kbn_core_analytics_server.mdx index 7f5fd713e15bc..6e3572328aa38 100644 --- a/api_docs/kbn_core_analytics_server.mdx +++ b/api_docs/kbn_core_analytics_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server title: "@kbn/core-analytics-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-server plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-server'] --- import kbnCoreAnalyticsServerObj from './kbn_core_analytics_server.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_server_internal.mdx b/api_docs/kbn_core_analytics_server_internal.mdx index 745590947e4f7..55c716c5195cf 100644 --- a/api_docs/kbn_core_analytics_server_internal.mdx +++ b/api_docs/kbn_core_analytics_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server-internal title: "@kbn/core-analytics-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-server-internal plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-server-internal'] --- import kbnCoreAnalyticsServerInternalObj from './kbn_core_analytics_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_server_mocks.mdx b/api_docs/kbn_core_analytics_server_mocks.mdx index 71ed4b601c9bc..1dc3b7ced43b1 100644 --- a/api_docs/kbn_core_analytics_server_mocks.mdx +++ b/api_docs/kbn_core_analytics_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server-mocks title: "@kbn/core-analytics-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-server-mocks plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-server-mocks'] --- import kbnCoreAnalyticsServerMocksObj from './kbn_core_analytics_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_application_browser.mdx b/api_docs/kbn_core_application_browser.mdx index 4f2c9cb0a9f97..385b70eab1822 100644 --- a/api_docs/kbn_core_application_browser.mdx +++ b/api_docs/kbn_core_application_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-browser title: "@kbn/core-application-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-browser plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-application-browser'] --- import kbnCoreApplicationBrowserObj from './kbn_core_application_browser.devdocs.json'; diff --git a/api_docs/kbn_core_application_browser_internal.mdx b/api_docs/kbn_core_application_browser_internal.mdx index 58030a04f751e..c93e1d6b36b2d 100644 --- a/api_docs/kbn_core_application_browser_internal.mdx +++ b/api_docs/kbn_core_application_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-browser-internal title: "@kbn/core-application-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-browser-internal plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-application-browser-internal'] --- import kbnCoreApplicationBrowserInternalObj from './kbn_core_application_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_application_browser_mocks.mdx b/api_docs/kbn_core_application_browser_mocks.mdx index 836aa31f35067..d2eee2647ac04 100644 --- a/api_docs/kbn_core_application_browser_mocks.mdx +++ b/api_docs/kbn_core_application_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-browser-mocks title: "@kbn/core-application-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-browser-mocks plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-application-browser-mocks'] --- import kbnCoreApplicationBrowserMocksObj from './kbn_core_application_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_application_common.mdx b/api_docs/kbn_core_application_common.mdx index a9b745604a316..15b69d35fb423 100644 --- a/api_docs/kbn_core_application_common.mdx +++ b/api_docs/kbn_core_application_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-common title: "@kbn/core-application-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-common plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-application-common'] --- import kbnCoreApplicationCommonObj from './kbn_core_application_common.devdocs.json'; diff --git a/api_docs/kbn_core_apps_browser_internal.mdx b/api_docs/kbn_core_apps_browser_internal.mdx index 6645730e93c39..f4a263b702009 100644 --- a/api_docs/kbn_core_apps_browser_internal.mdx +++ b/api_docs/kbn_core_apps_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-apps-browser-internal title: "@kbn/core-apps-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-apps-browser-internal plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-apps-browser-internal'] --- import kbnCoreAppsBrowserInternalObj from './kbn_core_apps_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_apps_browser_mocks.mdx b/api_docs/kbn_core_apps_browser_mocks.mdx index af92e2508f726..d11bf0ef25541 100644 --- a/api_docs/kbn_core_apps_browser_mocks.mdx +++ b/api_docs/kbn_core_apps_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-apps-browser-mocks title: "@kbn/core-apps-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-apps-browser-mocks plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-apps-browser-mocks'] --- import kbnCoreAppsBrowserMocksObj from './kbn_core_apps_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_apps_server_internal.mdx b/api_docs/kbn_core_apps_server_internal.mdx index 0d1aabf531c18..9e6309e566ad9 100644 --- a/api_docs/kbn_core_apps_server_internal.mdx +++ b/api_docs/kbn_core_apps_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-apps-server-internal title: "@kbn/core-apps-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-apps-server-internal plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-apps-server-internal'] --- import kbnCoreAppsServerInternalObj from './kbn_core_apps_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_base_browser_mocks.mdx b/api_docs/kbn_core_base_browser_mocks.mdx index 1a6a20971dfa9..e70df86ee3ed8 100644 --- a/api_docs/kbn_core_base_browser_mocks.mdx +++ b/api_docs/kbn_core_base_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-browser-mocks title: "@kbn/core-base-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-browser-mocks plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-browser-mocks'] --- import kbnCoreBaseBrowserMocksObj from './kbn_core_base_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_base_common.mdx b/api_docs/kbn_core_base_common.mdx index b1179216c27ee..f4e6af94f0376 100644 --- a/api_docs/kbn_core_base_common.mdx +++ b/api_docs/kbn_core_base_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-common title: "@kbn/core-base-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-common plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-common'] --- import kbnCoreBaseCommonObj from './kbn_core_base_common.devdocs.json'; diff --git a/api_docs/kbn_core_base_server_internal.mdx b/api_docs/kbn_core_base_server_internal.mdx index 81028158e5b45..59b22026793ac 100644 --- a/api_docs/kbn_core_base_server_internal.mdx +++ b/api_docs/kbn_core_base_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-server-internal title: "@kbn/core-base-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-server-internal plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-server-internal'] --- import kbnCoreBaseServerInternalObj from './kbn_core_base_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_base_server_mocks.mdx b/api_docs/kbn_core_base_server_mocks.mdx index 264bf3c98c17c..227ed73b3c168 100644 --- a/api_docs/kbn_core_base_server_mocks.mdx +++ b/api_docs/kbn_core_base_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-server-mocks title: "@kbn/core-base-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-server-mocks plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-server-mocks'] --- import kbnCoreBaseServerMocksObj from './kbn_core_base_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_capabilities_browser_mocks.mdx b/api_docs/kbn_core_capabilities_browser_mocks.mdx index bc2e1b08f9b50..ff91510acfaf3 100644 --- a/api_docs/kbn_core_capabilities_browser_mocks.mdx +++ b/api_docs/kbn_core_capabilities_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-browser-mocks title: "@kbn/core-capabilities-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-browser-mocks plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-browser-mocks'] --- import kbnCoreCapabilitiesBrowserMocksObj from './kbn_core_capabilities_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_capabilities_common.mdx b/api_docs/kbn_core_capabilities_common.mdx index 344a35ae577d4..6658412504cf0 100644 --- a/api_docs/kbn_core_capabilities_common.mdx +++ b/api_docs/kbn_core_capabilities_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-common title: "@kbn/core-capabilities-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-common plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-common'] --- import kbnCoreCapabilitiesCommonObj from './kbn_core_capabilities_common.devdocs.json'; diff --git a/api_docs/kbn_core_capabilities_server.mdx b/api_docs/kbn_core_capabilities_server.mdx index cecb40b2c34c9..6f6f9b67f4714 100644 --- a/api_docs/kbn_core_capabilities_server.mdx +++ b/api_docs/kbn_core_capabilities_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-server title: "@kbn/core-capabilities-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-server plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-server'] --- import kbnCoreCapabilitiesServerObj from './kbn_core_capabilities_server.devdocs.json'; diff --git a/api_docs/kbn_core_capabilities_server_mocks.mdx b/api_docs/kbn_core_capabilities_server_mocks.mdx index 0f456d148cc73..a0c45fad5a714 100644 --- a/api_docs/kbn_core_capabilities_server_mocks.mdx +++ b/api_docs/kbn_core_capabilities_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-server-mocks title: "@kbn/core-capabilities-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-server-mocks plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-server-mocks'] --- import kbnCoreCapabilitiesServerMocksObj from './kbn_core_capabilities_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_chrome_browser.mdx b/api_docs/kbn_core_chrome_browser.mdx index 80490d9af3247..ae8118d69b160 100644 --- a/api_docs/kbn_core_chrome_browser.mdx +++ b/api_docs/kbn_core_chrome_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-chrome-browser title: "@kbn/core-chrome-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-chrome-browser plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-chrome-browser'] --- import kbnCoreChromeBrowserObj from './kbn_core_chrome_browser.devdocs.json'; diff --git a/api_docs/kbn_core_chrome_browser_mocks.mdx b/api_docs/kbn_core_chrome_browser_mocks.mdx index 77375e0afc90c..4d87b9bf64a04 100644 --- a/api_docs/kbn_core_chrome_browser_mocks.mdx +++ b/api_docs/kbn_core_chrome_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-chrome-browser-mocks title: "@kbn/core-chrome-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-chrome-browser-mocks plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-chrome-browser-mocks'] --- import kbnCoreChromeBrowserMocksObj from './kbn_core_chrome_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_config_server_internal.mdx b/api_docs/kbn_core_config_server_internal.mdx index 125ace356257a..19132ba78af5c 100644 --- a/api_docs/kbn_core_config_server_internal.mdx +++ b/api_docs/kbn_core_config_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-config-server-internal title: "@kbn/core-config-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-config-server-internal plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-config-server-internal'] --- import kbnCoreConfigServerInternalObj from './kbn_core_config_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_browser.mdx b/api_docs/kbn_core_custom_branding_browser.mdx index a263c55ae18f2..3e877454b83cd 100644 --- a/api_docs/kbn_core_custom_branding_browser.mdx +++ b/api_docs/kbn_core_custom_branding_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-browser title: "@kbn/core-custom-branding-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-browser plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-browser'] --- import kbnCoreCustomBrandingBrowserObj from './kbn_core_custom_branding_browser.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_browser_internal.mdx b/api_docs/kbn_core_custom_branding_browser_internal.mdx index 1c8bba339550e..bd98ce434b956 100644 --- a/api_docs/kbn_core_custom_branding_browser_internal.mdx +++ b/api_docs/kbn_core_custom_branding_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-browser-internal title: "@kbn/core-custom-branding-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-browser-internal plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-browser-internal'] --- import kbnCoreCustomBrandingBrowserInternalObj from './kbn_core_custom_branding_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_browser_mocks.mdx b/api_docs/kbn_core_custom_branding_browser_mocks.mdx index feaed5863e23c..6c9eff9988d3c 100644 --- a/api_docs/kbn_core_custom_branding_browser_mocks.mdx +++ b/api_docs/kbn_core_custom_branding_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-browser-mocks title: "@kbn/core-custom-branding-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-browser-mocks plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-browser-mocks'] --- import kbnCoreCustomBrandingBrowserMocksObj from './kbn_core_custom_branding_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_common.mdx b/api_docs/kbn_core_custom_branding_common.mdx index 42cd47b756929..68beb9c6ae3d5 100644 --- a/api_docs/kbn_core_custom_branding_common.mdx +++ b/api_docs/kbn_core_custom_branding_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-common title: "@kbn/core-custom-branding-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-common plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-common'] --- import kbnCoreCustomBrandingCommonObj from './kbn_core_custom_branding_common.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_server.mdx b/api_docs/kbn_core_custom_branding_server.mdx index cf5723b78e352..372cdd0b4ec53 100644 --- a/api_docs/kbn_core_custom_branding_server.mdx +++ b/api_docs/kbn_core_custom_branding_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-server title: "@kbn/core-custom-branding-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-server plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-server'] --- import kbnCoreCustomBrandingServerObj from './kbn_core_custom_branding_server.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_server_internal.mdx b/api_docs/kbn_core_custom_branding_server_internal.mdx index 2ec8eb9217a03..7942915dc5971 100644 --- a/api_docs/kbn_core_custom_branding_server_internal.mdx +++ b/api_docs/kbn_core_custom_branding_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-server-internal title: "@kbn/core-custom-branding-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-server-internal plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-server-internal'] --- import kbnCoreCustomBrandingServerInternalObj from './kbn_core_custom_branding_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_server_mocks.mdx b/api_docs/kbn_core_custom_branding_server_mocks.mdx index 984717dd56b8d..c259b64cbf3fe 100644 --- a/api_docs/kbn_core_custom_branding_server_mocks.mdx +++ b/api_docs/kbn_core_custom_branding_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-server-mocks title: "@kbn/core-custom-branding-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-server-mocks plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-server-mocks'] --- import kbnCoreCustomBrandingServerMocksObj from './kbn_core_custom_branding_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_browser.mdx b/api_docs/kbn_core_deprecations_browser.mdx index 4d086432714da..90fe4f7840ccd 100644 --- a/api_docs/kbn_core_deprecations_browser.mdx +++ b/api_docs/kbn_core_deprecations_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-browser title: "@kbn/core-deprecations-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-browser plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-browser'] --- import kbnCoreDeprecationsBrowserObj from './kbn_core_deprecations_browser.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_browser_internal.mdx b/api_docs/kbn_core_deprecations_browser_internal.mdx index fb3eb118457bb..60fbb36154474 100644 --- a/api_docs/kbn_core_deprecations_browser_internal.mdx +++ b/api_docs/kbn_core_deprecations_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-browser-internal title: "@kbn/core-deprecations-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-browser-internal plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-browser-internal'] --- import kbnCoreDeprecationsBrowserInternalObj from './kbn_core_deprecations_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_browser_mocks.mdx b/api_docs/kbn_core_deprecations_browser_mocks.mdx index 3ba5965026867..e3a4f3069d9d0 100644 --- a/api_docs/kbn_core_deprecations_browser_mocks.mdx +++ b/api_docs/kbn_core_deprecations_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-browser-mocks title: "@kbn/core-deprecations-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-browser-mocks plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-browser-mocks'] --- import kbnCoreDeprecationsBrowserMocksObj from './kbn_core_deprecations_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_common.mdx b/api_docs/kbn_core_deprecations_common.mdx index 632ae7d2485bb..175356815a82f 100644 --- a/api_docs/kbn_core_deprecations_common.mdx +++ b/api_docs/kbn_core_deprecations_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-common title: "@kbn/core-deprecations-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-common plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-common'] --- import kbnCoreDeprecationsCommonObj from './kbn_core_deprecations_common.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_server.mdx b/api_docs/kbn_core_deprecations_server.mdx index 5d1323645287e..b2daa0f917604 100644 --- a/api_docs/kbn_core_deprecations_server.mdx +++ b/api_docs/kbn_core_deprecations_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-server title: "@kbn/core-deprecations-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-server plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-server'] --- import kbnCoreDeprecationsServerObj from './kbn_core_deprecations_server.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_server_internal.mdx b/api_docs/kbn_core_deprecations_server_internal.mdx index 93bb673d1c9b3..bd55fd32f8990 100644 --- a/api_docs/kbn_core_deprecations_server_internal.mdx +++ b/api_docs/kbn_core_deprecations_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-server-internal title: "@kbn/core-deprecations-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-server-internal plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-server-internal'] --- import kbnCoreDeprecationsServerInternalObj from './kbn_core_deprecations_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_server_mocks.mdx b/api_docs/kbn_core_deprecations_server_mocks.mdx index 2b7a499ed8ba1..cfb99447d5ff4 100644 --- a/api_docs/kbn_core_deprecations_server_mocks.mdx +++ b/api_docs/kbn_core_deprecations_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-server-mocks title: "@kbn/core-deprecations-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-server-mocks plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-server-mocks'] --- import kbnCoreDeprecationsServerMocksObj from './kbn_core_deprecations_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_doc_links_browser.mdx b/api_docs/kbn_core_doc_links_browser.mdx index 8900940502bd0..fa541c8101c46 100644 --- a/api_docs/kbn_core_doc_links_browser.mdx +++ b/api_docs/kbn_core_doc_links_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-browser title: "@kbn/core-doc-links-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-browser plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-browser'] --- import kbnCoreDocLinksBrowserObj from './kbn_core_doc_links_browser.devdocs.json'; diff --git a/api_docs/kbn_core_doc_links_browser_mocks.mdx b/api_docs/kbn_core_doc_links_browser_mocks.mdx index dab4dd94db454..6abfb4f6ef16c 100644 --- a/api_docs/kbn_core_doc_links_browser_mocks.mdx +++ b/api_docs/kbn_core_doc_links_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-browser-mocks title: "@kbn/core-doc-links-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-browser-mocks plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-browser-mocks'] --- import kbnCoreDocLinksBrowserMocksObj from './kbn_core_doc_links_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_doc_links_server.mdx b/api_docs/kbn_core_doc_links_server.mdx index f0c93c7b83acc..b8f98e965cf07 100644 --- a/api_docs/kbn_core_doc_links_server.mdx +++ b/api_docs/kbn_core_doc_links_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-server title: "@kbn/core-doc-links-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-server plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-server'] --- import kbnCoreDocLinksServerObj from './kbn_core_doc_links_server.devdocs.json'; diff --git a/api_docs/kbn_core_doc_links_server_mocks.mdx b/api_docs/kbn_core_doc_links_server_mocks.mdx index c4bc30eeee34c..2a9917b2c125c 100644 --- a/api_docs/kbn_core_doc_links_server_mocks.mdx +++ b/api_docs/kbn_core_doc_links_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-server-mocks title: "@kbn/core-doc-links-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-server-mocks plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-server-mocks'] --- import kbnCoreDocLinksServerMocksObj from './kbn_core_doc_links_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_client_server_internal.mdx b/api_docs/kbn_core_elasticsearch_client_server_internal.mdx index f3002aad50e09..dd669241d943d 100644 --- a/api_docs/kbn_core_elasticsearch_client_server_internal.mdx +++ b/api_docs/kbn_core_elasticsearch_client_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-client-server-internal title: "@kbn/core-elasticsearch-client-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-client-server-internal plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-client-server-internal'] --- import kbnCoreElasticsearchClientServerInternalObj from './kbn_core_elasticsearch_client_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx b/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx index f2172c4e0ca6a..c9f33864366fc 100644 --- a/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx +++ b/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-client-server-mocks title: "@kbn/core-elasticsearch-client-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-client-server-mocks plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-client-server-mocks'] --- import kbnCoreElasticsearchClientServerMocksObj from './kbn_core_elasticsearch_client_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_server.mdx b/api_docs/kbn_core_elasticsearch_server.mdx index 0d0642dc211aa..2a2f8f06c4a20 100644 --- a/api_docs/kbn_core_elasticsearch_server.mdx +++ b/api_docs/kbn_core_elasticsearch_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server title: "@kbn/core-elasticsearch-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-server plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-server'] --- import kbnCoreElasticsearchServerObj from './kbn_core_elasticsearch_server.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_server_internal.mdx b/api_docs/kbn_core_elasticsearch_server_internal.mdx index 0657f2f3e523c..8893dc1cb951f 100644 --- a/api_docs/kbn_core_elasticsearch_server_internal.mdx +++ b/api_docs/kbn_core_elasticsearch_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server-internal title: "@kbn/core-elasticsearch-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-server-internal plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-server-internal'] --- import kbnCoreElasticsearchServerInternalObj from './kbn_core_elasticsearch_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_server_mocks.mdx b/api_docs/kbn_core_elasticsearch_server_mocks.mdx index be36b21731fdc..79c5a37393840 100644 --- a/api_docs/kbn_core_elasticsearch_server_mocks.mdx +++ b/api_docs/kbn_core_elasticsearch_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server-mocks title: "@kbn/core-elasticsearch-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-server-mocks plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-server-mocks'] --- import kbnCoreElasticsearchServerMocksObj from './kbn_core_elasticsearch_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_environment_server_internal.mdx b/api_docs/kbn_core_environment_server_internal.mdx index f87a9f14fd803..e99acf6a3e672 100644 --- a/api_docs/kbn_core_environment_server_internal.mdx +++ b/api_docs/kbn_core_environment_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-environment-server-internal title: "@kbn/core-environment-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-environment-server-internal plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-environment-server-internal'] --- import kbnCoreEnvironmentServerInternalObj from './kbn_core_environment_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_environment_server_mocks.mdx b/api_docs/kbn_core_environment_server_mocks.mdx index 2a17e4f365d9d..96cd751aff25e 100644 --- a/api_docs/kbn_core_environment_server_mocks.mdx +++ b/api_docs/kbn_core_environment_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-environment-server-mocks title: "@kbn/core-environment-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-environment-server-mocks plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-environment-server-mocks'] --- import kbnCoreEnvironmentServerMocksObj from './kbn_core_environment_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_browser.mdx b/api_docs/kbn_core_execution_context_browser.mdx index fb8952b47bce0..cb4aca1b40993 100644 --- a/api_docs/kbn_core_execution_context_browser.mdx +++ b/api_docs/kbn_core_execution_context_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-browser title: "@kbn/core-execution-context-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-browser plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-browser'] --- import kbnCoreExecutionContextBrowserObj from './kbn_core_execution_context_browser.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_browser_internal.mdx b/api_docs/kbn_core_execution_context_browser_internal.mdx index eb960b5be3091..513da81629358 100644 --- a/api_docs/kbn_core_execution_context_browser_internal.mdx +++ b/api_docs/kbn_core_execution_context_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-browser-internal title: "@kbn/core-execution-context-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-browser-internal plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-browser-internal'] --- import kbnCoreExecutionContextBrowserInternalObj from './kbn_core_execution_context_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_browser_mocks.mdx b/api_docs/kbn_core_execution_context_browser_mocks.mdx index 8a0448903f1df..7967bb82da0db 100644 --- a/api_docs/kbn_core_execution_context_browser_mocks.mdx +++ b/api_docs/kbn_core_execution_context_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-browser-mocks title: "@kbn/core-execution-context-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-browser-mocks plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-browser-mocks'] --- import kbnCoreExecutionContextBrowserMocksObj from './kbn_core_execution_context_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_common.mdx b/api_docs/kbn_core_execution_context_common.mdx index 69f7cdbdf52d2..0f608a0690c96 100644 --- a/api_docs/kbn_core_execution_context_common.mdx +++ b/api_docs/kbn_core_execution_context_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-common title: "@kbn/core-execution-context-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-common plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-common'] --- import kbnCoreExecutionContextCommonObj from './kbn_core_execution_context_common.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_server.mdx b/api_docs/kbn_core_execution_context_server.mdx index 9c7576a7f456e..7328a307f1252 100644 --- a/api_docs/kbn_core_execution_context_server.mdx +++ b/api_docs/kbn_core_execution_context_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-server title: "@kbn/core-execution-context-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-server plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-server'] --- import kbnCoreExecutionContextServerObj from './kbn_core_execution_context_server.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_server_internal.mdx b/api_docs/kbn_core_execution_context_server_internal.mdx index 7391331a2490f..1fa7cfaf1d569 100644 --- a/api_docs/kbn_core_execution_context_server_internal.mdx +++ b/api_docs/kbn_core_execution_context_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-server-internal title: "@kbn/core-execution-context-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-server-internal plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-server-internal'] --- import kbnCoreExecutionContextServerInternalObj from './kbn_core_execution_context_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_server_mocks.mdx b/api_docs/kbn_core_execution_context_server_mocks.mdx index 4a2399325e241..8209391797eb8 100644 --- a/api_docs/kbn_core_execution_context_server_mocks.mdx +++ b/api_docs/kbn_core_execution_context_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-server-mocks title: "@kbn/core-execution-context-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-server-mocks plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-server-mocks'] --- import kbnCoreExecutionContextServerMocksObj from './kbn_core_execution_context_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_fatal_errors_browser.mdx b/api_docs/kbn_core_fatal_errors_browser.mdx index b5f4edfe2d1e5..26e88146b34cb 100644 --- a/api_docs/kbn_core_fatal_errors_browser.mdx +++ b/api_docs/kbn_core_fatal_errors_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-fatal-errors-browser title: "@kbn/core-fatal-errors-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-fatal-errors-browser plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-fatal-errors-browser'] --- import kbnCoreFatalErrorsBrowserObj from './kbn_core_fatal_errors_browser.devdocs.json'; diff --git a/api_docs/kbn_core_fatal_errors_browser_mocks.mdx b/api_docs/kbn_core_fatal_errors_browser_mocks.mdx index 4e3183e041180..a875baf15e78e 100644 --- a/api_docs/kbn_core_fatal_errors_browser_mocks.mdx +++ b/api_docs/kbn_core_fatal_errors_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-fatal-errors-browser-mocks title: "@kbn/core-fatal-errors-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-fatal-errors-browser-mocks plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-fatal-errors-browser-mocks'] --- import kbnCoreFatalErrorsBrowserMocksObj from './kbn_core_fatal_errors_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_feature_flags_browser.mdx b/api_docs/kbn_core_feature_flags_browser.mdx index 2d31d86b2764d..42fa72a883963 100644 --- a/api_docs/kbn_core_feature_flags_browser.mdx +++ b/api_docs/kbn_core_feature_flags_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-feature-flags-browser title: "@kbn/core-feature-flags-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-feature-flags-browser plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-feature-flags-browser'] --- import kbnCoreFeatureFlagsBrowserObj from './kbn_core_feature_flags_browser.devdocs.json'; diff --git a/api_docs/kbn_core_feature_flags_browser_internal.mdx b/api_docs/kbn_core_feature_flags_browser_internal.mdx index 9383ab606183f..d217d041e47f8 100644 --- a/api_docs/kbn_core_feature_flags_browser_internal.mdx +++ b/api_docs/kbn_core_feature_flags_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-feature-flags-browser-internal title: "@kbn/core-feature-flags-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-feature-flags-browser-internal plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-feature-flags-browser-internal'] --- import kbnCoreFeatureFlagsBrowserInternalObj from './kbn_core_feature_flags_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_feature_flags_browser_mocks.mdx b/api_docs/kbn_core_feature_flags_browser_mocks.mdx index 637f2504fa5ba..f0e6419529cec 100644 --- a/api_docs/kbn_core_feature_flags_browser_mocks.mdx +++ b/api_docs/kbn_core_feature_flags_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-feature-flags-browser-mocks title: "@kbn/core-feature-flags-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-feature-flags-browser-mocks plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-feature-flags-browser-mocks'] --- import kbnCoreFeatureFlagsBrowserMocksObj from './kbn_core_feature_flags_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_feature_flags_server.mdx b/api_docs/kbn_core_feature_flags_server.mdx index 51db3fe102e5c..7407052fffac0 100644 --- a/api_docs/kbn_core_feature_flags_server.mdx +++ b/api_docs/kbn_core_feature_flags_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-feature-flags-server title: "@kbn/core-feature-flags-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-feature-flags-server plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-feature-flags-server'] --- import kbnCoreFeatureFlagsServerObj from './kbn_core_feature_flags_server.devdocs.json'; diff --git a/api_docs/kbn_core_feature_flags_server_internal.mdx b/api_docs/kbn_core_feature_flags_server_internal.mdx index 9db2449e7eccd..8de24625d29c5 100644 --- a/api_docs/kbn_core_feature_flags_server_internal.mdx +++ b/api_docs/kbn_core_feature_flags_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-feature-flags-server-internal title: "@kbn/core-feature-flags-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-feature-flags-server-internal plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-feature-flags-server-internal'] --- import kbnCoreFeatureFlagsServerInternalObj from './kbn_core_feature_flags_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_feature_flags_server_mocks.mdx b/api_docs/kbn_core_feature_flags_server_mocks.mdx index 1325a4eb181af..8e1c60b0e1223 100644 --- a/api_docs/kbn_core_feature_flags_server_mocks.mdx +++ b/api_docs/kbn_core_feature_flags_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-feature-flags-server-mocks title: "@kbn/core-feature-flags-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-feature-flags-server-mocks plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-feature-flags-server-mocks'] --- import kbnCoreFeatureFlagsServerMocksObj from './kbn_core_feature_flags_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_browser.mdx b/api_docs/kbn_core_http_browser.mdx index 6001c3b1760c1..4f05da87b338f 100644 --- a/api_docs/kbn_core_http_browser.mdx +++ b/api_docs/kbn_core_http_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-browser title: "@kbn/core-http-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-browser plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-browser'] --- import kbnCoreHttpBrowserObj from './kbn_core_http_browser.devdocs.json'; diff --git a/api_docs/kbn_core_http_browser_internal.mdx b/api_docs/kbn_core_http_browser_internal.mdx index e6cee51657b8c..76025554376d3 100644 --- a/api_docs/kbn_core_http_browser_internal.mdx +++ b/api_docs/kbn_core_http_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-browser-internal title: "@kbn/core-http-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-browser-internal plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-browser-internal'] --- import kbnCoreHttpBrowserInternalObj from './kbn_core_http_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_http_browser_mocks.mdx b/api_docs/kbn_core_http_browser_mocks.mdx index 4100051fc09ba..2ed6505492725 100644 --- a/api_docs/kbn_core_http_browser_mocks.mdx +++ b/api_docs/kbn_core_http_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-browser-mocks title: "@kbn/core-http-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-browser-mocks plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-browser-mocks'] --- import kbnCoreHttpBrowserMocksObj from './kbn_core_http_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_common.mdx b/api_docs/kbn_core_http_common.mdx index 4406976fe3f1f..76e5bf1c26146 100644 --- a/api_docs/kbn_core_http_common.mdx +++ b/api_docs/kbn_core_http_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-common title: "@kbn/core-http-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-common plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-common'] --- import kbnCoreHttpCommonObj from './kbn_core_http_common.devdocs.json'; diff --git a/api_docs/kbn_core_http_context_server_mocks.mdx b/api_docs/kbn_core_http_context_server_mocks.mdx index 502631dbf04c2..e5f33881d9b3d 100644 --- a/api_docs/kbn_core_http_context_server_mocks.mdx +++ b/api_docs/kbn_core_http_context_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-context-server-mocks title: "@kbn/core-http-context-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-context-server-mocks plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-context-server-mocks'] --- import kbnCoreHttpContextServerMocksObj from './kbn_core_http_context_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_request_handler_context_server.mdx b/api_docs/kbn_core_http_request_handler_context_server.mdx index 77eb7646fb5fd..f4855ca0d6167 100644 --- a/api_docs/kbn_core_http_request_handler_context_server.mdx +++ b/api_docs/kbn_core_http_request_handler_context_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-request-handler-context-server title: "@kbn/core-http-request-handler-context-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-request-handler-context-server plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-request-handler-context-server'] --- import kbnCoreHttpRequestHandlerContextServerObj from './kbn_core_http_request_handler_context_server.devdocs.json'; diff --git a/api_docs/kbn_core_http_resources_server.mdx b/api_docs/kbn_core_http_resources_server.mdx index ad6cf90e871e0..1997e4cc5eecc 100644 --- a/api_docs/kbn_core_http_resources_server.mdx +++ b/api_docs/kbn_core_http_resources_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-resources-server title: "@kbn/core-http-resources-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-resources-server plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-resources-server'] --- import kbnCoreHttpResourcesServerObj from './kbn_core_http_resources_server.devdocs.json'; diff --git a/api_docs/kbn_core_http_resources_server_internal.mdx b/api_docs/kbn_core_http_resources_server_internal.mdx index b803e563f827e..efbdec67cab4d 100644 --- a/api_docs/kbn_core_http_resources_server_internal.mdx +++ b/api_docs/kbn_core_http_resources_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-resources-server-internal title: "@kbn/core-http-resources-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-resources-server-internal plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-resources-server-internal'] --- import kbnCoreHttpResourcesServerInternalObj from './kbn_core_http_resources_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_http_resources_server_mocks.mdx b/api_docs/kbn_core_http_resources_server_mocks.mdx index 21626b5029159..c852a9402ddf3 100644 --- a/api_docs/kbn_core_http_resources_server_mocks.mdx +++ b/api_docs/kbn_core_http_resources_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-resources-server-mocks title: "@kbn/core-http-resources-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-resources-server-mocks plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-resources-server-mocks'] --- import kbnCoreHttpResourcesServerMocksObj from './kbn_core_http_resources_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_router_server_internal.mdx b/api_docs/kbn_core_http_router_server_internal.mdx index b6f86985d1888..cbeafe319ddc0 100644 --- a/api_docs/kbn_core_http_router_server_internal.mdx +++ b/api_docs/kbn_core_http_router_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-router-server-internal title: "@kbn/core-http-router-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-router-server-internal plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-router-server-internal'] --- import kbnCoreHttpRouterServerInternalObj from './kbn_core_http_router_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_http_router_server_mocks.mdx b/api_docs/kbn_core_http_router_server_mocks.mdx index d65248840a6f4..2b867d2b8ad3a 100644 --- a/api_docs/kbn_core_http_router_server_mocks.mdx +++ b/api_docs/kbn_core_http_router_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-router-server-mocks title: "@kbn/core-http-router-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-router-server-mocks plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-router-server-mocks'] --- import kbnCoreHttpRouterServerMocksObj from './kbn_core_http_router_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_server.devdocs.json b/api_docs/kbn_core_http_server.devdocs.json index 165ea653d91b7..e00fe9fba4edb 100644 --- a/api_docs/kbn_core_http_server.devdocs.json +++ b/api_docs/kbn_core_http_server.devdocs.json @@ -7475,6 +7475,10 @@ "plugin": "serverlessSearch", "path": "x-pack/plugins/serverless_search/server/routes/connectors_routes.ts" }, + { + "plugin": "serverlessSearch", + "path": "x-pack/plugins/serverless_search/server/routes/connectors_routes.ts" + }, { "plugin": "snapshotRestore", "path": "x-pack/plugins/snapshot_restore/server/routes/api/repositories.ts" @@ -17659,6 +17663,14 @@ "plugin": "securitySolution", "path": "x-pack/plugins/security_solution/server/lib/siem_migrations/rules/api/resources/upsert.ts" }, + { + "plugin": "securitySolution", + "path": "x-pack/plugins/security_solution/server/lib/siem_migrations/rules/api/rules/install.ts" + }, + { + "plugin": "securitySolution", + "path": "x-pack/plugins/security_solution/server/lib/siem_migrations/rules/api/rules/install_translated.ts" + }, { "plugin": "securitySolution", "path": "x-pack/plugins/security_solution/server/endpoint/routes/actions/response_actions.ts" @@ -17751,10 +17763,6 @@ "plugin": "dataUsage", "path": "x-pack/plugins/data_usage/server/routes/internal/usage_metrics.test.ts" }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/routes/stats.ts" - }, { "plugin": "securitySolution", "path": "x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_create_rules/route.ts" diff --git a/api_docs/kbn_core_http_server.mdx b/api_docs/kbn_core_http_server.mdx index 123bde26436ec..b708669c2e294 100644 --- a/api_docs/kbn_core_http_server.mdx +++ b/api_docs/kbn_core_http_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-server title: "@kbn/core-http-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-server plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-server'] --- import kbnCoreHttpServerObj from './kbn_core_http_server.devdocs.json'; diff --git a/api_docs/kbn_core_http_server_internal.mdx b/api_docs/kbn_core_http_server_internal.mdx index 4a2eafb16665d..d65f99fef2e36 100644 --- a/api_docs/kbn_core_http_server_internal.mdx +++ b/api_docs/kbn_core_http_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-server-internal title: "@kbn/core-http-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-server-internal plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-server-internal'] --- import kbnCoreHttpServerInternalObj from './kbn_core_http_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_http_server_mocks.mdx b/api_docs/kbn_core_http_server_mocks.mdx index 25aa9ce471276..d1ad90e098d70 100644 --- a/api_docs/kbn_core_http_server_mocks.mdx +++ b/api_docs/kbn_core_http_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-server-mocks title: "@kbn/core-http-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-server-mocks plugin -date: 2024-11-29 +date: 2024-12-03 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_http_server_utils.mdx b/api_docs/kbn_core_http_server_utils.mdx index cb7fd6814e42a..6633aca139c15 100644 --- a/api_docs/kbn_core_http_server_utils.mdx +++ b/api_docs/kbn_core_http_server_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-server-utils title: "@kbn/core-http-server-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-server-utils plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-server-utils'] --- import kbnCoreHttpServerUtilsObj from './kbn_core_http_server_utils.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_browser.mdx b/api_docs/kbn_core_i18n_browser.mdx index 296d76157dc0c..5567e2a5af4c6 100644 --- a/api_docs/kbn_core_i18n_browser.mdx +++ b/api_docs/kbn_core_i18n_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-browser title: "@kbn/core-i18n-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-browser plugin -date: 2024-11-29 +date: 2024-12-03 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 f925a2da54cff..6cfea71eaffbd 100644 --- a/api_docs/kbn_core_i18n_browser_mocks.mdx +++ b/api_docs/kbn_core_i18n_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-browser-mocks title: "@kbn/core-i18n-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-browser-mocks plugin -date: 2024-11-29 +date: 2024-12-03 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 ac450338540a6..d743f16279ba3 100644 --- a/api_docs/kbn_core_i18n_server.mdx +++ b/api_docs/kbn_core_i18n_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-server title: "@kbn/core-i18n-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-server plugin -date: 2024-11-29 +date: 2024-12-03 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 78b7544b133e2..7adde615137c0 100644 --- a/api_docs/kbn_core_i18n_server_internal.mdx +++ b/api_docs/kbn_core_i18n_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-server-internal title: "@kbn/core-i18n-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-server-internal plugin -date: 2024-11-29 +date: 2024-12-03 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 e7ef905f95308..0ac752131d67a 100644 --- a/api_docs/kbn_core_i18n_server_mocks.mdx +++ b/api_docs/kbn_core_i18n_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-server-mocks title: "@kbn/core-i18n-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-server-mocks plugin -date: 2024-11-29 +date: 2024-12-03 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 30f900dde375f..d8926d7c3e3f8 100644 --- a/api_docs/kbn_core_injected_metadata_browser_mocks.mdx +++ b/api_docs/kbn_core_injected_metadata_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-injected-metadata-browser-mocks title: "@kbn/core-injected-metadata-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-injected-metadata-browser-mocks plugin -date: 2024-11-29 +date: 2024-12-03 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 ac0c404d6ca5f..8f9c96d1b0820 100644 --- a/api_docs/kbn_core_integrations_browser_internal.mdx +++ b/api_docs/kbn_core_integrations_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-integrations-browser-internal title: "@kbn/core-integrations-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-integrations-browser-internal plugin -date: 2024-11-29 +date: 2024-12-03 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 f9ffbf310388e..e8c551ba6970c 100644 --- a/api_docs/kbn_core_integrations_browser_mocks.mdx +++ b/api_docs/kbn_core_integrations_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-integrations-browser-mocks title: "@kbn/core-integrations-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-integrations-browser-mocks plugin -date: 2024-11-29 +date: 2024-12-03 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 76058d74f0826..2e3e60c740e8f 100644 --- a/api_docs/kbn_core_lifecycle_browser.mdx +++ b/api_docs/kbn_core_lifecycle_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-browser title: "@kbn/core-lifecycle-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-browser plugin -date: 2024-11-29 +date: 2024-12-03 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 42a4adfc7d675..2b98c841824ba 100644 --- a/api_docs/kbn_core_lifecycle_browser_mocks.mdx +++ b/api_docs/kbn_core_lifecycle_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-browser-mocks title: "@kbn/core-lifecycle-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-browser-mocks plugin -date: 2024-11-29 +date: 2024-12-03 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 65b186ccdc3d2..81363e2d8c60e 100644 --- a/api_docs/kbn_core_lifecycle_server.mdx +++ b/api_docs/kbn_core_lifecycle_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-server title: "@kbn/core-lifecycle-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-server plugin -date: 2024-11-29 +date: 2024-12-03 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 2e07fec1fd6c9..1efc5ce8cec4a 100644 --- a/api_docs/kbn_core_lifecycle_server_mocks.mdx +++ b/api_docs/kbn_core_lifecycle_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-server-mocks title: "@kbn/core-lifecycle-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-server-mocks plugin -date: 2024-11-29 +date: 2024-12-03 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 48759186d02d6..6be2aa265a4a3 100644 --- a/api_docs/kbn_core_logging_browser_mocks.mdx +++ b/api_docs/kbn_core_logging_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-browser-mocks title: "@kbn/core-logging-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-browser-mocks plugin -date: 2024-11-29 +date: 2024-12-03 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 749f3b376cced..b461602b7cf9c 100644 --- a/api_docs/kbn_core_logging_common_internal.mdx +++ b/api_docs/kbn_core_logging_common_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-common-internal title: "@kbn/core-logging-common-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-common-internal plugin -date: 2024-11-29 +date: 2024-12-03 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 a8957c1b054b2..267c8ca7ec069 100644 --- a/api_docs/kbn_core_logging_server.mdx +++ b/api_docs/kbn_core_logging_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-server title: "@kbn/core-logging-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-server plugin -date: 2024-11-29 +date: 2024-12-03 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 ffd64c49278f8..dd391bef61679 100644 --- a/api_docs/kbn_core_logging_server_internal.mdx +++ b/api_docs/kbn_core_logging_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-server-internal title: "@kbn/core-logging-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-server-internal plugin -date: 2024-11-29 +date: 2024-12-03 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 c1fd692ffb38d..2c1d89369c266 100644 --- a/api_docs/kbn_core_logging_server_mocks.mdx +++ b/api_docs/kbn_core_logging_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-server-mocks title: "@kbn/core-logging-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-server-mocks plugin -date: 2024-11-29 +date: 2024-12-03 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 3242e7a877f4f..e92dbb42156e9 100644 --- a/api_docs/kbn_core_metrics_collectors_server_internal.mdx +++ b/api_docs/kbn_core_metrics_collectors_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-collectors-server-internal title: "@kbn/core-metrics-collectors-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-collectors-server-internal plugin -date: 2024-11-29 +date: 2024-12-03 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 90d2ad881e080..7467c3c278ff9 100644 --- a/api_docs/kbn_core_metrics_collectors_server_mocks.mdx +++ b/api_docs/kbn_core_metrics_collectors_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-collectors-server-mocks title: "@kbn/core-metrics-collectors-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-collectors-server-mocks plugin -date: 2024-11-29 +date: 2024-12-03 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 d05ff9845297a..f97db3c3c112a 100644 --- a/api_docs/kbn_core_metrics_server.mdx +++ b/api_docs/kbn_core_metrics_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-server title: "@kbn/core-metrics-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-server plugin -date: 2024-11-29 +date: 2024-12-03 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 6fed1b3984f50..1091e8d8ae9ff 100644 --- a/api_docs/kbn_core_metrics_server_internal.mdx +++ b/api_docs/kbn_core_metrics_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-server-internal title: "@kbn/core-metrics-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-server-internal plugin -date: 2024-11-29 +date: 2024-12-03 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 7a5a706e4930f..0b2667b4756aa 100644 --- a/api_docs/kbn_core_metrics_server_mocks.mdx +++ b/api_docs/kbn_core_metrics_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-server-mocks title: "@kbn/core-metrics-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-server-mocks plugin -date: 2024-11-29 +date: 2024-12-03 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 078bfcba9055e..97030cbe9deed 100644 --- a/api_docs/kbn_core_mount_utils_browser.mdx +++ b/api_docs/kbn_core_mount_utils_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-mount-utils-browser title: "@kbn/core-mount-utils-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-mount-utils-browser plugin -date: 2024-11-29 +date: 2024-12-03 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 25436d5660eb6..aef8e3db6898f 100644 --- a/api_docs/kbn_core_node_server.mdx +++ b/api_docs/kbn_core_node_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-node-server title: "@kbn/core-node-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-node-server plugin -date: 2024-11-29 +date: 2024-12-03 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 c180e9673b564..0159d8b222d29 100644 --- a/api_docs/kbn_core_node_server_internal.mdx +++ b/api_docs/kbn_core_node_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-node-server-internal title: "@kbn/core-node-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-node-server-internal plugin -date: 2024-11-29 +date: 2024-12-03 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 d1077761aa6d1..ca934e7d7fc9f 100644 --- a/api_docs/kbn_core_node_server_mocks.mdx +++ b/api_docs/kbn_core_node_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-node-server-mocks title: "@kbn/core-node-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-node-server-mocks plugin -date: 2024-11-29 +date: 2024-12-03 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 e9f82c4336090..53e4db7c561b8 100644 --- a/api_docs/kbn_core_notifications_browser.mdx +++ b/api_docs/kbn_core_notifications_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-notifications-browser title: "@kbn/core-notifications-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-notifications-browser plugin -date: 2024-11-29 +date: 2024-12-03 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 6af4037b9458f..b2e1537228ccf 100644 --- a/api_docs/kbn_core_notifications_browser_internal.mdx +++ b/api_docs/kbn_core_notifications_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-notifications-browser-internal title: "@kbn/core-notifications-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-notifications-browser-internal plugin -date: 2024-11-29 +date: 2024-12-03 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 b846b7ae7ecd3..23c2274e15a38 100644 --- a/api_docs/kbn_core_notifications_browser_mocks.mdx +++ b/api_docs/kbn_core_notifications_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-notifications-browser-mocks title: "@kbn/core-notifications-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-notifications-browser-mocks plugin -date: 2024-11-29 +date: 2024-12-03 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 c011318466ebe..50ac9d4b57cc5 100644 --- a/api_docs/kbn_core_overlays_browser.mdx +++ b/api_docs/kbn_core_overlays_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-overlays-browser title: "@kbn/core-overlays-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-overlays-browser plugin -date: 2024-11-29 +date: 2024-12-03 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 54d70e6445bee..d07a99390dc31 100644 --- a/api_docs/kbn_core_overlays_browser_internal.mdx +++ b/api_docs/kbn_core_overlays_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-overlays-browser-internal title: "@kbn/core-overlays-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-overlays-browser-internal plugin -date: 2024-11-29 +date: 2024-12-03 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 4ce76ef4c0629..75124a902a562 100644 --- a/api_docs/kbn_core_overlays_browser_mocks.mdx +++ b/api_docs/kbn_core_overlays_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-overlays-browser-mocks title: "@kbn/core-overlays-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-overlays-browser-mocks plugin -date: 2024-11-29 +date: 2024-12-03 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 cce9e7c67fca1..783da4ddb53f0 100644 --- a/api_docs/kbn_core_plugins_browser.mdx +++ b/api_docs/kbn_core_plugins_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-browser title: "@kbn/core-plugins-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-browser plugin -date: 2024-11-29 +date: 2024-12-03 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 d4661d0b88443..f92668accf930 100644 --- a/api_docs/kbn_core_plugins_browser_mocks.mdx +++ b/api_docs/kbn_core_plugins_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-browser-mocks title: "@kbn/core-plugins-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-browser-mocks plugin -date: 2024-11-29 +date: 2024-12-03 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 9ec09c43f6d48..3443582ec645b 100644 --- a/api_docs/kbn_core_plugins_contracts_browser.mdx +++ b/api_docs/kbn_core_plugins_contracts_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-contracts-browser title: "@kbn/core-plugins-contracts-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-contracts-browser plugin -date: 2024-11-29 +date: 2024-12-03 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 a8aa1bbc0e110..cafbdd0dbdfea 100644 --- a/api_docs/kbn_core_plugins_contracts_server.mdx +++ b/api_docs/kbn_core_plugins_contracts_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-contracts-server title: "@kbn/core-plugins-contracts-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-contracts-server plugin -date: 2024-11-29 +date: 2024-12-03 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 fcca86babc805..21b9b4a11bd16 100644 --- a/api_docs/kbn_core_plugins_server.mdx +++ b/api_docs/kbn_core_plugins_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-server title: "@kbn/core-plugins-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-server plugin -date: 2024-11-29 +date: 2024-12-03 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 00001acd0eb48..d1ddd23bcebac 100644 --- a/api_docs/kbn_core_plugins_server_mocks.mdx +++ b/api_docs/kbn_core_plugins_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-server-mocks title: "@kbn/core-plugins-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-server-mocks plugin -date: 2024-11-29 +date: 2024-12-03 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 ac127a0fc776c..d967299d7f003 100644 --- a/api_docs/kbn_core_preboot_server.mdx +++ b/api_docs/kbn_core_preboot_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-preboot-server title: "@kbn/core-preboot-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-preboot-server plugin -date: 2024-11-29 +date: 2024-12-03 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 7f4533933d896..6651f38621fbc 100644 --- a/api_docs/kbn_core_preboot_server_mocks.mdx +++ b/api_docs/kbn_core_preboot_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-preboot-server-mocks title: "@kbn/core-preboot-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-preboot-server-mocks plugin -date: 2024-11-29 +date: 2024-12-03 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.mdx b/api_docs/kbn_core_rendering_browser.mdx index 329897d21beb2..40bc8f495cf72 100644 --- a/api_docs/kbn_core_rendering_browser.mdx +++ b/api_docs/kbn_core_rendering_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-rendering-browser title: "@kbn/core-rendering-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-rendering-browser plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-rendering-browser'] --- import kbnCoreRenderingBrowserObj from './kbn_core_rendering_browser.devdocs.json'; diff --git a/api_docs/kbn_core_rendering_browser_mocks.mdx b/api_docs/kbn_core_rendering_browser_mocks.mdx index cf4419dcf7177..45b2d207b2523 100644 --- a/api_docs/kbn_core_rendering_browser_mocks.mdx +++ b/api_docs/kbn_core_rendering_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-rendering-browser-mocks title: "@kbn/core-rendering-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-rendering-browser-mocks plugin -date: 2024-11-29 +date: 2024-12-03 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 d16850b43166c..67d55f3ecc1f5 100644 --- a/api_docs/kbn_core_rendering_server_internal.mdx +++ b/api_docs/kbn_core_rendering_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-rendering-server-internal title: "@kbn/core-rendering-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-rendering-server-internal plugin -date: 2024-11-29 +date: 2024-12-03 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 aa164c8f24225..d0577d2523b33 100644 --- a/api_docs/kbn_core_rendering_server_mocks.mdx +++ b/api_docs/kbn_core_rendering_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-rendering-server-mocks title: "@kbn/core-rendering-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-rendering-server-mocks plugin -date: 2024-11-29 +date: 2024-12-03 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 4e6d70baa8fb4..d9714266c585a 100644 --- a/api_docs/kbn_core_root_server_internal.mdx +++ b/api_docs/kbn_core_root_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-root-server-internal title: "@kbn/core-root-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-root-server-internal plugin -date: 2024-11-29 +date: 2024-12-03 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 632ea40d537b7..f3cbde1178c1a 100644 --- a/api_docs/kbn_core_saved_objects_api_browser.mdx +++ b/api_docs/kbn_core_saved_objects_api_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-browser title: "@kbn/core-saved-objects-api-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-browser plugin -date: 2024-11-29 +date: 2024-12-03 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 366ffcfd1c089..f678ab1ec3d67 100644 --- a/api_docs/kbn_core_saved_objects_api_server.mdx +++ b/api_docs/kbn_core_saved_objects_api_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-server title: "@kbn/core-saved-objects-api-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-server plugin -date: 2024-11-29 +date: 2024-12-03 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 7dc2171f46bc6..493afd439a826 100644 --- a/api_docs/kbn_core_saved_objects_api_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_api_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-server-mocks title: "@kbn/core-saved-objects-api-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-server-mocks plugin -date: 2024-11-29 +date: 2024-12-03 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 c32f79a321d20..aba0c61c2614d 100644 --- a/api_docs/kbn_core_saved_objects_base_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_base_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-base-server-internal title: "@kbn/core-saved-objects-base-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-base-server-internal plugin -date: 2024-11-29 +date: 2024-12-03 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 771938d8807b2..d9ca3c27db3d2 100644 --- a/api_docs/kbn_core_saved_objects_base_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_base_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-base-server-mocks title: "@kbn/core-saved-objects-base-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-base-server-mocks plugin -date: 2024-11-29 +date: 2024-12-03 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 447a8059cf59c..75f59d3536485 100644 --- a/api_docs/kbn_core_saved_objects_browser.mdx +++ b/api_docs/kbn_core_saved_objects_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-browser title: "@kbn/core-saved-objects-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-browser plugin -date: 2024-11-29 +date: 2024-12-03 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 a67797993cdb6..68a5fee7c6902 100644 --- a/api_docs/kbn_core_saved_objects_browser_internal.mdx +++ b/api_docs/kbn_core_saved_objects_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-browser-internal title: "@kbn/core-saved-objects-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-browser-internal plugin -date: 2024-11-29 +date: 2024-12-03 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 8a1432e4912f6..e615bec13081b 100644 --- a/api_docs/kbn_core_saved_objects_browser_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-browser-mocks title: "@kbn/core-saved-objects-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-browser-mocks plugin -date: 2024-11-29 +date: 2024-12-03 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 bb003fca3dc16..4af0177f5296d 100644 --- a/api_docs/kbn_core_saved_objects_common.mdx +++ b/api_docs/kbn_core_saved_objects_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-common title: "@kbn/core-saved-objects-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-common plugin -date: 2024-11-29 +date: 2024-12-03 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 8e2aef6c42888..22704341fa3f5 100644 --- a/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-import-export-server-internal title: "@kbn/core-saved-objects-import-export-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-import-export-server-internal plugin -date: 2024-11-29 +date: 2024-12-03 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 44e3ce8b63f33..5137325e5f25a 100644 --- a/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-import-export-server-mocks title: "@kbn/core-saved-objects-import-export-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-import-export-server-mocks plugin -date: 2024-11-29 +date: 2024-12-03 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 dcf3ed01d6006..9c1431826cd1e 100644 --- a/api_docs/kbn_core_saved_objects_migration_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_migration_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-migration-server-internal title: "@kbn/core-saved-objects-migration-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-migration-server-internal plugin -date: 2024-11-29 +date: 2024-12-03 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 f2f0f11c1158c..43b6f9c7ca40c 100644 --- a/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-migration-server-mocks title: "@kbn/core-saved-objects-migration-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-migration-server-mocks plugin -date: 2024-11-29 +date: 2024-12-03 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.devdocs.json b/api_docs/kbn_core_saved_objects_server.devdocs.json index b64f85ca1c4e5..ba262035a1c0f 100644 --- a/api_docs/kbn_core_saved_objects_server.devdocs.json +++ b/api_docs/kbn_core_saved_objects_server.devdocs.json @@ -10539,7 +10539,7 @@ ], "label": "migrations", "description": [ - "\nAn optional map of {@link SavedObjectMigrationFn | migrations} or a function returning a map of {@link SavedObjectMigrationFn | migrations} to be used to migrate the type." + "\nAn optional map of {@link SavedObjectMigrationFn | migrations} or a function returning a map of\n{@link SavedObjectMigrationFn | migrations} to be used to migrate the type.\n" ], "signature": [ { @@ -11445,7 +11445,7 @@ ], "label": "convertToMultiNamespaceTypeVersion", "description": [ - "\nIf defined, objects of this type will be converted to a 'multiple' or 'multiple-isolated' namespace type when migrating to this\nversion.\n\nRequirements:\n\n 1. This string value must be a valid semver version\n 2. This type must have previously specified {@link SavedObjectsNamespaceType | `namespaceType: 'single'`}\n 3. This type must also specify {@link SavedObjectsNamespaceType | `namespaceType: 'multiple'`} *or*\n {@link SavedObjectsNamespaceType | `namespaceType: 'multiple-isolated'`}\n\nExample of a single-namespace type in 7.12:\n\n```ts\n{\n name: 'foo',\n hidden: false,\n namespaceType: 'single',\n mappings: {...}\n}\n```\n\nExample after converting to a multi-namespace (isolated) type in 8.0:\n\n```ts\n{\n name: 'foo',\n hidden: false,\n namespaceType: 'multiple-isolated',\n mappings: {...},\n convertToMultiNamespaceTypeVersion: '8.0.0'\n}\n```\n\nExample after converting to a multi-namespace (shareable) type in 8.1:\n\n```ts\n{\n name: 'foo',\n hidden: false,\n namespaceType: 'multiple',\n mappings: {...},\n convertToMultiNamespaceTypeVersion: '8.0.0'\n}\n```\n\nNote: migration function(s) can be optionally specified for any of these versions and will not interfere with the conversion process." + "\nIf defined, objects of this type will be converted to a 'multiple' or 'multiple-isolated' namespace type when migrating to\nthis version.\n\nRequirements:\n\n 1. This string value must be a valid semver version\n 2. This type must have previously specified {@link SavedObjectsNamespaceType | `namespaceType: 'single'`}\n 3. This type must also specify {@link SavedObjectsNamespaceType | `namespaceType: 'multiple'`} *or*\n {@link SavedObjectsNamespaceType | `namespaceType: 'multiple-isolated'`}\n\nExample of a single-namespace type in 7.12:\n\n```ts\n{\n name: 'foo',\n hidden: false,\n namespaceType: 'single',\n mappings: {...}\n}\n```\n\nExample after converting to a multi-namespace (isolated) type in 8.0:\n\n```ts\n{\n name: 'foo',\n hidden: false,\n namespaceType: 'multiple-isolated',\n mappings: {...},\n convertToMultiNamespaceTypeVersion: '8.0.0'\n}\n```\n\nExample after converting to a multi-namespace (shareable) type in 8.1:\n\n```ts\n{\n name: 'foo',\n hidden: false,\n namespaceType: 'multiple',\n mappings: {...},\n convertToMultiNamespaceTypeVersion: '8.0.0'\n}\n```\n\nNote: migration function(s) can be optionally specified for any of these versions and will not interfere with the conversion process." ], "signature": [ "string | undefined" diff --git a/api_docs/kbn_core_saved_objects_server.mdx b/api_docs/kbn_core_saved_objects_server.mdx index c6e0c04fe8720..fb9b79f4816e4 100644 --- a/api_docs/kbn_core_saved_objects_server.mdx +++ b/api_docs/kbn_core_saved_objects_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-server title: "@kbn/core-saved-objects-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-server plugin -date: 2024-11-29 +date: 2024-12-03 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 3b2f869d72eaf..017493d5617a9 100644 --- a/api_docs/kbn_core_saved_objects_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-server-internal title: "@kbn/core-saved-objects-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-server-internal plugin -date: 2024-11-29 +date: 2024-12-03 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 3c85a8188b1aa..9659a6fe1e225 100644 --- a/api_docs/kbn_core_saved_objects_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-server-mocks title: "@kbn/core-saved-objects-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-server-mocks plugin -date: 2024-11-29 +date: 2024-12-03 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 b3b38c8dbfca2..ae7cb4a7add0a 100644 --- a/api_docs/kbn_core_saved_objects_utils_server.mdx +++ b/api_docs/kbn_core_saved_objects_utils_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-utils-server title: "@kbn/core-saved-objects-utils-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-utils-server plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-utils-server'] --- import kbnCoreSavedObjectsUtilsServerObj from './kbn_core_saved_objects_utils_server.devdocs.json'; diff --git a/api_docs/kbn_core_security_browser.mdx b/api_docs/kbn_core_security_browser.mdx index db2d15fde08a2..08620be021693 100644 --- a/api_docs/kbn_core_security_browser.mdx +++ b/api_docs/kbn_core_security_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-security-browser title: "@kbn/core-security-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-security-browser plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-security-browser'] --- import kbnCoreSecurityBrowserObj from './kbn_core_security_browser.devdocs.json'; diff --git a/api_docs/kbn_core_security_browser_internal.mdx b/api_docs/kbn_core_security_browser_internal.mdx index 5ccb64bd2f3ad..6361b016784ad 100644 --- a/api_docs/kbn_core_security_browser_internal.mdx +++ b/api_docs/kbn_core_security_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-security-browser-internal title: "@kbn/core-security-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-security-browser-internal plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-security-browser-internal'] --- import kbnCoreSecurityBrowserInternalObj from './kbn_core_security_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_security_browser_mocks.mdx b/api_docs/kbn_core_security_browser_mocks.mdx index a5122c763a5b5..624b0a5d0b129 100644 --- a/api_docs/kbn_core_security_browser_mocks.mdx +++ b/api_docs/kbn_core_security_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-security-browser-mocks title: "@kbn/core-security-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-security-browser-mocks plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-security-browser-mocks'] --- import kbnCoreSecurityBrowserMocksObj from './kbn_core_security_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_security_common.mdx b/api_docs/kbn_core_security_common.mdx index d601dfae85ec6..386ddb30bdac1 100644 --- a/api_docs/kbn_core_security_common.mdx +++ b/api_docs/kbn_core_security_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-security-common title: "@kbn/core-security-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-security-common plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-security-common'] --- import kbnCoreSecurityCommonObj from './kbn_core_security_common.devdocs.json'; diff --git a/api_docs/kbn_core_security_server.mdx b/api_docs/kbn_core_security_server.mdx index bf83337522aea..b2215891233ae 100644 --- a/api_docs/kbn_core_security_server.mdx +++ b/api_docs/kbn_core_security_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-security-server title: "@kbn/core-security-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-security-server plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-security-server'] --- import kbnCoreSecurityServerObj from './kbn_core_security_server.devdocs.json'; diff --git a/api_docs/kbn_core_security_server_internal.mdx b/api_docs/kbn_core_security_server_internal.mdx index 25e7a66ad3189..a644a1c8d4081 100644 --- a/api_docs/kbn_core_security_server_internal.mdx +++ b/api_docs/kbn_core_security_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-security-server-internal title: "@kbn/core-security-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-security-server-internal plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-security-server-internal'] --- import kbnCoreSecurityServerInternalObj from './kbn_core_security_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_security_server_mocks.mdx b/api_docs/kbn_core_security_server_mocks.mdx index b3aa2d54fe470..b8afb11f52fa7 100644 --- a/api_docs/kbn_core_security_server_mocks.mdx +++ b/api_docs/kbn_core_security_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-security-server-mocks title: "@kbn/core-security-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-security-server-mocks plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-security-server-mocks'] --- import kbnCoreSecurityServerMocksObj from './kbn_core_security_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_status_common.mdx b/api_docs/kbn_core_status_common.mdx index 8e413c1232146..e1475a8b1af0d 100644 --- a/api_docs/kbn_core_status_common.mdx +++ b/api_docs/kbn_core_status_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-common title: "@kbn/core-status-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-common plugin -date: 2024-11-29 +date: 2024-12-03 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_server.mdx b/api_docs/kbn_core_status_server.mdx index e45a4fc498b80..3ffe739dcf1a3 100644 --- a/api_docs/kbn_core_status_server.mdx +++ b/api_docs/kbn_core_status_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-server title: "@kbn/core-status-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-server plugin -date: 2024-11-29 +date: 2024-12-03 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 00b6e4a704aa5..2d0c5252744ca 100644 --- a/api_docs/kbn_core_status_server_internal.mdx +++ b/api_docs/kbn_core_status_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-server-internal title: "@kbn/core-status-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-server-internal plugin -date: 2024-11-29 +date: 2024-12-03 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 301e37689e04c..f5b5471a7cbfc 100644 --- a/api_docs/kbn_core_status_server_mocks.mdx +++ b/api_docs/kbn_core_status_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-server-mocks title: "@kbn/core-status-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-server-mocks plugin -date: 2024-11-29 +date: 2024-12-03 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 1e3f356276688..21176f25ee98a 100644 --- a/api_docs/kbn_core_test_helpers_deprecations_getters.mdx +++ b/api_docs/kbn_core_test_helpers_deprecations_getters.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-deprecations-getters title: "@kbn/core-test-helpers-deprecations-getters" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-deprecations-getters plugin -date: 2024-11-29 +date: 2024-12-03 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 a177d71ed74af..affb67dfd35a9 100644 --- a/api_docs/kbn_core_test_helpers_http_setup_browser.mdx +++ b/api_docs/kbn_core_test_helpers_http_setup_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-http-setup-browser title: "@kbn/core-test-helpers-http-setup-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-http-setup-browser plugin -date: 2024-11-29 +date: 2024-12-03 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 9846a585c803a..e1e74dd173f0f 100644 --- a/api_docs/kbn_core_test_helpers_kbn_server.mdx +++ b/api_docs/kbn_core_test_helpers_kbn_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-kbn-server title: "@kbn/core-test-helpers-kbn-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-kbn-server plugin -date: 2024-11-29 +date: 2024-12-03 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 cf876c1fcb4f7..4ae54cd255a13 100644 --- a/api_docs/kbn_core_test_helpers_model_versions.mdx +++ b/api_docs/kbn_core_test_helpers_model_versions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-model-versions title: "@kbn/core-test-helpers-model-versions" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-model-versions plugin -date: 2024-11-29 +date: 2024-12-03 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 b855069514b0b..b7360eaa5643d 100644 --- a/api_docs/kbn_core_test_helpers_so_type_serializer.mdx +++ b/api_docs/kbn_core_test_helpers_so_type_serializer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-so-type-serializer title: "@kbn/core-test-helpers-so-type-serializer" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-so-type-serializer plugin -date: 2024-11-29 +date: 2024-12-03 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 ada493725c346..ef14e3924099c 100644 --- a/api_docs/kbn_core_test_helpers_test_utils.mdx +++ b/api_docs/kbn_core_test_helpers_test_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-test-utils title: "@kbn/core-test-helpers-test-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-test-utils plugin -date: 2024-11-29 +date: 2024-12-03 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 e8fa3d76034fa..90c38d173feca 100644 --- a/api_docs/kbn_core_theme_browser.mdx +++ b/api_docs/kbn_core_theme_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-theme-browser title: "@kbn/core-theme-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-theme-browser plugin -date: 2024-11-29 +date: 2024-12-03 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 99d5aa2fa0018..6a69407ce5f0a 100644 --- a/api_docs/kbn_core_theme_browser_mocks.mdx +++ b/api_docs/kbn_core_theme_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-theme-browser-mocks title: "@kbn/core-theme-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-theme-browser-mocks plugin -date: 2024-11-29 +date: 2024-12-03 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 787b3b35fdbdd..ec4e3e5b92bf7 100644 --- a/api_docs/kbn_core_ui_settings_browser.mdx +++ b/api_docs/kbn_core_ui_settings_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-browser title: "@kbn/core-ui-settings-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-browser plugin -date: 2024-11-29 +date: 2024-12-03 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 af827e8467ffe..1a262c962c2c3 100644 --- a/api_docs/kbn_core_ui_settings_browser_internal.mdx +++ b/api_docs/kbn_core_ui_settings_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-browser-internal title: "@kbn/core-ui-settings-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-browser-internal plugin -date: 2024-11-29 +date: 2024-12-03 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 853e61f90f578..a7ee3280341a7 100644 --- a/api_docs/kbn_core_ui_settings_browser_mocks.mdx +++ b/api_docs/kbn_core_ui_settings_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-browser-mocks title: "@kbn/core-ui-settings-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-browser-mocks plugin -date: 2024-11-29 +date: 2024-12-03 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 32b1330dbb028..37d3a023d3fc3 100644 --- a/api_docs/kbn_core_ui_settings_common.mdx +++ b/api_docs/kbn_core_ui_settings_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-common title: "@kbn/core-ui-settings-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-common plugin -date: 2024-11-29 +date: 2024-12-03 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 3bc8a045c9383..5ca0c3bf77fee 100644 --- a/api_docs/kbn_core_ui_settings_server.mdx +++ b/api_docs/kbn_core_ui_settings_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-server title: "@kbn/core-ui-settings-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-server plugin -date: 2024-11-29 +date: 2024-12-03 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 d8f8ed795d3e3..4cad5e0861586 100644 --- a/api_docs/kbn_core_ui_settings_server_internal.mdx +++ b/api_docs/kbn_core_ui_settings_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-server-internal title: "@kbn/core-ui-settings-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-server-internal plugin -date: 2024-11-29 +date: 2024-12-03 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 62a69bc7b0a8a..d103bb0c7d6fd 100644 --- a/api_docs/kbn_core_ui_settings_server_mocks.mdx +++ b/api_docs/kbn_core_ui_settings_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-server-mocks title: "@kbn/core-ui-settings-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-server-mocks plugin -date: 2024-11-29 +date: 2024-12-03 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 69dcca110ae2e..fdfe693586930 100644 --- a/api_docs/kbn_core_usage_data_server.mdx +++ b/api_docs/kbn_core_usage_data_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-usage-data-server title: "@kbn/core-usage-data-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-usage-data-server plugin -date: 2024-11-29 +date: 2024-12-03 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 a9d7a0107a45f..cb8a524ee13c5 100644 --- a/api_docs/kbn_core_usage_data_server_internal.mdx +++ b/api_docs/kbn_core_usage_data_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-usage-data-server-internal title: "@kbn/core-usage-data-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-usage-data-server-internal plugin -date: 2024-11-29 +date: 2024-12-03 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 45623b10af2ab..0d4fae499ec4e 100644 --- a/api_docs/kbn_core_usage_data_server_mocks.mdx +++ b/api_docs/kbn_core_usage_data_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-usage-data-server-mocks title: "@kbn/core-usage-data-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-usage-data-server-mocks plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-usage-data-server-mocks'] --- import kbnCoreUsageDataServerMocksObj from './kbn_core_usage_data_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_user_profile_browser.mdx b/api_docs/kbn_core_user_profile_browser.mdx index 31baff7d84ae4..c1fcd5b094ccc 100644 --- a/api_docs/kbn_core_user_profile_browser.mdx +++ b/api_docs/kbn_core_user_profile_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-profile-browser title: "@kbn/core-user-profile-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-profile-browser plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-user-profile-browser'] --- import kbnCoreUserProfileBrowserObj from './kbn_core_user_profile_browser.devdocs.json'; diff --git a/api_docs/kbn_core_user_profile_browser_internal.mdx b/api_docs/kbn_core_user_profile_browser_internal.mdx index 154e73344a656..bef6c0ea9803e 100644 --- a/api_docs/kbn_core_user_profile_browser_internal.mdx +++ b/api_docs/kbn_core_user_profile_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-profile-browser-internal title: "@kbn/core-user-profile-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-profile-browser-internal plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-user-profile-browser-internal'] --- import kbnCoreUserProfileBrowserInternalObj from './kbn_core_user_profile_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_user_profile_browser_mocks.mdx b/api_docs/kbn_core_user_profile_browser_mocks.mdx index 82eb28c459c28..4d890925ee072 100644 --- a/api_docs/kbn_core_user_profile_browser_mocks.mdx +++ b/api_docs/kbn_core_user_profile_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-profile-browser-mocks title: "@kbn/core-user-profile-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-profile-browser-mocks plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-user-profile-browser-mocks'] --- import kbnCoreUserProfileBrowserMocksObj from './kbn_core_user_profile_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_user_profile_common.mdx b/api_docs/kbn_core_user_profile_common.mdx index 64b7a3cb27bd2..b39634e1c9b6a 100644 --- a/api_docs/kbn_core_user_profile_common.mdx +++ b/api_docs/kbn_core_user_profile_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-profile-common title: "@kbn/core-user-profile-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-profile-common plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-user-profile-common'] --- import kbnCoreUserProfileCommonObj from './kbn_core_user_profile_common.devdocs.json'; diff --git a/api_docs/kbn_core_user_profile_server.mdx b/api_docs/kbn_core_user_profile_server.mdx index e6646f7f2ee05..2c02b4fa2e39f 100644 --- a/api_docs/kbn_core_user_profile_server.mdx +++ b/api_docs/kbn_core_user_profile_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-profile-server title: "@kbn/core-user-profile-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-profile-server plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-user-profile-server'] --- import kbnCoreUserProfileServerObj from './kbn_core_user_profile_server.devdocs.json'; diff --git a/api_docs/kbn_core_user_profile_server_internal.mdx b/api_docs/kbn_core_user_profile_server_internal.mdx index 18751680350d1..198f309fb2a69 100644 --- a/api_docs/kbn_core_user_profile_server_internal.mdx +++ b/api_docs/kbn_core_user_profile_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-profile-server-internal title: "@kbn/core-user-profile-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-profile-server-internal plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-user-profile-server-internal'] --- import kbnCoreUserProfileServerInternalObj from './kbn_core_user_profile_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_user_profile_server_mocks.mdx b/api_docs/kbn_core_user_profile_server_mocks.mdx index f1b69a7956cb5..c3fc8a4dca169 100644 --- a/api_docs/kbn_core_user_profile_server_mocks.mdx +++ b/api_docs/kbn_core_user_profile_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-profile-server-mocks title: "@kbn/core-user-profile-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-profile-server-mocks plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-user-profile-server-mocks'] --- import kbnCoreUserProfileServerMocksObj from './kbn_core_user_profile_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_user_settings_server.mdx b/api_docs/kbn_core_user_settings_server.mdx index 42a2bccf1f7fb..7c4f2b3a3f3d0 100644 --- a/api_docs/kbn_core_user_settings_server.mdx +++ b/api_docs/kbn_core_user_settings_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-settings-server title: "@kbn/core-user-settings-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-settings-server plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-user-settings-server'] --- import kbnCoreUserSettingsServerObj from './kbn_core_user_settings_server.devdocs.json'; diff --git a/api_docs/kbn_core_user_settings_server_mocks.mdx b/api_docs/kbn_core_user_settings_server_mocks.mdx index ef8ce6b6a8aac..a33bf4c57ffed 100644 --- a/api_docs/kbn_core_user_settings_server_mocks.mdx +++ b/api_docs/kbn_core_user_settings_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-settings-server-mocks title: "@kbn/core-user-settings-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-settings-server-mocks plugin -date: 2024-11-29 +date: 2024-12-03 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 c45311316b99a..3cb164f04dcb3 100644 --- a/api_docs/kbn_crypto.mdx +++ b/api_docs/kbn_crypto.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-crypto title: "@kbn/crypto" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/crypto plugin -date: 2024-11-29 +date: 2024-12-03 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 d3c7c3f8b9163..d1979d3093040 100644 --- a/api_docs/kbn_crypto_browser.mdx +++ b/api_docs/kbn_crypto_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-crypto-browser title: "@kbn/crypto-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/crypto-browser plugin -date: 2024-11-29 +date: 2024-12-03 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 df9b7c52d4f5c..af91c339c9053 100644 --- a/api_docs/kbn_custom_icons.mdx +++ b/api_docs/kbn_custom_icons.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-custom-icons title: "@kbn/custom-icons" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/custom-icons plugin -date: 2024-11-29 +date: 2024-12-03 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 89ce343eb53a0..8655a577dea72 100644 --- a/api_docs/kbn_custom_integrations.mdx +++ b/api_docs/kbn_custom_integrations.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-custom-integrations title: "@kbn/custom-integrations" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/custom-integrations plugin -date: 2024-11-29 +date: 2024-12-03 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 99e5d57f34d44..3f621be4e2203 100644 --- a/api_docs/kbn_cypress_config.mdx +++ b/api_docs/kbn_cypress_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cypress-config title: "@kbn/cypress-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cypress-config plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cypress-config'] --- import kbnCypressConfigObj from './kbn_cypress_config.devdocs.json'; diff --git a/api_docs/kbn_data_forge.mdx b/api_docs/kbn_data_forge.mdx index d50d09dfa7305..2a3339618636f 100644 --- a/api_docs/kbn_data_forge.mdx +++ b/api_docs/kbn_data_forge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-data-forge title: "@kbn/data-forge" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/data-forge plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/data-forge'] --- import kbnDataForgeObj from './kbn_data_forge.devdocs.json'; diff --git a/api_docs/kbn_data_service.mdx b/api_docs/kbn_data_service.mdx index 16d694da58475..6551b2268ad04 100644 --- a/api_docs/kbn_data_service.mdx +++ b/api_docs/kbn_data_service.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-data-service title: "@kbn/data-service" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/data-service plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/data-service'] --- import kbnDataServiceObj from './kbn_data_service.devdocs.json'; diff --git a/api_docs/kbn_data_stream_adapter.mdx b/api_docs/kbn_data_stream_adapter.mdx index e96482d6db46a..ebb7346d96d6d 100644 --- a/api_docs/kbn_data_stream_adapter.mdx +++ b/api_docs/kbn_data_stream_adapter.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-data-stream-adapter title: "@kbn/data-stream-adapter" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/data-stream-adapter plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/data-stream-adapter'] --- import kbnDataStreamAdapterObj from './kbn_data_stream_adapter.devdocs.json'; diff --git a/api_docs/kbn_data_view_utils.mdx b/api_docs/kbn_data_view_utils.mdx index c503df11420f9..79a9c2dbb7b0d 100644 --- a/api_docs/kbn_data_view_utils.mdx +++ b/api_docs/kbn_data_view_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-data-view-utils title: "@kbn/data-view-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/data-view-utils plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/data-view-utils'] --- import kbnDataViewUtilsObj from './kbn_data_view_utils.devdocs.json'; diff --git a/api_docs/kbn_datemath.mdx b/api_docs/kbn_datemath.mdx index 161148ade8af3..1455bf677aff7 100644 --- a/api_docs/kbn_datemath.mdx +++ b/api_docs/kbn_datemath.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-datemath title: "@kbn/datemath" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/datemath plugin -date: 2024-11-29 +date: 2024-12-03 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 a5480a8a94c9d..b65be683d9a4c 100644 --- a/api_docs/kbn_deeplinks_analytics.mdx +++ b/api_docs/kbn_deeplinks_analytics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-analytics title: "@kbn/deeplinks-analytics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-analytics plugin -date: 2024-11-29 +date: 2024-12-03 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 e48200722a0b8..54539c3301c12 100644 --- a/api_docs/kbn_deeplinks_devtools.mdx +++ b/api_docs/kbn_deeplinks_devtools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-devtools title: "@kbn/deeplinks-devtools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-devtools plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-devtools'] --- import kbnDeeplinksDevtoolsObj from './kbn_deeplinks_devtools.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_fleet.mdx b/api_docs/kbn_deeplinks_fleet.mdx index f7946395c942c..d3b9bb051e83e 100644 --- a/api_docs/kbn_deeplinks_fleet.mdx +++ b/api_docs/kbn_deeplinks_fleet.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-fleet title: "@kbn/deeplinks-fleet" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-fleet plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-fleet'] --- import kbnDeeplinksFleetObj from './kbn_deeplinks_fleet.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_management.mdx b/api_docs/kbn_deeplinks_management.mdx index 7d68ec2d0d214..7ae3d99853bde 100644 --- a/api_docs/kbn_deeplinks_management.mdx +++ b/api_docs/kbn_deeplinks_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-management title: "@kbn/deeplinks-management" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-management plugin -date: 2024-11-29 +date: 2024-12-03 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 77a955327cde9..a6b5fa3abb5b7 100644 --- a/api_docs/kbn_deeplinks_ml.mdx +++ b/api_docs/kbn_deeplinks_ml.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-ml title: "@kbn/deeplinks-ml" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-ml plugin -date: 2024-11-29 +date: 2024-12-03 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 465e0da4de22b..af6d377e013d9 100644 --- a/api_docs/kbn_deeplinks_observability.mdx +++ b/api_docs/kbn_deeplinks_observability.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-observability title: "@kbn/deeplinks-observability" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-observability plugin -date: 2024-11-29 +date: 2024-12-03 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 4aa29de243a74..1a2a2cd9ef0ce 100644 --- a/api_docs/kbn_deeplinks_search.mdx +++ b/api_docs/kbn_deeplinks_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-search title: "@kbn/deeplinks-search" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-search plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-search'] --- import kbnDeeplinksSearchObj from './kbn_deeplinks_search.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_security.mdx b/api_docs/kbn_deeplinks_security.mdx index f55a80c473b06..c54c298706262 100644 --- a/api_docs/kbn_deeplinks_security.mdx +++ b/api_docs/kbn_deeplinks_security.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-security title: "@kbn/deeplinks-security" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-security plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-security'] --- import kbnDeeplinksSecurityObj from './kbn_deeplinks_security.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_shared.mdx b/api_docs/kbn_deeplinks_shared.mdx index 915bce8c2ae23..1539a457301ec 100644 --- a/api_docs/kbn_deeplinks_shared.mdx +++ b/api_docs/kbn_deeplinks_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-shared title: "@kbn/deeplinks-shared" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-shared plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-shared'] --- import kbnDeeplinksSharedObj from './kbn_deeplinks_shared.devdocs.json'; diff --git a/api_docs/kbn_default_nav_analytics.mdx b/api_docs/kbn_default_nav_analytics.mdx index 8dfcce249612b..a504eacb588bf 100644 --- a/api_docs/kbn_default_nav_analytics.mdx +++ b/api_docs/kbn_default_nav_analytics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-default-nav-analytics title: "@kbn/default-nav-analytics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/default-nav-analytics plugin -date: 2024-11-29 +date: 2024-12-03 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 ce4e4aeed92ff..d3b5f84e66789 100644 --- a/api_docs/kbn_default_nav_devtools.mdx +++ b/api_docs/kbn_default_nav_devtools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-default-nav-devtools title: "@kbn/default-nav-devtools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/default-nav-devtools plugin -date: 2024-11-29 +date: 2024-12-03 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 7e8a428bf89d3..c3a20a08c0dd5 100644 --- a/api_docs/kbn_default_nav_management.mdx +++ b/api_docs/kbn_default_nav_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-default-nav-management title: "@kbn/default-nav-management" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/default-nav-management plugin -date: 2024-11-29 +date: 2024-12-03 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 73e501c2e7bfa..f24a7c9a93bf8 100644 --- a/api_docs/kbn_default_nav_ml.mdx +++ b/api_docs/kbn_default_nav_ml.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-default-nav-ml title: "@kbn/default-nav-ml" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/default-nav-ml plugin -date: 2024-11-29 +date: 2024-12-03 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 82bcac4737509..54aa8ae5d2c5c 100644 --- a/api_docs/kbn_dev_cli_errors.mdx +++ b/api_docs/kbn_dev_cli_errors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-cli-errors title: "@kbn/dev-cli-errors" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-cli-errors plugin -date: 2024-11-29 +date: 2024-12-03 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 f9c3d9a0f648b..3883f9059ea02 100644 --- a/api_docs/kbn_dev_cli_runner.mdx +++ b/api_docs/kbn_dev_cli_runner.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-cli-runner title: "@kbn/dev-cli-runner" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-cli-runner plugin -date: 2024-11-29 +date: 2024-12-03 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 cc7858b837b00..2701e447f13f2 100644 --- a/api_docs/kbn_dev_proc_runner.mdx +++ b/api_docs/kbn_dev_proc_runner.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-proc-runner title: "@kbn/dev-proc-runner" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-proc-runner plugin -date: 2024-11-29 +date: 2024-12-03 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 248d5589d1aed..c20cd17c10d5d 100644 --- a/api_docs/kbn_dev_utils.mdx +++ b/api_docs/kbn_dev_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-utils title: "@kbn/dev-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-utils plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-utils'] --- import kbnDevUtilsObj from './kbn_dev_utils.devdocs.json'; diff --git a/api_docs/kbn_discover_contextual_components.mdx b/api_docs/kbn_discover_contextual_components.mdx index 178b8cec6be4a..399c8f63e9e85 100644 --- a/api_docs/kbn_discover_contextual_components.mdx +++ b/api_docs/kbn_discover_contextual_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-discover-contextual-components title: "@kbn/discover-contextual-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/discover-contextual-components plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/discover-contextual-components'] --- import kbnDiscoverContextualComponentsObj from './kbn_discover_contextual_components.devdocs.json'; diff --git a/api_docs/kbn_discover_utils.mdx b/api_docs/kbn_discover_utils.mdx index 4b0ff81bcef35..575c61a63f7bc 100644 --- a/api_docs/kbn_discover_utils.mdx +++ b/api_docs/kbn_discover_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-discover-utils title: "@kbn/discover-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/discover-utils plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/discover-utils'] --- import kbnDiscoverUtilsObj from './kbn_discover_utils.devdocs.json'; diff --git a/api_docs/kbn_doc_links.mdx b/api_docs/kbn_doc_links.mdx index 0679ecb2c47af..35e2126df6ab7 100644 --- a/api_docs/kbn_doc_links.mdx +++ b/api_docs/kbn_doc_links.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-doc-links title: "@kbn/doc-links" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/doc-links plugin -date: 2024-11-29 +date: 2024-12-03 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 6418b8515ceed..c986a79cd2119 100644 --- a/api_docs/kbn_docs_utils.mdx +++ b/api_docs/kbn_docs_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-docs-utils title: "@kbn/docs-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/docs-utils plugin -date: 2024-11-29 +date: 2024-12-03 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 9a1f0b33bfb8f..b8416c3ddc464 100644 --- a/api_docs/kbn_dom_drag_drop.mdx +++ b/api_docs/kbn_dom_drag_drop.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dom-drag-drop title: "@kbn/dom-drag-drop" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dom-drag-drop plugin -date: 2024-11-29 +date: 2024-12-03 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 0549c7004a367..1c566e0da9228 100644 --- a/api_docs/kbn_ebt_tools.mdx +++ b/api_docs/kbn_ebt_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ebt-tools title: "@kbn/ebt-tools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ebt-tools plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ebt-tools'] --- import kbnEbtToolsObj from './kbn_ebt_tools.devdocs.json'; diff --git a/api_docs/kbn_ecs_data_quality_dashboard.mdx b/api_docs/kbn_ecs_data_quality_dashboard.mdx index 60c8e4b7ddf98..db839b71d28b8 100644 --- a/api_docs/kbn_ecs_data_quality_dashboard.mdx +++ b/api_docs/kbn_ecs_data_quality_dashboard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ecs-data-quality-dashboard title: "@kbn/ecs-data-quality-dashboard" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ecs-data-quality-dashboard plugin -date: 2024-11-29 +date: 2024-12-03 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 eaec352891de6..f9337eea4a0ef 100644 --- a/api_docs/kbn_elastic_agent_utils.mdx +++ b/api_docs/kbn_elastic_agent_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-elastic-agent-utils title: "@kbn/elastic-agent-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/elastic-agent-utils plugin -date: 2024-11-29 +date: 2024-12-03 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 07731913b9f8b..96a0ddcc59cf9 100644 --- a/api_docs/kbn_elastic_assistant.mdx +++ b/api_docs/kbn_elastic_assistant.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-elastic-assistant title: "@kbn/elastic-assistant" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/elastic-assistant plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/elastic-assistant'] --- import kbnElasticAssistantObj from './kbn_elastic_assistant.devdocs.json'; diff --git a/api_docs/kbn_elastic_assistant_common.mdx b/api_docs/kbn_elastic_assistant_common.mdx index 009df2a2bf02e..7d8c4aca6ae58 100644 --- a/api_docs/kbn_elastic_assistant_common.mdx +++ b/api_docs/kbn_elastic_assistant_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-elastic-assistant-common title: "@kbn/elastic-assistant-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/elastic-assistant-common plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/elastic-assistant-common'] --- import kbnElasticAssistantCommonObj from './kbn_elastic_assistant_common.devdocs.json'; diff --git a/api_docs/kbn_entities_schema.devdocs.json b/api_docs/kbn_entities_schema.devdocs.json index 5bc7ba4f31a9f..0269efb5711d8 100644 --- a/api_docs/kbn_entities_schema.devdocs.json +++ b/api_docs/kbn_entities_schema.devdocs.json @@ -144,10 +144,10 @@ }, { "parentPluginId": "@kbn/entities-schema", - "id": "def-common.EntityV2.entity.last_seen_timestamp", + "id": "def-common.EntityV2.entity.type", "type": "string", "tags": [], - "label": "'entity.last_seen_timestamp'", + "label": "'entity.type'", "description": [], "path": "x-pack/packages/kbn-entities-schema/src/schema/entity.ts", "deprecated": false, @@ -155,15 +155,29 @@ }, { "parentPluginId": "@kbn/entities-schema", - "id": "def-common.EntityV2.entity.type", + "id": "def-common.EntityV2.entity.display_name", "type": "string", "tags": [], - "label": "'entity.type'", + "label": "'entity.display_name'", "description": [], "path": "x-pack/packages/kbn-entities-schema/src/schema/entity.ts", "deprecated": false, "trackAdoption": false }, + { + "parentPluginId": "@kbn/entities-schema", + "id": "def-common.EntityV2.entity.last_seen_timestamp", + "type": "string", + "tags": [], + "label": "'entity.last_seen_timestamp'", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "x-pack/packages/kbn-entities-schema/src/schema/entity.ts", + "deprecated": false, + "trackAdoption": false + }, { "parentPluginId": "@kbn/entities-schema", "id": "def-common.EntityV2.Unnamed", diff --git a/api_docs/kbn_entities_schema.mdx b/api_docs/kbn_entities_schema.mdx index 1fdfc24f73a16..44f3602c6853b 100644 --- a/api_docs/kbn_entities_schema.mdx +++ b/api_docs/kbn_entities_schema.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-entities-schema title: "@kbn/entities-schema" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/entities-schema plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/entities-schema'] --- import kbnEntitiesSchemaObj from './kbn_entities_schema.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/obs-entities](https://github.com/orgs/elastic/teams/obs-entiti | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 50 | 0 | 50 | 0 | +| 51 | 0 | 51 | 0 | ## Common diff --git a/api_docs/kbn_es.mdx b/api_docs/kbn_es.mdx index ff5a0e55d3785..a5b21a5246807 100644 --- a/api_docs/kbn_es.mdx +++ b/api_docs/kbn_es.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es title: "@kbn/es" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es plugin -date: 2024-11-29 +date: 2024-12-03 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 ee7df4f3b4292..08056225d1035 100644 --- a/api_docs/kbn_es_archiver.mdx +++ b/api_docs/kbn_es_archiver.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-archiver title: "@kbn/es-archiver" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-archiver plugin -date: 2024-11-29 +date: 2024-12-03 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 376bd72e43b16..103cdb4662ab2 100644 --- a/api_docs/kbn_es_errors.mdx +++ b/api_docs/kbn_es_errors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-errors title: "@kbn/es-errors" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-errors plugin -date: 2024-11-29 +date: 2024-12-03 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 b246670d184c6..0a2ccb86bd955 100644 --- a/api_docs/kbn_es_query.mdx +++ b/api_docs/kbn_es_query.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-query title: "@kbn/es-query" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-query plugin -date: 2024-11-29 +date: 2024-12-03 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 9476011a57c4a..91d3926517788 100644 --- a/api_docs/kbn_es_types.mdx +++ b/api_docs/kbn_es_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-types title: "@kbn/es-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-types plugin -date: 2024-11-29 +date: 2024-12-03 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 b869c12ff0c2d..7d28e5b2815ff 100644 --- a/api_docs/kbn_eslint_plugin_imports.mdx +++ b/api_docs/kbn_eslint_plugin_imports.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-eslint-plugin-imports title: "@kbn/eslint-plugin-imports" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/eslint-plugin-imports plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/eslint-plugin-imports'] --- import kbnEslintPluginImportsObj from './kbn_eslint_plugin_imports.devdocs.json'; diff --git a/api_docs/kbn_esql_ast.devdocs.json b/api_docs/kbn_esql_ast.devdocs.json index f2d113ae788eb..bf0442c6badd7 100644 --- a/api_docs/kbn_esql_ast.devdocs.json +++ b/api_docs/kbn_esql_ast.devdocs.json @@ -282,13 +282,7 @@ "description": [], "signature": [ "(expression: ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ", opts?: ", { "pluginId": "@kbn/esql-ast", @@ -313,13 +307,7 @@ "ES|QL expression AST node to print." ], "signature": [ - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - } + "ESQLAstExpression" ], "path": "packages/kbn-esql-ast/src/pretty_print/basic_pretty_printer.ts", "deprecated": false, @@ -496,13 +484,7 @@ "description": [], "signature": [ "(node: ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ", minusCount?: number) => string | undefined" ], "path": "packages/kbn-esql-ast/src/pretty_print/basic_pretty_printer.ts", @@ -517,13 +499,7 @@ "label": "node", "description": [], "signature": [ - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - } + "ESQLAstExpression" ], "path": "packages/kbn-esql-ast/src/pretty_print/basic_pretty_printer.ts", "deprecated": false, @@ -666,13 +642,7 @@ "description": [], "signature": [ "(expression: ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ") => any" ], "path": "packages/kbn-esql-ast/src/pretty_print/basic_pretty_printer.ts", @@ -687,13 +657,7 @@ "label": "expression", "description": [], "signature": [ - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - } + "ESQLAstExpression" ], "path": "packages/kbn-esql-ast/src/pretty_print/basic_pretty_printer.ts", "deprecated": false, @@ -2650,13 +2614,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -2672,13 +2630,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -2696,13 +2648,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -2718,13 +2664,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -2744,13 +2684,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -2766,13 +2700,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -2790,13 +2718,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -2812,13 +2734,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -2848,13 +2764,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -2870,13 +2780,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -2894,13 +2798,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -2916,13 +2814,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -2942,13 +2834,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -2964,13 +2850,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -2988,13 +2868,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -3010,13 +2884,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -3048,13 +2916,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -3070,13 +2932,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -3094,13 +2950,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -3116,13 +2966,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -3142,13 +2986,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -3164,13 +3002,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -3188,13 +3020,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -3210,13 +3036,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -3246,13 +3066,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -3268,13 +3082,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -3292,13 +3100,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -3314,13 +3116,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -3340,13 +3136,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -3362,13 +3152,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -3386,13 +3170,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -3408,13 +3186,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -3448,13 +3220,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -3470,13 +3236,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -3494,13 +3254,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -3516,13 +3270,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -3542,13 +3290,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -3564,13 +3306,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -3588,13 +3324,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -3610,13 +3340,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -3646,13 +3370,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -3668,13 +3386,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -3692,13 +3404,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -3714,13 +3420,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -3740,13 +3440,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -3762,13 +3456,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -3786,13 +3474,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -3808,13 +3490,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -3846,13 +3522,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -3868,13 +3538,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -3892,13 +3556,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -3914,13 +3572,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -3940,13 +3592,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -3962,13 +3608,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -3986,13 +3626,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -4008,13 +3642,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -4044,13 +3672,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -4066,13 +3688,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -4090,13 +3706,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -4112,13 +3722,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -4138,13 +3742,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -4160,13 +3758,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -4184,13 +3776,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -4206,13 +3792,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -4248,13 +3828,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -4270,13 +3844,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -4294,13 +3862,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -4316,13 +3878,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -4342,13 +3898,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -4364,13 +3914,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -4388,13 +3932,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -4410,13 +3948,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -4446,13 +3978,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -4468,13 +3994,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -4492,13 +4012,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -4514,13 +4028,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -4540,13 +4048,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -4562,13 +4064,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -4586,13 +4082,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -4608,13 +4098,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -4646,13 +4130,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -4668,13 +4146,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -4692,13 +4164,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -4714,13 +4180,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -4740,13 +4200,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -4762,13 +4216,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -4786,13 +4234,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -4808,13 +4250,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -4844,13 +4280,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -4866,13 +4296,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -4890,13 +4314,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -4912,13 +4330,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -4938,13 +4350,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -4960,13 +4366,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -4984,13 +4384,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -5006,13 +4400,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -5046,13 +4434,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -5068,13 +4450,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -5092,13 +4468,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -5114,13 +4484,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -5140,13 +4504,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -5162,13 +4520,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -5186,13 +4538,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -5208,13 +4554,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -5244,13 +4584,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -5266,13 +4600,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -5290,13 +4618,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -5312,13 +4634,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -5338,13 +4654,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -5360,13 +4670,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -5384,13 +4688,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -5406,13 +4704,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -5444,13 +4736,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -5466,13 +4752,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -5490,13 +4770,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -5512,13 +4786,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -5538,13 +4806,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -5560,13 +4822,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -5584,13 +4840,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -5606,13 +4856,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -5642,13 +4886,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -5664,13 +4902,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -5688,13 +4920,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -5710,13 +4936,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -5736,13 +4956,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -5758,13 +4972,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -5782,13 +4990,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -5804,13 +5006,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -5850,13 +5046,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -5872,13 +5062,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -5896,13 +5080,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -5918,13 +5096,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -5944,13 +5116,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -5966,13 +5132,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -5990,13 +5150,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -6012,13 +5166,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -6048,13 +5196,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -6070,13 +5212,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -6094,13 +5230,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -6116,13 +5246,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -6142,13 +5266,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -6164,13 +5282,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -6188,13 +5300,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -6210,13 +5316,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -6248,13 +5348,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -6270,13 +5364,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -6294,13 +5382,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -6316,13 +5398,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -6342,13 +5418,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -6364,13 +5434,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -6388,13 +5452,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -6410,13 +5468,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -6446,13 +5498,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -6468,13 +5514,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -6492,13 +5532,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -6514,13 +5548,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -6540,13 +5568,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -6562,13 +5584,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -6586,13 +5602,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -6608,13 +5618,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -6648,13 +5652,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -6670,13 +5668,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -6694,13 +5686,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -6716,13 +5702,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -6742,13 +5722,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -6764,13 +5738,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -6788,13 +5756,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -6810,13 +5772,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -6846,13 +5802,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -6868,13 +5818,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -6892,13 +5836,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -6914,13 +5852,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -6940,13 +5872,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -6962,13 +5888,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -6986,13 +5906,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -7008,13 +5922,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -7046,13 +5954,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -7068,13 +5970,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -7092,13 +5988,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -7114,13 +6004,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -7140,13 +6024,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -7162,13 +6040,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -7186,13 +6058,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -7208,13 +6074,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -7244,13 +6104,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -7266,13 +6120,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -7290,13 +6138,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -7312,13 +6154,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -7338,13 +6174,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -7360,13 +6190,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -7384,13 +6208,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -7406,13 +6224,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -7448,13 +6260,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -7470,13 +6276,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -7494,13 +6294,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -7516,13 +6310,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -7542,13 +6330,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -7564,13 +6346,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -7588,13 +6364,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -7610,13 +6380,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -7646,13 +6410,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -7668,13 +6426,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -7692,13 +6444,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -7714,13 +6460,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -7740,13 +6480,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -7762,13 +6496,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -7786,13 +6514,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -7808,13 +6530,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -7846,13 +6562,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -7868,13 +6578,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -7892,13 +6596,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -7914,13 +6612,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -7940,13 +6632,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -7962,13 +6648,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -7986,13 +6666,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -8008,13 +6682,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -8044,13 +6712,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -8066,13 +6728,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -8090,13 +6746,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -8112,13 +6762,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -8138,13 +6782,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -8160,13 +6798,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -8184,13 +6816,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -8206,13 +6832,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -8246,13 +6866,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -8268,13 +6882,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -8292,13 +6900,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -8314,13 +6916,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -8340,13 +6936,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -8362,13 +6952,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -8386,13 +6970,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -8408,13 +6986,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -8444,13 +7016,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -8466,13 +7032,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -8490,13 +7050,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -8512,13 +7066,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -8538,13 +7086,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -8560,13 +7102,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -8584,13 +7120,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -8606,13 +7136,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -8644,13 +7168,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -8666,13 +7184,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -8690,13 +7202,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -8712,13 +7218,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -8738,13 +7238,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -8760,13 +7254,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -8784,13 +7272,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -8806,13 +7288,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -8842,13 +7318,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -8864,13 +7334,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -8888,13 +7352,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -8910,13 +7368,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -8936,13 +7388,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -8958,13 +7404,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -8982,13 +7422,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -9004,13 +7438,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -9052,13 +7480,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -9074,13 +7496,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -9098,13 +7514,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -9120,13 +7530,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -9146,13 +7550,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -9168,13 +7566,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -9192,13 +7584,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -9214,13 +7600,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -9250,13 +7630,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -9272,13 +7646,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -9296,13 +7664,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -9318,13 +7680,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -9344,13 +7700,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -9366,13 +7716,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -9390,13 +7734,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -9412,13 +7750,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -9450,13 +7782,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -9472,13 +7798,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -9496,13 +7816,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -9518,13 +7832,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -9544,13 +7852,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -9566,13 +7868,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -9590,13 +7886,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -9612,13 +7902,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -9648,13 +7932,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -9670,13 +7948,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -9694,13 +7966,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -9716,13 +7982,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -9742,13 +8002,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -9764,13 +8018,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -9788,13 +8036,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -9810,13 +8052,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -9850,13 +8086,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -9872,13 +8102,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -9896,13 +8120,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -9918,13 +8136,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -9944,13 +8156,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -9966,13 +8172,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -9990,13 +8190,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -10012,13 +8206,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -10048,13 +8236,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -10070,13 +8252,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -10094,13 +8270,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -10116,13 +8286,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -10142,13 +8306,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -10164,13 +8322,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -10188,13 +8340,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -10210,13 +8356,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -10248,13 +8388,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -10270,13 +8404,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -10294,13 +8422,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -10316,13 +8438,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -10342,13 +8458,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -10364,13 +8474,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -10388,13 +8492,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -10410,13 +8508,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -10446,13 +8538,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -10468,13 +8554,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -10492,13 +8572,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -10514,13 +8588,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -10540,13 +8608,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -10562,13 +8624,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -10586,13 +8642,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -10608,13 +8658,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -10650,13 +8694,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -10672,13 +8710,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -10696,13 +8728,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -10718,13 +8744,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -10744,13 +8764,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -10766,13 +8780,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -10790,13 +8798,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -10812,13 +8814,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -10848,13 +8844,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -10870,13 +8860,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -10894,13 +8878,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -10916,13 +8894,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -10942,13 +8914,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -10964,13 +8930,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -10988,13 +8948,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -11010,13 +8964,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -11048,13 +8996,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -11070,13 +9012,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -11094,13 +9030,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -11116,13 +9046,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -11142,13 +9066,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -11164,13 +9082,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -11188,13 +9100,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -11210,13 +9116,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -11246,13 +9146,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -11268,13 +9162,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -11292,13 +9180,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -11314,13 +9196,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -11340,13 +9216,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -11362,13 +9232,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -11386,13 +9250,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -11408,13 +9266,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -11448,13 +9300,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -11470,13 +9316,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -11494,13 +9334,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -11516,13 +9350,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -11542,13 +9370,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -11564,13 +9386,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -11588,13 +9404,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -11610,13 +9420,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -11646,13 +9450,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -11668,13 +9466,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -11692,13 +9484,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -11714,13 +9500,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -11740,13 +9520,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -11762,13 +9536,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -11786,13 +9554,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -11808,13 +9570,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -11846,13 +9602,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -11868,13 +9618,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -11892,13 +9636,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -11914,13 +9652,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -11940,13 +9672,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -11962,13 +9688,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -11986,13 +9706,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -12008,13 +9722,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -12044,13 +9752,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -12066,13 +9768,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -12090,13 +9786,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -12112,13 +9802,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -12138,13 +9822,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -12160,13 +9838,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -12184,13 +9856,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -12206,13 +9872,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -12252,13 +9912,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -12274,13 +9928,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -12298,13 +9946,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -12320,13 +9962,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -12346,13 +9982,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -12368,13 +9998,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -12392,13 +10016,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -12414,13 +10032,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -12450,13 +10062,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -12472,13 +10078,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -12496,13 +10096,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -12518,13 +10112,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -12544,13 +10132,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -12566,13 +10148,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -12590,13 +10166,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -12612,13 +10182,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -12650,13 +10214,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -12672,13 +10230,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -12696,13 +10248,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -12718,13 +10264,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -12744,13 +10284,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -12766,13 +10300,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -12790,13 +10318,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -12812,13 +10334,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -12848,13 +10364,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -12870,13 +10380,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -12894,13 +10398,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -12916,13 +10414,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -12942,13 +10434,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -12964,13 +10450,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -12988,13 +10468,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -13010,13 +10484,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -13050,13 +10518,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -13072,13 +10534,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -13096,13 +10552,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -13118,13 +10568,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -13144,13 +10588,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -13166,13 +10604,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -13190,13 +10622,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -13212,13 +10638,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -13248,13 +10668,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -13270,13 +10684,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -13294,13 +10702,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -13316,13 +10718,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -13342,13 +10738,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -13364,13 +10754,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -13388,13 +10772,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -13410,13 +10788,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -13448,13 +10820,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -13470,13 +10836,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -13494,13 +10854,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -13516,13 +10870,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -13542,13 +10890,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -13564,13 +10906,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -13588,13 +10924,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -13610,13 +10940,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -13646,13 +10970,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -13668,13 +10986,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -13692,13 +11004,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -13714,13 +11020,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -13740,13 +11040,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -13762,13 +11056,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -13786,13 +11074,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -13808,13 +11090,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -13850,13 +11126,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -13872,13 +11142,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -13896,13 +11160,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -13918,13 +11176,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -13944,13 +11196,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -13966,13 +11212,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -13990,13 +11230,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -14012,13 +11246,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -14048,13 +11276,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -14070,13 +11292,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -14094,13 +11310,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -14116,13 +11326,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -14142,13 +11346,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -14164,13 +11362,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -14188,13 +11380,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -14210,13 +11396,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -14248,13 +11428,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -14270,13 +11444,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -14294,13 +11462,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -14316,13 +11478,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -14342,13 +11498,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -14364,13 +11514,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -14388,13 +11532,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -14410,13 +11548,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -14446,13 +11578,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -14468,13 +11594,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -14492,13 +11612,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -14514,13 +11628,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -14540,13 +11648,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -14562,13 +11664,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -14586,13 +11682,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -14608,13 +11698,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -14648,13 +11732,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -14670,13 +11748,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -14694,13 +11766,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -14716,13 +11782,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -14742,13 +11802,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -14764,13 +11818,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -14788,13 +11836,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -14810,13 +11852,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -14846,13 +11882,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -14868,13 +11898,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -14892,13 +11916,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -14914,13 +11932,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -14940,13 +11952,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -14962,13 +11968,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -14986,13 +11986,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -15008,13 +12002,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -15046,13 +12034,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -15068,13 +12050,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -15092,13 +12068,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -15114,13 +12084,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -15140,13 +12104,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -15162,13 +12120,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -15186,13 +12138,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -15208,13 +12154,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -15244,13 +12184,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -15266,13 +12200,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -15290,13 +12218,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -15312,13 +12234,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -15338,13 +12254,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -15360,13 +12270,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -15384,13 +12288,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -15406,13 +12304,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -15456,13 +12348,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -15478,13 +12364,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -15502,13 +12382,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -15524,13 +12398,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -15550,13 +12418,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -15572,13 +12434,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -15596,13 +12452,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -15618,13 +12468,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -15654,13 +12498,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -15676,13 +12514,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -15700,13 +12532,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -15722,13 +12548,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -15748,13 +12568,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -15770,13 +12584,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -15794,13 +12602,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -15813,16 +12615,10 @@ "VisitorMethods", ", ", - "SharedData", - ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + ">, ", + "SharedData", + ", ", + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -15854,13 +12650,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -15876,13 +12666,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -15900,13 +12684,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -15922,13 +12700,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -15948,13 +12720,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -15970,13 +12736,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -15994,13 +12754,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -16016,13 +12770,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -16052,13 +12800,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -16074,13 +12816,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -16098,13 +12834,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -16120,13 +12850,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -16146,13 +12870,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -16168,13 +12886,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -16192,13 +12904,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -16214,13 +12920,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -16254,13 +12954,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -16276,13 +12970,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -16300,13 +12988,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -16322,13 +13004,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -16348,13 +13024,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -16370,13 +13040,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -16394,13 +13058,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -16416,13 +13074,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -16452,13 +13104,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -16474,13 +13120,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -16498,13 +13138,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -16520,13 +13154,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -16546,13 +13174,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -16568,13 +13190,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -16592,13 +13208,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -16614,13 +13224,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -16652,13 +13256,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -16674,13 +13272,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -16698,13 +13290,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -16720,13 +13306,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -16746,13 +13326,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -16768,13 +13342,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { visitColumnExpression: (ctx: ", @@ -16792,13 +13360,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -16814,13 +13376,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; }, ", @@ -16850,13 +13406,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; } & { visitSourceExpression: (ctx: ", "SourceExpressionVisitorContext", "<", @@ -16872,13 +13422,7 @@ ">, ", "SharedData", ", ", - { - "pluginId": "@kbn/esql-ast", - "scope": "common", - "docId": "kibKbnEsqlAstPluginApi", - "section": "def-common.ESQLSingleAstItem", - "text": "ESQLSingleAstItem" - }, + "ESQLAstExpression", ">, inp: Input) => Output; }, ", "SharedData", ">, inp: Input) => Output; } & { ...; } & { ...; }, ", diff --git a/api_docs/kbn_esql_ast.mdx b/api_docs/kbn_esql_ast.mdx index 52c33525ec069..4a5f0a3e7bec0 100644 --- a/api_docs/kbn_esql_ast.mdx +++ b/api_docs/kbn_esql_ast.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-esql-ast title: "@kbn/esql-ast" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/esql-ast plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/esql-ast'] --- import kbnEsqlAstObj from './kbn_esql_ast.devdocs.json'; diff --git a/api_docs/kbn_esql_editor.mdx b/api_docs/kbn_esql_editor.mdx index d1406d5a45043..e248e4ea11ebb 100644 --- a/api_docs/kbn_esql_editor.mdx +++ b/api_docs/kbn_esql_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-esql-editor title: "@kbn/esql-editor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/esql-editor plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/esql-editor'] --- import kbnEsqlEditorObj from './kbn_esql_editor.devdocs.json'; diff --git a/api_docs/kbn_esql_utils.mdx b/api_docs/kbn_esql_utils.mdx index 2a4e2f45c2197..b0514fa934b3f 100644 --- a/api_docs/kbn_esql_utils.mdx +++ b/api_docs/kbn_esql_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-esql-utils title: "@kbn/esql-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/esql-utils plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/esql-utils'] --- import kbnEsqlUtilsObj from './kbn_esql_utils.devdocs.json'; diff --git a/api_docs/kbn_esql_validation_autocomplete.mdx b/api_docs/kbn_esql_validation_autocomplete.mdx index fa71b49c84391..88c2ac9e48182 100644 --- a/api_docs/kbn_esql_validation_autocomplete.mdx +++ b/api_docs/kbn_esql_validation_autocomplete.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-esql-validation-autocomplete title: "@kbn/esql-validation-autocomplete" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/esql-validation-autocomplete plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/esql-validation-autocomplete'] --- import kbnEsqlValidationAutocompleteObj from './kbn_esql_validation_autocomplete.devdocs.json'; diff --git a/api_docs/kbn_event_annotation_common.mdx b/api_docs/kbn_event_annotation_common.mdx index 97b3406635d54..87e1d520171bc 100644 --- a/api_docs/kbn_event_annotation_common.mdx +++ b/api_docs/kbn_event_annotation_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-event-annotation-common title: "@kbn/event-annotation-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/event-annotation-common plugin -date: 2024-11-29 +date: 2024-12-03 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 1318d7669a6b6..c19339435c2a2 100644 --- a/api_docs/kbn_event_annotation_components.mdx +++ b/api_docs/kbn_event_annotation_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-event-annotation-components title: "@kbn/event-annotation-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/event-annotation-components plugin -date: 2024-11-29 +date: 2024-12-03 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 92ff21eaf7d75..9000c27e42bba 100644 --- a/api_docs/kbn_expandable_flyout.mdx +++ b/api_docs/kbn_expandable_flyout.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-expandable-flyout title: "@kbn/expandable-flyout" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/expandable-flyout plugin -date: 2024-11-29 +date: 2024-12-03 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 c21fbe5a0c45f..918a1fcb1ab0b 100644 --- a/api_docs/kbn_field_types.mdx +++ b/api_docs/kbn_field_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-field-types title: "@kbn/field-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/field-types plugin -date: 2024-11-29 +date: 2024-12-03 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 b7345e3779ba6..ffc55a9cb0d60 100644 --- a/api_docs/kbn_field_utils.mdx +++ b/api_docs/kbn_field_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-field-utils title: "@kbn/field-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/field-utils plugin -date: 2024-11-29 +date: 2024-12-03 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 7f4ab1666460c..d735227da336a 100644 --- a/api_docs/kbn_find_used_node_modules.mdx +++ b/api_docs/kbn_find_used_node_modules.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-find-used-node-modules title: "@kbn/find-used-node-modules" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/find-used-node-modules plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/find-used-node-modules'] --- import kbnFindUsedNodeModulesObj from './kbn_find_used_node_modules.devdocs.json'; diff --git a/api_docs/kbn_formatters.mdx b/api_docs/kbn_formatters.mdx index fd05c16364c89..28d8b3a1038a2 100644 --- a/api_docs/kbn_formatters.mdx +++ b/api_docs/kbn_formatters.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-formatters title: "@kbn/formatters" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/formatters plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/formatters'] --- import kbnFormattersObj from './kbn_formatters.devdocs.json'; diff --git a/api_docs/kbn_ftr_common_functional_services.mdx b/api_docs/kbn_ftr_common_functional_services.mdx index 362f9039fcc23..dc63d68701864 100644 --- a/api_docs/kbn_ftr_common_functional_services.mdx +++ b/api_docs/kbn_ftr_common_functional_services.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ftr-common-functional-services title: "@kbn/ftr-common-functional-services" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ftr-common-functional-services plugin -date: 2024-11-29 +date: 2024-12-03 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_ftr_common_functional_ui_services.mdx b/api_docs/kbn_ftr_common_functional_ui_services.mdx index bc878f09ab5ef..0265a519eb55a 100644 --- a/api_docs/kbn_ftr_common_functional_ui_services.mdx +++ b/api_docs/kbn_ftr_common_functional_ui_services.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ftr-common-functional-ui-services title: "@kbn/ftr-common-functional-ui-services" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ftr-common-functional-ui-services plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ftr-common-functional-ui-services'] --- import kbnFtrCommonFunctionalUiServicesObj from './kbn_ftr_common_functional_ui_services.devdocs.json'; diff --git a/api_docs/kbn_generate.mdx b/api_docs/kbn_generate.mdx index c6724fc8e4771..257c25cd2d4a3 100644 --- a/api_docs/kbn_generate.mdx +++ b/api_docs/kbn_generate.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-generate title: "@kbn/generate" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/generate plugin -date: 2024-11-29 +date: 2024-12-03 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 272d0908d0875..c5dc8ad3d6c02 100644 --- a/api_docs/kbn_generate_console_definitions.mdx +++ b/api_docs/kbn_generate_console_definitions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-generate-console-definitions title: "@kbn/generate-console-definitions" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/generate-console-definitions plugin -date: 2024-11-29 +date: 2024-12-03 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 50dc7b248ca12..a607f6fda20b6 100644 --- a/api_docs/kbn_generate_csv.mdx +++ b/api_docs/kbn_generate_csv.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-generate-csv title: "@kbn/generate-csv" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/generate-csv plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate-csv'] --- import kbnGenerateCsvObj from './kbn_generate_csv.devdocs.json'; diff --git a/api_docs/kbn_grid_layout.mdx b/api_docs/kbn_grid_layout.mdx index 78fc64717fe85..3b5b2d38d288d 100644 --- a/api_docs/kbn_grid_layout.mdx +++ b/api_docs/kbn_grid_layout.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-grid-layout title: "@kbn/grid-layout" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/grid-layout plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/grid-layout'] --- import kbnGridLayoutObj from './kbn_grid_layout.devdocs.json'; diff --git a/api_docs/kbn_grouping.mdx b/api_docs/kbn_grouping.mdx index b37fd3cfc77fc..0afb988a87149 100644 --- a/api_docs/kbn_grouping.mdx +++ b/api_docs/kbn_grouping.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-grouping title: "@kbn/grouping" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/grouping plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/grouping'] --- import kbnGroupingObj from './kbn_grouping.devdocs.json'; diff --git a/api_docs/kbn_guided_onboarding.mdx b/api_docs/kbn_guided_onboarding.mdx index 273cd69edeca2..07ab2aac3453d 100644 --- a/api_docs/kbn_guided_onboarding.mdx +++ b/api_docs/kbn_guided_onboarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-guided-onboarding title: "@kbn/guided-onboarding" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/guided-onboarding plugin -date: 2024-11-29 +date: 2024-12-03 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 8412a842c1040..b0f23a50a30b6 100644 --- a/api_docs/kbn_handlebars.mdx +++ b/api_docs/kbn_handlebars.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-handlebars title: "@kbn/handlebars" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/handlebars plugin -date: 2024-11-29 +date: 2024-12-03 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 b7dd1df91f418..47a3a083c8eff 100644 --- a/api_docs/kbn_hapi_mocks.mdx +++ b/api_docs/kbn_hapi_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-hapi-mocks title: "@kbn/hapi-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/hapi-mocks plugin -date: 2024-11-29 +date: 2024-12-03 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 48872e3968659..1960482ce1873 100644 --- a/api_docs/kbn_health_gateway_server.mdx +++ b/api_docs/kbn_health_gateway_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-health-gateway-server title: "@kbn/health-gateway-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/health-gateway-server plugin -date: 2024-11-29 +date: 2024-12-03 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 9527222c744e2..6f993df67f97b 100644 --- a/api_docs/kbn_home_sample_data_card.mdx +++ b/api_docs/kbn_home_sample_data_card.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-home-sample-data-card title: "@kbn/home-sample-data-card" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/home-sample-data-card plugin -date: 2024-11-29 +date: 2024-12-03 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 68dab94ea7ddc..85a33135ef8af 100644 --- a/api_docs/kbn_home_sample_data_tab.mdx +++ b/api_docs/kbn_home_sample_data_tab.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-home-sample-data-tab title: "@kbn/home-sample-data-tab" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/home-sample-data-tab plugin -date: 2024-11-29 +date: 2024-12-03 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 783f40f5f96c5..7e04c4bc64410 100644 --- a/api_docs/kbn_i18n.mdx +++ b/api_docs/kbn_i18n.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-i18n title: "@kbn/i18n" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/i18n plugin -date: 2024-11-29 +date: 2024-12-03 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 d3e062aece582..3a1018ad2270e 100644 --- a/api_docs/kbn_i18n_react.mdx +++ b/api_docs/kbn_i18n_react.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-i18n-react title: "@kbn/i18n-react" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/i18n-react plugin -date: 2024-11-29 +date: 2024-12-03 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 97cd8297ccaf1..6ef15ebfbb5d6 100644 --- a/api_docs/kbn_import_resolver.mdx +++ b/api_docs/kbn_import_resolver.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-import-resolver title: "@kbn/import-resolver" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/import-resolver plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/import-resolver'] --- import kbnImportResolverObj from './kbn_import_resolver.devdocs.json'; diff --git a/api_docs/kbn_index_adapter.mdx b/api_docs/kbn_index_adapter.mdx index 0997baa79d5e8..d879aa0fd368d 100644 --- a/api_docs/kbn_index_adapter.mdx +++ b/api_docs/kbn_index_adapter.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-index-adapter title: "@kbn/index-adapter" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/index-adapter plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/index-adapter'] --- import kbnIndexAdapterObj from './kbn_index_adapter.devdocs.json'; diff --git a/api_docs/kbn_index_lifecycle_management_common_shared.mdx b/api_docs/kbn_index_lifecycle_management_common_shared.mdx index bbb674a835bbc..f1dde434829d9 100644 --- a/api_docs/kbn_index_lifecycle_management_common_shared.mdx +++ b/api_docs/kbn_index_lifecycle_management_common_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-index-lifecycle-management-common-shared title: "@kbn/index-lifecycle-management-common-shared" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/index-lifecycle-management-common-shared plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/index-lifecycle-management-common-shared'] --- import kbnIndexLifecycleManagementCommonSharedObj from './kbn_index_lifecycle_management_common_shared.devdocs.json'; diff --git a/api_docs/kbn_index_management_shared_types.mdx b/api_docs/kbn_index_management_shared_types.mdx index f236057da6d9b..245bfbb2b8883 100644 --- a/api_docs/kbn_index_management_shared_types.mdx +++ b/api_docs/kbn_index_management_shared_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-index-management-shared-types title: "@kbn/index-management-shared-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/index-management-shared-types plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/index-management-shared-types'] --- import kbnIndexManagementSharedTypesObj from './kbn_index_management_shared_types.devdocs.json'; diff --git a/api_docs/kbn_inference_common.mdx b/api_docs/kbn_inference_common.mdx index dd6f1fb5639c8..94da9c77efb54 100644 --- a/api_docs/kbn_inference_common.mdx +++ b/api_docs/kbn_inference_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-inference-common title: "@kbn/inference-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/inference-common plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/inference-common'] --- import kbnInferenceCommonObj from './kbn_inference_common.devdocs.json'; diff --git a/api_docs/kbn_inference_integration_flyout.mdx b/api_docs/kbn_inference_integration_flyout.mdx index c31b245a987ae..afbe1bbccd177 100644 --- a/api_docs/kbn_inference_integration_flyout.mdx +++ b/api_docs/kbn_inference_integration_flyout.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-inference_integration_flyout title: "@kbn/inference_integration_flyout" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/inference_integration_flyout plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/inference_integration_flyout'] --- import kbnInferenceIntegrationFlyoutObj from './kbn_inference_integration_flyout.devdocs.json'; diff --git a/api_docs/kbn_infra_forge.mdx b/api_docs/kbn_infra_forge.mdx index d0f73073afdea..37563b02dbf1c 100644 --- a/api_docs/kbn_infra_forge.mdx +++ b/api_docs/kbn_infra_forge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-infra-forge title: "@kbn/infra-forge" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/infra-forge plugin -date: 2024-11-29 +date: 2024-12-03 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 41b627ee00b56..a1cf8e0625a76 100644 --- a/api_docs/kbn_interpreter.mdx +++ b/api_docs/kbn_interpreter.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-interpreter title: "@kbn/interpreter" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/interpreter plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/interpreter'] --- import kbnInterpreterObj from './kbn_interpreter.devdocs.json'; diff --git a/api_docs/kbn_investigation_shared.mdx b/api_docs/kbn_investigation_shared.mdx index 6bb233ec71d2a..e15da2052ee4f 100644 --- a/api_docs/kbn_investigation_shared.mdx +++ b/api_docs/kbn_investigation_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-investigation-shared title: "@kbn/investigation-shared" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/investigation-shared plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/investigation-shared'] --- import kbnInvestigationSharedObj from './kbn_investigation_shared.devdocs.json'; diff --git a/api_docs/kbn_io_ts_utils.mdx b/api_docs/kbn_io_ts_utils.mdx index 7d100a69df8f1..7b4d6cb76c62c 100644 --- a/api_docs/kbn_io_ts_utils.mdx +++ b/api_docs/kbn_io_ts_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-io-ts-utils title: "@kbn/io-ts-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/io-ts-utils plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/io-ts-utils'] --- import kbnIoTsUtilsObj from './kbn_io_ts_utils.devdocs.json'; diff --git a/api_docs/kbn_ipynb.mdx b/api_docs/kbn_ipynb.mdx index 40376336488db..db11da137ee74 100644 --- a/api_docs/kbn_ipynb.mdx +++ b/api_docs/kbn_ipynb.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ipynb title: "@kbn/ipynb" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ipynb plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ipynb'] --- import kbnIpynbObj from './kbn_ipynb.devdocs.json'; diff --git a/api_docs/kbn_item_buffer.mdx b/api_docs/kbn_item_buffer.mdx index c84ddb933b2ad..2271ae79bfd84 100644 --- a/api_docs/kbn_item_buffer.mdx +++ b/api_docs/kbn_item_buffer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-item-buffer title: "@kbn/item-buffer" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/item-buffer plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/item-buffer'] --- import kbnItemBufferObj from './kbn_item_buffer.devdocs.json'; diff --git a/api_docs/kbn_jest_serializers.mdx b/api_docs/kbn_jest_serializers.mdx index 204cc9be85641..313c3d90e615c 100644 --- a/api_docs/kbn_jest_serializers.mdx +++ b/api_docs/kbn_jest_serializers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-jest-serializers title: "@kbn/jest-serializers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/jest-serializers plugin -date: 2024-11-29 +date: 2024-12-03 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 842fa76870c1b..cb52b76f3e656 100644 --- a/api_docs/kbn_journeys.mdx +++ b/api_docs/kbn_journeys.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-journeys title: "@kbn/journeys" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/journeys plugin -date: 2024-11-29 +date: 2024-12-03 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 e4c493b4d88c1..0bc116461cd9f 100644 --- a/api_docs/kbn_json_ast.mdx +++ b/api_docs/kbn_json_ast.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-json-ast title: "@kbn/json-ast" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/json-ast plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/json-ast'] --- import kbnJsonAstObj from './kbn_json_ast.devdocs.json'; diff --git a/api_docs/kbn_json_schemas.mdx b/api_docs/kbn_json_schemas.mdx index 6b64d30c2439c..76f1da98e7202 100644 --- a/api_docs/kbn_json_schemas.mdx +++ b/api_docs/kbn_json_schemas.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-json-schemas title: "@kbn/json-schemas" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/json-schemas plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/json-schemas'] --- import kbnJsonSchemasObj from './kbn_json_schemas.devdocs.json'; diff --git a/api_docs/kbn_kibana_manifest_schema.mdx b/api_docs/kbn_kibana_manifest_schema.mdx index 0da97df332485..5b12795dee994 100644 --- a/api_docs/kbn_kibana_manifest_schema.mdx +++ b/api_docs/kbn_kibana_manifest_schema.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-kibana-manifest-schema title: "@kbn/kibana-manifest-schema" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/kibana-manifest-schema plugin -date: 2024-11-29 +date: 2024-12-03 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.mdx b/api_docs/kbn_language_documentation.mdx index c3af766e65eba..b73082cc05537 100644 --- a/api_docs/kbn_language_documentation.mdx +++ b/api_docs/kbn_language_documentation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-language-documentation title: "@kbn/language-documentation" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/language-documentation plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/language-documentation'] --- import kbnLanguageDocumentationObj from './kbn_language_documentation.devdocs.json'; diff --git a/api_docs/kbn_lens_embeddable_utils.mdx b/api_docs/kbn_lens_embeddable_utils.mdx index b0de89432004b..4b939509b4c1b 100644 --- a/api_docs/kbn_lens_embeddable_utils.mdx +++ b/api_docs/kbn_lens_embeddable_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-lens-embeddable-utils title: "@kbn/lens-embeddable-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/lens-embeddable-utils plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/lens-embeddable-utils'] --- import kbnLensEmbeddableUtilsObj from './kbn_lens_embeddable_utils.devdocs.json'; diff --git a/api_docs/kbn_lens_formula_docs.mdx b/api_docs/kbn_lens_formula_docs.mdx index 04434c7a7c5de..7112c1008157e 100644 --- a/api_docs/kbn_lens_formula_docs.mdx +++ b/api_docs/kbn_lens_formula_docs.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-lens-formula-docs title: "@kbn/lens-formula-docs" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/lens-formula-docs plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/lens-formula-docs'] --- import kbnLensFormulaDocsObj from './kbn_lens_formula_docs.devdocs.json'; diff --git a/api_docs/kbn_logging.mdx b/api_docs/kbn_logging.mdx index 8a1657d2c27f8..8fb3be8864c78 100644 --- a/api_docs/kbn_logging.mdx +++ b/api_docs/kbn_logging.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-logging title: "@kbn/logging" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/logging plugin -date: 2024-11-29 +date: 2024-12-03 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 143238efda543..837ac4721ebce 100644 --- a/api_docs/kbn_logging_mocks.mdx +++ b/api_docs/kbn_logging_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-logging-mocks title: "@kbn/logging-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/logging-mocks plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/logging-mocks'] --- import kbnLoggingMocksObj from './kbn_logging_mocks.devdocs.json'; diff --git a/api_docs/kbn_managed_content_badge.mdx b/api_docs/kbn_managed_content_badge.mdx index d1cf6f3e07a68..dde5ec6d1a50e 100644 --- a/api_docs/kbn_managed_content_badge.mdx +++ b/api_docs/kbn_managed_content_badge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-managed-content-badge title: "@kbn/managed-content-badge" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/managed-content-badge plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/managed-content-badge'] --- import kbnManagedContentBadgeObj from './kbn_managed_content_badge.devdocs.json'; diff --git a/api_docs/kbn_managed_vscode_config.mdx b/api_docs/kbn_managed_vscode_config.mdx index 6c4e55399c3d1..55eea305678c4 100644 --- a/api_docs/kbn_managed_vscode_config.mdx +++ b/api_docs/kbn_managed_vscode_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-managed-vscode-config title: "@kbn/managed-vscode-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/managed-vscode-config plugin -date: 2024-11-29 +date: 2024-12-03 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 68f5a94d06463..2db4f527e160e 100644 --- a/api_docs/kbn_management_cards_navigation.mdx +++ b/api_docs/kbn_management_cards_navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-cards-navigation title: "@kbn/management-cards-navigation" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-cards-navigation plugin -date: 2024-11-29 +date: 2024-12-03 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 89340c8414217..5479db788c684 100644 --- a/api_docs/kbn_management_settings_application.mdx +++ b/api_docs/kbn_management_settings_application.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-application title: "@kbn/management-settings-application" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-application plugin -date: 2024-11-29 +date: 2024-12-03 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 fd9741c05931e..dc68e598b6d5e 100644 --- a/api_docs/kbn_management_settings_components_field_category.mdx +++ b/api_docs/kbn_management_settings_components_field_category.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-components-field-category title: "@kbn/management-settings-components-field-category" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-components-field-category plugin -date: 2024-11-29 +date: 2024-12-03 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 c0a6d08885d11..a1cb7fde56bb7 100644 --- a/api_docs/kbn_management_settings_components_field_input.mdx +++ b/api_docs/kbn_management_settings_components_field_input.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-components-field-input title: "@kbn/management-settings-components-field-input" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-components-field-input plugin -date: 2024-11-29 +date: 2024-12-03 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 937832113d1e7..903896f47ab4a 100644 --- a/api_docs/kbn_management_settings_components_field_row.mdx +++ b/api_docs/kbn_management_settings_components_field_row.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-components-field-row title: "@kbn/management-settings-components-field-row" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-components-field-row plugin -date: 2024-11-29 +date: 2024-12-03 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 e7770efcb0d70..23f6c111f9358 100644 --- a/api_docs/kbn_management_settings_components_form.mdx +++ b/api_docs/kbn_management_settings_components_form.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-components-form title: "@kbn/management-settings-components-form" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-components-form plugin -date: 2024-11-29 +date: 2024-12-03 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 c824020522707..775a385a0c4fb 100644 --- a/api_docs/kbn_management_settings_field_definition.mdx +++ b/api_docs/kbn_management_settings_field_definition.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-field-definition title: "@kbn/management-settings-field-definition" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-field-definition plugin -date: 2024-11-29 +date: 2024-12-03 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 6415a0f5ab9fd..68f7d07837e9a 100644 --- a/api_docs/kbn_management_settings_ids.mdx +++ b/api_docs/kbn_management_settings_ids.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-ids title: "@kbn/management-settings-ids" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-ids plugin -date: 2024-11-29 +date: 2024-12-03 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 0e0129eb8b7c3..302b3f5520e86 100644 --- a/api_docs/kbn_management_settings_section_registry.mdx +++ b/api_docs/kbn_management_settings_section_registry.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-section-registry title: "@kbn/management-settings-section-registry" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-section-registry plugin -date: 2024-11-29 +date: 2024-12-03 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 35fdd672660de..be056860418a8 100644 --- a/api_docs/kbn_management_settings_types.mdx +++ b/api_docs/kbn_management_settings_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-types title: "@kbn/management-settings-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-types plugin -date: 2024-11-29 +date: 2024-12-03 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 dd3e251f15d87..a0dd4ed2bfaca 100644 --- a/api_docs/kbn_management_settings_utilities.mdx +++ b/api_docs/kbn_management_settings_utilities.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-utilities title: "@kbn/management-settings-utilities" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-utilities plugin -date: 2024-11-29 +date: 2024-12-03 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 970a239ba28bf..58f02befefd12 100644 --- a/api_docs/kbn_management_storybook_config.mdx +++ b/api_docs/kbn_management_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-storybook-config title: "@kbn/management-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-storybook-config plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-storybook-config'] --- import kbnManagementStorybookConfigObj from './kbn_management_storybook_config.devdocs.json'; diff --git a/api_docs/kbn_manifest.mdx b/api_docs/kbn_manifest.mdx index 4210ec64ba509..b4c1a7d344d99 100644 --- a/api_docs/kbn_manifest.mdx +++ b/api_docs/kbn_manifest.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-manifest title: "@kbn/manifest" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/manifest plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/manifest'] --- import kbnManifestObj from './kbn_manifest.devdocs.json'; diff --git a/api_docs/kbn_mapbox_gl.mdx b/api_docs/kbn_mapbox_gl.mdx index ca9f19dd79721..417cef0255309 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: 2024-11-29 +date: 2024-12-03 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 b7c04b5908234..aa7a2b00efa36 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: 2024-11-29 +date: 2024-12-03 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 39262e447d6bc..c798d2a14dbf1 100644 --- a/api_docs/kbn_ml_agg_utils.mdx +++ b/api_docs/kbn_ml_agg_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-agg-utils title: "@kbn/ml-agg-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-agg-utils plugin -date: 2024-11-29 +date: 2024-12-03 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 8421aed8705b3..5c04c5bf3c7e8 100644 --- a/api_docs/kbn_ml_anomaly_utils.mdx +++ b/api_docs/kbn_ml_anomaly_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-anomaly-utils title: "@kbn/ml-anomaly-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-anomaly-utils plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-anomaly-utils'] --- import kbnMlAnomalyUtilsObj from './kbn_ml_anomaly_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_cancellable_search.mdx b/api_docs/kbn_ml_cancellable_search.mdx index e8a26b83e81ae..bccf9871bb700 100644 --- a/api_docs/kbn_ml_cancellable_search.mdx +++ b/api_docs/kbn_ml_cancellable_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-cancellable-search title: "@kbn/ml-cancellable-search" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-cancellable-search plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-cancellable-search'] --- import kbnMlCancellableSearchObj from './kbn_ml_cancellable_search.devdocs.json'; diff --git a/api_docs/kbn_ml_category_validator.mdx b/api_docs/kbn_ml_category_validator.mdx index 2548c1163e235..7049fb1c993cb 100644 --- a/api_docs/kbn_ml_category_validator.mdx +++ b/api_docs/kbn_ml_category_validator.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-category-validator title: "@kbn/ml-category-validator" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-category-validator plugin -date: 2024-11-29 +date: 2024-12-03 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 4e54e643470fb..c7a672f0a9bf8 100644 --- a/api_docs/kbn_ml_chi2test.mdx +++ b/api_docs/kbn_ml_chi2test.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-chi2test title: "@kbn/ml-chi2test" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-chi2test plugin -date: 2024-11-29 +date: 2024-12-03 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 fba31f06293bc..a510a28e70f18 100644 --- a/api_docs/kbn_ml_data_frame_analytics_utils.mdx +++ b/api_docs/kbn_ml_data_frame_analytics_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-data-frame-analytics-utils title: "@kbn/ml-data-frame-analytics-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-data-frame-analytics-utils plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-data-frame-analytics-utils'] --- import kbnMlDataFrameAnalyticsUtilsObj from './kbn_ml_data_frame_analytics_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_data_grid.mdx b/api_docs/kbn_ml_data_grid.mdx index 7021c51e0893f..328d8ab43cad0 100644 --- a/api_docs/kbn_ml_data_grid.mdx +++ b/api_docs/kbn_ml_data_grid.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-data-grid title: "@kbn/ml-data-grid" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-data-grid plugin -date: 2024-11-29 +date: 2024-12-03 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 5e2f4baf60a14..20ed3d344ff0c 100644 --- a/api_docs/kbn_ml_date_picker.mdx +++ b/api_docs/kbn_ml_date_picker.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-date-picker title: "@kbn/ml-date-picker" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-date-picker plugin -date: 2024-11-29 +date: 2024-12-03 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 551d6269dec26..2ccc1a8d0ca3e 100644 --- a/api_docs/kbn_ml_date_utils.mdx +++ b/api_docs/kbn_ml_date_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-date-utils title: "@kbn/ml-date-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-date-utils plugin -date: 2024-11-29 +date: 2024-12-03 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 dfc0e4ad9d301..0f14619eea8d5 100644 --- a/api_docs/kbn_ml_error_utils.mdx +++ b/api_docs/kbn_ml_error_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-error-utils title: "@kbn/ml-error-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-error-utils plugin -date: 2024-11-29 +date: 2024-12-03 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_field_stats_flyout.mdx b/api_docs/kbn_ml_field_stats_flyout.mdx index 3a9d7de5eee9f..7ca2933d42708 100644 --- a/api_docs/kbn_ml_field_stats_flyout.mdx +++ b/api_docs/kbn_ml_field_stats_flyout.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-field-stats-flyout title: "@kbn/ml-field-stats-flyout" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-field-stats-flyout plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-field-stats-flyout'] --- import kbnMlFieldStatsFlyoutObj from './kbn_ml_field_stats_flyout.devdocs.json'; diff --git a/api_docs/kbn_ml_in_memory_table.mdx b/api_docs/kbn_ml_in_memory_table.mdx index 472cd6a0a6790..fca65dac63dcc 100644 --- a/api_docs/kbn_ml_in_memory_table.mdx +++ b/api_docs/kbn_ml_in_memory_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-in-memory-table title: "@kbn/ml-in-memory-table" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-in-memory-table plugin -date: 2024-11-29 +date: 2024-12-03 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 f0c90468348a2..67d0e11795de5 100644 --- a/api_docs/kbn_ml_is_defined.mdx +++ b/api_docs/kbn_ml_is_defined.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-is-defined title: "@kbn/ml-is-defined" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-is-defined plugin -date: 2024-11-29 +date: 2024-12-03 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 be1de7fa845b7..eb3713848a0b7 100644 --- a/api_docs/kbn_ml_is_populated_object.mdx +++ b/api_docs/kbn_ml_is_populated_object.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-is-populated-object title: "@kbn/ml-is-populated-object" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-is-populated-object plugin -date: 2024-11-29 +date: 2024-12-03 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 16e4e047f2863..0432c75446ce3 100644 --- a/api_docs/kbn_ml_kibana_theme.mdx +++ b/api_docs/kbn_ml_kibana_theme.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-kibana-theme title: "@kbn/ml-kibana-theme" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-kibana-theme plugin -date: 2024-11-29 +date: 2024-12-03 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 769ad142f6950..0c03b4334e57e 100644 --- a/api_docs/kbn_ml_local_storage.mdx +++ b/api_docs/kbn_ml_local_storage.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-local-storage title: "@kbn/ml-local-storage" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-local-storage plugin -date: 2024-11-29 +date: 2024-12-03 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 788a48622ed37..383213651c64b 100644 --- a/api_docs/kbn_ml_nested_property.mdx +++ b/api_docs/kbn_ml_nested_property.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-nested-property title: "@kbn/ml-nested-property" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-nested-property plugin -date: 2024-11-29 +date: 2024-12-03 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 a83df02d2f101..4e51d1d0009d9 100644 --- a/api_docs/kbn_ml_number_utils.mdx +++ b/api_docs/kbn_ml_number_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-number-utils title: "@kbn/ml-number-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-number-utils plugin -date: 2024-11-29 +date: 2024-12-03 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_parse_interval.mdx b/api_docs/kbn_ml_parse_interval.mdx index 289ab959d0a5d..79776bb90c849 100644 --- a/api_docs/kbn_ml_parse_interval.mdx +++ b/api_docs/kbn_ml_parse_interval.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-parse-interval title: "@kbn/ml-parse-interval" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-parse-interval plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-parse-interval'] --- import kbnMlParseIntervalObj from './kbn_ml_parse_interval.devdocs.json'; diff --git a/api_docs/kbn_ml_query_utils.mdx b/api_docs/kbn_ml_query_utils.mdx index 37b8f9fc2126d..f70ee2016d1f5 100644 --- a/api_docs/kbn_ml_query_utils.mdx +++ b/api_docs/kbn_ml_query_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-query-utils title: "@kbn/ml-query-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-query-utils plugin -date: 2024-11-29 +date: 2024-12-03 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 0c2e3b9fe2cec..41c0612f70e10 100644 --- a/api_docs/kbn_ml_random_sampler_utils.mdx +++ b/api_docs/kbn_ml_random_sampler_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-random-sampler-utils title: "@kbn/ml-random-sampler-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-random-sampler-utils plugin -date: 2024-11-29 +date: 2024-12-03 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 62c583cabb0ca..a77f77c57730e 100644 --- a/api_docs/kbn_ml_route_utils.mdx +++ b/api_docs/kbn_ml_route_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-route-utils title: "@kbn/ml-route-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-route-utils plugin -date: 2024-11-29 +date: 2024-12-03 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 b1b5f9bd75536..96cac2b534741 100644 --- a/api_docs/kbn_ml_runtime_field_utils.mdx +++ b/api_docs/kbn_ml_runtime_field_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-runtime-field-utils title: "@kbn/ml-runtime-field-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-runtime-field-utils plugin -date: 2024-11-29 +date: 2024-12-03 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 acc48b939c50e..645d4beed457c 100644 --- a/api_docs/kbn_ml_string_hash.mdx +++ b/api_docs/kbn_ml_string_hash.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-string-hash title: "@kbn/ml-string-hash" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-string-hash plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-string-hash'] --- import kbnMlStringHashObj from './kbn_ml_string_hash.devdocs.json'; diff --git a/api_docs/kbn_ml_time_buckets.mdx b/api_docs/kbn_ml_time_buckets.mdx index d7f9f0181364e..fbc302a9d09dd 100644 --- a/api_docs/kbn_ml_time_buckets.mdx +++ b/api_docs/kbn_ml_time_buckets.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-time-buckets title: "@kbn/ml-time-buckets" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-time-buckets plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-time-buckets'] --- import kbnMlTimeBucketsObj from './kbn_ml_time_buckets.devdocs.json'; diff --git a/api_docs/kbn_ml_trained_models_utils.mdx b/api_docs/kbn_ml_trained_models_utils.mdx index 85eda3fc5f196..817cc7be8687c 100644 --- a/api_docs/kbn_ml_trained_models_utils.mdx +++ b/api_docs/kbn_ml_trained_models_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-trained-models-utils title: "@kbn/ml-trained-models-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-trained-models-utils plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-trained-models-utils'] --- import kbnMlTrainedModelsUtilsObj from './kbn_ml_trained_models_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_ui_actions.mdx b/api_docs/kbn_ml_ui_actions.mdx index f08a258e38dff..0eeb89193d1b0 100644 --- a/api_docs/kbn_ml_ui_actions.mdx +++ b/api_docs/kbn_ml_ui_actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-ui-actions title: "@kbn/ml-ui-actions" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-ui-actions plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-ui-actions'] --- import kbnMlUiActionsObj from './kbn_ml_ui_actions.devdocs.json'; diff --git a/api_docs/kbn_ml_url_state.mdx b/api_docs/kbn_ml_url_state.mdx index c1d7f8bcda3ce..dee866819cc94 100644 --- a/api_docs/kbn_ml_url_state.mdx +++ b/api_docs/kbn_ml_url_state.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-url-state title: "@kbn/ml-url-state" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-url-state plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-url-state'] --- import kbnMlUrlStateObj from './kbn_ml_url_state.devdocs.json'; diff --git a/api_docs/kbn_ml_validators.mdx b/api_docs/kbn_ml_validators.mdx index 42caffff90456..89da130184b69 100644 --- a/api_docs/kbn_ml_validators.mdx +++ b/api_docs/kbn_ml_validators.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-validators title: "@kbn/ml-validators" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-validators plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-validators'] --- import kbnMlValidatorsObj from './kbn_ml_validators.devdocs.json'; diff --git a/api_docs/kbn_mock_idp_utils.mdx b/api_docs/kbn_mock_idp_utils.mdx index 32e7ee1a060a3..61bab08535a8f 100644 --- a/api_docs/kbn_mock_idp_utils.mdx +++ b/api_docs/kbn_mock_idp_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-mock-idp-utils title: "@kbn/mock-idp-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/mock-idp-utils plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/mock-idp-utils'] --- import kbnMockIdpUtilsObj from './kbn_mock_idp_utils.devdocs.json'; diff --git a/api_docs/kbn_monaco.mdx b/api_docs/kbn_monaco.mdx index b7ab41b129982..ed9d2f96307ed 100644 --- a/api_docs/kbn_monaco.mdx +++ b/api_docs/kbn_monaco.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-monaco title: "@kbn/monaco" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/monaco plugin -date: 2024-11-29 +date: 2024-12-03 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 1409c4885b1ab..c9172a194bb92 100644 --- a/api_docs/kbn_object_versioning.mdx +++ b/api_docs/kbn_object_versioning.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-object-versioning title: "@kbn/object-versioning" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/object-versioning plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/object-versioning'] --- import kbnObjectVersioningObj from './kbn_object_versioning.devdocs.json'; diff --git a/api_docs/kbn_object_versioning_utils.mdx b/api_docs/kbn_object_versioning_utils.mdx index b82d87f58b97b..bcf44cf3f807a 100644 --- a/api_docs/kbn_object_versioning_utils.mdx +++ b/api_docs/kbn_object_versioning_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-object-versioning-utils title: "@kbn/object-versioning-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/object-versioning-utils plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/object-versioning-utils'] --- import kbnObjectVersioningUtilsObj from './kbn_object_versioning_utils.devdocs.json'; diff --git a/api_docs/kbn_observability_alert_details.mdx b/api_docs/kbn_observability_alert_details.mdx index 54d362912bd03..78a482ad69844 100644 --- a/api_docs/kbn_observability_alert_details.mdx +++ b/api_docs/kbn_observability_alert_details.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-observability-alert-details title: "@kbn/observability-alert-details" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/observability-alert-details plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/observability-alert-details'] --- import kbnObservabilityAlertDetailsObj from './kbn_observability_alert_details.devdocs.json'; diff --git a/api_docs/kbn_observability_alerting_rule_utils.mdx b/api_docs/kbn_observability_alerting_rule_utils.mdx index efeae5b312dd0..d50cc46632056 100644 --- a/api_docs/kbn_observability_alerting_rule_utils.mdx +++ b/api_docs/kbn_observability_alerting_rule_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-observability-alerting-rule-utils title: "@kbn/observability-alerting-rule-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/observability-alerting-rule-utils plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/observability-alerting-rule-utils'] --- import kbnObservabilityAlertingRuleUtilsObj from './kbn_observability_alerting_rule_utils.devdocs.json'; diff --git a/api_docs/kbn_observability_alerting_test_data.mdx b/api_docs/kbn_observability_alerting_test_data.mdx index b7cf920e2d034..ad1f805afb938 100644 --- a/api_docs/kbn_observability_alerting_test_data.mdx +++ b/api_docs/kbn_observability_alerting_test_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-observability-alerting-test-data title: "@kbn/observability-alerting-test-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/observability-alerting-test-data plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/observability-alerting-test-data'] --- import kbnObservabilityAlertingTestDataObj from './kbn_observability_alerting_test_data.devdocs.json'; diff --git a/api_docs/kbn_observability_get_padded_alert_time_range_util.mdx b/api_docs/kbn_observability_get_padded_alert_time_range_util.mdx index f098300c38879..0f54b2e88fe49 100644 --- a/api_docs/kbn_observability_get_padded_alert_time_range_util.mdx +++ b/api_docs/kbn_observability_get_padded_alert_time_range_util.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-observability-get-padded-alert-time-range-util title: "@kbn/observability-get-padded-alert-time-range-util" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/observability-get-padded-alert-time-range-util plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/observability-get-padded-alert-time-range-util'] --- import kbnObservabilityGetPaddedAlertTimeRangeUtilObj from './kbn_observability_get_padded_alert_time_range_util.devdocs.json'; diff --git a/api_docs/kbn_observability_logs_overview.devdocs.json b/api_docs/kbn_observability_logs_overview.devdocs.json index 43156c3b352e4..e43439900367a 100644 --- a/api_docs/kbn_observability_logs_overview.devdocs.json +++ b/api_docs/kbn_observability_logs_overview.devdocs.json @@ -316,6 +316,8 @@ "LogCategoriesGridChangeTimeCellDependencies", " & ", "LogCategoryDocumentExamplesTableDependencies", + " & ", + "DiscoverLinkDependencies", " & { search: ", { "pluginId": "@kbn/search-types", @@ -467,6 +469,8 @@ "LogCategoriesGridChangeTimeCellDependencies", " & ", "LogCategoryDocumentExamplesTableDependencies", + " & ", + "DiscoverLinkDependencies", " & { search: ", { "pluginId": "@kbn/search-types", diff --git a/api_docs/kbn_observability_logs_overview.mdx b/api_docs/kbn_observability_logs_overview.mdx index 1e41e75b831f8..736523bbd1b83 100644 --- a/api_docs/kbn_observability_logs_overview.mdx +++ b/api_docs/kbn_observability_logs_overview.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-observability-logs-overview title: "@kbn/observability-logs-overview" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/observability-logs-overview plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/observability-logs-overview'] --- import kbnObservabilityLogsOverviewObj from './kbn_observability_logs_overview.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 | |-------------------|-----------|------------------------|-----------------| -| 29 | 0 | 27 | 4 | +| 29 | 0 | 27 | 5 | ## Client diff --git a/api_docs/kbn_observability_synthetics_test_data.mdx b/api_docs/kbn_observability_synthetics_test_data.mdx index 00134a389c8c1..af1fe17052224 100644 --- a/api_docs/kbn_observability_synthetics_test_data.mdx +++ b/api_docs/kbn_observability_synthetics_test_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-observability-synthetics-test-data title: "@kbn/observability-synthetics-test-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/observability-synthetics-test-data plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/observability-synthetics-test-data'] --- import kbnObservabilitySyntheticsTestDataObj from './kbn_observability_synthetics_test_data.devdocs.json'; diff --git a/api_docs/kbn_openapi_bundler.mdx b/api_docs/kbn_openapi_bundler.mdx index 4f713fe621f68..f1bbdfac697b8 100644 --- a/api_docs/kbn_openapi_bundler.mdx +++ b/api_docs/kbn_openapi_bundler.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-openapi-bundler title: "@kbn/openapi-bundler" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/openapi-bundler plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/openapi-bundler'] --- import kbnOpenapiBundlerObj from './kbn_openapi_bundler.devdocs.json'; diff --git a/api_docs/kbn_openapi_generator.mdx b/api_docs/kbn_openapi_generator.mdx index 916ec6772666f..5626be167782e 100644 --- a/api_docs/kbn_openapi_generator.mdx +++ b/api_docs/kbn_openapi_generator.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-openapi-generator title: "@kbn/openapi-generator" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/openapi-generator plugin -date: 2024-11-29 +date: 2024-12-03 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 0c18398ebc4c2..84b58776b775f 100644 --- a/api_docs/kbn_optimizer.mdx +++ b/api_docs/kbn_optimizer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-optimizer title: "@kbn/optimizer" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/optimizer plugin -date: 2024-11-29 +date: 2024-12-03 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 3b0fd1b21e480..959b2ad430261 100644 --- a/api_docs/kbn_optimizer_webpack_helpers.mdx +++ b/api_docs/kbn_optimizer_webpack_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-optimizer-webpack-helpers title: "@kbn/optimizer-webpack-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/optimizer-webpack-helpers plugin -date: 2024-11-29 +date: 2024-12-03 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 838200925c8d6..95aabcc3d4074 100644 --- a/api_docs/kbn_osquery_io_ts_types.mdx +++ b/api_docs/kbn_osquery_io_ts_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-osquery-io-ts-types title: "@kbn/osquery-io-ts-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/osquery-io-ts-types plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/osquery-io-ts-types'] --- import kbnOsqueryIoTsTypesObj from './kbn_osquery_io_ts_types.devdocs.json'; diff --git a/api_docs/kbn_panel_loader.mdx b/api_docs/kbn_panel_loader.mdx index 5fa490dbedb7a..37e99b6c8f23c 100644 --- a/api_docs/kbn_panel_loader.mdx +++ b/api_docs/kbn_panel_loader.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-panel-loader title: "@kbn/panel-loader" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/panel-loader plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/panel-loader'] --- import kbnPanelLoaderObj from './kbn_panel_loader.devdocs.json'; diff --git a/api_docs/kbn_performance_testing_dataset_extractor.mdx b/api_docs/kbn_performance_testing_dataset_extractor.mdx index 7921cb7337b8b..01143124a8119 100644 --- a/api_docs/kbn_performance_testing_dataset_extractor.mdx +++ b/api_docs/kbn_performance_testing_dataset_extractor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-performance-testing-dataset-extractor title: "@kbn/performance-testing-dataset-extractor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/performance-testing-dataset-extractor plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/performance-testing-dataset-extractor'] --- import kbnPerformanceTestingDatasetExtractorObj from './kbn_performance_testing_dataset_extractor.devdocs.json'; diff --git a/api_docs/kbn_plugin_check.mdx b/api_docs/kbn_plugin_check.mdx index d3984bf980ca6..a8529cd3e4b91 100644 --- a/api_docs/kbn_plugin_check.mdx +++ b/api_docs/kbn_plugin_check.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-plugin-check title: "@kbn/plugin-check" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/plugin-check plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/plugin-check'] --- import kbnPluginCheckObj from './kbn_plugin_check.devdocs.json'; diff --git a/api_docs/kbn_plugin_generator.mdx b/api_docs/kbn_plugin_generator.mdx index 6e04eeed2c4b5..cd46b3b93b5a3 100644 --- a/api_docs/kbn_plugin_generator.mdx +++ b/api_docs/kbn_plugin_generator.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-plugin-generator title: "@kbn/plugin-generator" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/plugin-generator plugin -date: 2024-11-29 +date: 2024-12-03 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 36b0d558f5c36..d209418616b10 100644 --- a/api_docs/kbn_plugin_helpers.mdx +++ b/api_docs/kbn_plugin_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-plugin-helpers title: "@kbn/plugin-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/plugin-helpers plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/plugin-helpers'] --- import kbnPluginHelpersObj from './kbn_plugin_helpers.devdocs.json'; diff --git a/api_docs/kbn_presentation_containers.mdx b/api_docs/kbn_presentation_containers.mdx index 00b73cc246a5c..45859f56729f0 100644 --- a/api_docs/kbn_presentation_containers.mdx +++ b/api_docs/kbn_presentation_containers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-presentation-containers title: "@kbn/presentation-containers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/presentation-containers plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/presentation-containers'] --- import kbnPresentationContainersObj from './kbn_presentation_containers.devdocs.json'; diff --git a/api_docs/kbn_presentation_publishing.devdocs.json b/api_docs/kbn_presentation_publishing.devdocs.json index 96ab95f427e63..46dd41e293a4c 100644 --- a/api_docs/kbn_presentation_publishing.devdocs.json +++ b/api_docs/kbn_presentation_publishing.devdocs.json @@ -8023,6 +8023,36 @@ "trackAdoption": false, "initialIsOpen": false }, + { + "parentPluginId": "@kbn/presentation-publishing", + "id": "def-public.PublishesWritableDataViews", + "type": "Type", + "tags": [], + "label": "PublishesWritableDataViews", + "description": [], + "signature": [ + { + "pluginId": "@kbn/presentation-publishing", + "scope": "public", + "docId": "kibKbnPresentationPublishingPluginApi", + "section": "def-public.PublishesDataViews", + "text": "PublishesDataViews" + }, + " & { setDataViews: (dataViews: ", + { + "pluginId": "dataViews", + "scope": "common", + "docId": "kibDataViewsPluginApi", + "section": "def-common.DataView", + "text": "DataView" + }, + "[]) => void; }" + ], + "path": "packages/presentation/presentation_publishing/interfaces/publishes_data_views.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "@kbn/presentation-publishing", "id": "def-public.PublishesWritablePanelDescription", diff --git a/api_docs/kbn_presentation_publishing.mdx b/api_docs/kbn_presentation_publishing.mdx index 3c75a29ea77aa..55e3be661aca6 100644 --- a/api_docs/kbn_presentation_publishing.mdx +++ b/api_docs/kbn_presentation_publishing.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-presentation-publishing title: "@kbn/presentation-publishing" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/presentation-publishing plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/presentation-publishing'] --- import kbnPresentationPublishingObj from './kbn_presentation_publishing.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 | |-------------------|-----------|------------------------|-----------------| -| 228 | 0 | 192 | 6 | +| 229 | 0 | 193 | 6 | ## Client diff --git a/api_docs/kbn_product_doc_artifact_builder.mdx b/api_docs/kbn_product_doc_artifact_builder.mdx index d04a1eea4679a..1d145c2963921 100644 --- a/api_docs/kbn_product_doc_artifact_builder.mdx +++ b/api_docs/kbn_product_doc_artifact_builder.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-product-doc-artifact-builder title: "@kbn/product-doc-artifact-builder" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/product-doc-artifact-builder plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/product-doc-artifact-builder'] --- import kbnProductDocArtifactBuilderObj from './kbn_product_doc_artifact_builder.devdocs.json'; diff --git a/api_docs/kbn_product_doc_common.devdocs.json b/api_docs/kbn_product_doc_common.devdocs.json index 57e3e65f89df3..f5c8ea4e0e653 100644 --- a/api_docs/kbn_product_doc_common.devdocs.json +++ b/api_docs/kbn_product_doc_common.devdocs.json @@ -426,7 +426,7 @@ "label": "productDocIndexPrefix", "description": [], "signature": [ - "\".kibana-ai-product-doc\"" + "\".kibana_ai_product_doc\"" ], "path": "x-pack/packages/ai-infra/product-doc-common/src/indices.ts", "deprecated": false, diff --git a/api_docs/kbn_product_doc_common.mdx b/api_docs/kbn_product_doc_common.mdx index 6048c13957f86..ff9efa88f98b0 100644 --- a/api_docs/kbn_product_doc_common.mdx +++ b/api_docs/kbn_product_doc_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-product-doc-common title: "@kbn/product-doc-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/product-doc-common plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/product-doc-common'] --- import kbnProductDocCommonObj from './kbn_product_doc_common.devdocs.json'; diff --git a/api_docs/kbn_profiling_utils.mdx b/api_docs/kbn_profiling_utils.mdx index 462e1066d15b5..32ba388ea4293 100644 --- a/api_docs/kbn_profiling_utils.mdx +++ b/api_docs/kbn_profiling_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-profiling-utils title: "@kbn/profiling-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/profiling-utils plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/profiling-utils'] --- import kbnProfilingUtilsObj from './kbn_profiling_utils.devdocs.json'; diff --git a/api_docs/kbn_random_sampling.mdx b/api_docs/kbn_random_sampling.mdx index 307620ab706b4..c19773b55d58c 100644 --- a/api_docs/kbn_random_sampling.mdx +++ b/api_docs/kbn_random_sampling.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-random-sampling title: "@kbn/random-sampling" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/random-sampling plugin -date: 2024-11-29 +date: 2024-12-03 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 836e93e6a876f..6e6c4e356054b 100644 --- a/api_docs/kbn_react_field.mdx +++ b/api_docs/kbn_react_field.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-field title: "@kbn/react-field" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-field plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-field'] --- import kbnReactFieldObj from './kbn_react_field.devdocs.json'; diff --git a/api_docs/kbn_react_hooks.mdx b/api_docs/kbn_react_hooks.mdx index 27a1f01140924..3499369aa5cc3 100644 --- a/api_docs/kbn_react_hooks.mdx +++ b/api_docs/kbn_react_hooks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-hooks title: "@kbn/react-hooks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-hooks plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-hooks'] --- import kbnReactHooksObj from './kbn_react_hooks.devdocs.json'; diff --git a/api_docs/kbn_react_kibana_context_common.mdx b/api_docs/kbn_react_kibana_context_common.mdx index 8750574bf792c..42b1829b1a1fd 100644 --- a/api_docs/kbn_react_kibana_context_common.mdx +++ b/api_docs/kbn_react_kibana_context_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-kibana-context-common title: "@kbn/react-kibana-context-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-kibana-context-common plugin -date: 2024-11-29 +date: 2024-12-03 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 2c28bc54076f6..b87aca0b8cc8d 100644 --- a/api_docs/kbn_react_kibana_context_render.mdx +++ b/api_docs/kbn_react_kibana_context_render.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-kibana-context-render title: "@kbn/react-kibana-context-render" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-kibana-context-render plugin -date: 2024-11-29 +date: 2024-12-03 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 733b785b2f859..caf56b307d1ce 100644 --- a/api_docs/kbn_react_kibana_context_root.mdx +++ b/api_docs/kbn_react_kibana_context_root.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-kibana-context-root title: "@kbn/react-kibana-context-root" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-kibana-context-root plugin -date: 2024-11-29 +date: 2024-12-03 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 98ff3cb0dccf4..9459e13934e85 100644 --- a/api_docs/kbn_react_kibana_context_styled.mdx +++ b/api_docs/kbn_react_kibana_context_styled.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-kibana-context-styled title: "@kbn/react-kibana-context-styled" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-kibana-context-styled plugin -date: 2024-11-29 +date: 2024-12-03 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 8547a28da3229..a81f9b215954e 100644 --- a/api_docs/kbn_react_kibana_context_theme.mdx +++ b/api_docs/kbn_react_kibana_context_theme.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-kibana-context-theme title: "@kbn/react-kibana-context-theme" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-kibana-context-theme plugin -date: 2024-11-29 +date: 2024-12-03 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 400035e0d887a..7aedab1a9b11d 100644 --- a/api_docs/kbn_react_kibana_mount.mdx +++ b/api_docs/kbn_react_kibana_mount.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-kibana-mount title: "@kbn/react-kibana-mount" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-kibana-mount plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-kibana-mount'] --- import kbnReactKibanaMountObj from './kbn_react_kibana_mount.devdocs.json'; diff --git a/api_docs/kbn_recently_accessed.mdx b/api_docs/kbn_recently_accessed.mdx index 1296059e735fa..78d6597cdca31 100644 --- a/api_docs/kbn_recently_accessed.mdx +++ b/api_docs/kbn_recently_accessed.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-recently-accessed title: "@kbn/recently-accessed" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/recently-accessed plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/recently-accessed'] --- import kbnRecentlyAccessedObj from './kbn_recently_accessed.devdocs.json'; diff --git a/api_docs/kbn_repo_file_maps.mdx b/api_docs/kbn_repo_file_maps.mdx index ad6653bc7286a..9fed1ad6757a8 100644 --- a/api_docs/kbn_repo_file_maps.mdx +++ b/api_docs/kbn_repo_file_maps.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-file-maps title: "@kbn/repo-file-maps" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-file-maps plugin -date: 2024-11-29 +date: 2024-12-03 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 43cdbd74b495b..b9f838f9b0769 100644 --- a/api_docs/kbn_repo_linter.mdx +++ b/api_docs/kbn_repo_linter.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-linter title: "@kbn/repo-linter" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-linter plugin -date: 2024-11-29 +date: 2024-12-03 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 f99be2314032d..e557cff63b8dd 100644 --- a/api_docs/kbn_repo_path.mdx +++ b/api_docs/kbn_repo_path.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-path title: "@kbn/repo-path" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-path plugin -date: 2024-11-29 +date: 2024-12-03 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 aa1ad2977a516..beb73cf75b9e5 100644 --- a/api_docs/kbn_repo_source_classifier.mdx +++ b/api_docs/kbn_repo_source_classifier.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-source-classifier title: "@kbn/repo-source-classifier" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-source-classifier plugin -date: 2024-11-29 +date: 2024-12-03 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 21cdaa1daa31d..f093fe90c5b87 100644 --- a/api_docs/kbn_reporting_common.mdx +++ b/api_docs/kbn_reporting_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-common title: "@kbn/reporting-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-common plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-common'] --- import kbnReportingCommonObj from './kbn_reporting_common.devdocs.json'; diff --git a/api_docs/kbn_reporting_csv_share_panel.mdx b/api_docs/kbn_reporting_csv_share_panel.mdx index e49b88b121dd6..82e042aef1c85 100644 --- a/api_docs/kbn_reporting_csv_share_panel.mdx +++ b/api_docs/kbn_reporting_csv_share_panel.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-csv-share-panel title: "@kbn/reporting-csv-share-panel" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-csv-share-panel plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-csv-share-panel'] --- import kbnReportingCsvSharePanelObj from './kbn_reporting_csv_share_panel.devdocs.json'; diff --git a/api_docs/kbn_reporting_export_types_csv.mdx b/api_docs/kbn_reporting_export_types_csv.mdx index 1aa7bb3e4486e..3f70bdb817dcb 100644 --- a/api_docs/kbn_reporting_export_types_csv.mdx +++ b/api_docs/kbn_reporting_export_types_csv.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-export-types-csv title: "@kbn/reporting-export-types-csv" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-export-types-csv plugin -date: 2024-11-29 +date: 2024-12-03 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 61eb5a6cd95e5..3cc02580d869f 100644 --- a/api_docs/kbn_reporting_export_types_csv_common.mdx +++ b/api_docs/kbn_reporting_export_types_csv_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-export-types-csv-common title: "@kbn/reporting-export-types-csv-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-export-types-csv-common plugin -date: 2024-11-29 +date: 2024-12-03 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 09ac3a504ccc0..fc4a512b1afaa 100644 --- a/api_docs/kbn_reporting_export_types_pdf.mdx +++ b/api_docs/kbn_reporting_export_types_pdf.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-export-types-pdf title: "@kbn/reporting-export-types-pdf" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-export-types-pdf plugin -date: 2024-11-29 +date: 2024-12-03 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 a10d560170048..ef46224ef48f1 100644 --- a/api_docs/kbn_reporting_export_types_pdf_common.mdx +++ b/api_docs/kbn_reporting_export_types_pdf_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-export-types-pdf-common title: "@kbn/reporting-export-types-pdf-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-export-types-pdf-common plugin -date: 2024-11-29 +date: 2024-12-03 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 d78b6e86019d4..16a17ea81b44c 100644 --- a/api_docs/kbn_reporting_export_types_png.mdx +++ b/api_docs/kbn_reporting_export_types_png.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-export-types-png title: "@kbn/reporting-export-types-png" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-export-types-png plugin -date: 2024-11-29 +date: 2024-12-03 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 495107ab119cb..6ae5fbbc4999b 100644 --- a/api_docs/kbn_reporting_export_types_png_common.mdx +++ b/api_docs/kbn_reporting_export_types_png_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-export-types-png-common title: "@kbn/reporting-export-types-png-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-export-types-png-common plugin -date: 2024-11-29 +date: 2024-12-03 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 e44db7ea0e2c5..d2db28bae21bd 100644 --- a/api_docs/kbn_reporting_mocks_server.mdx +++ b/api_docs/kbn_reporting_mocks_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-mocks-server title: "@kbn/reporting-mocks-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-mocks-server plugin -date: 2024-11-29 +date: 2024-12-03 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 a90c7bdfb4158..58115068d6d1c 100644 --- a/api_docs/kbn_reporting_public.mdx +++ b/api_docs/kbn_reporting_public.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-public title: "@kbn/reporting-public" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-public plugin -date: 2024-11-29 +date: 2024-12-03 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 e67b3d300567c..e4078c796b5cf 100644 --- a/api_docs/kbn_reporting_server.mdx +++ b/api_docs/kbn_reporting_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-server title: "@kbn/reporting-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-server plugin -date: 2024-11-29 +date: 2024-12-03 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 92aabed363e3e..b69b31c42766c 100644 --- a/api_docs/kbn_resizable_layout.mdx +++ b/api_docs/kbn_resizable_layout.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-resizable-layout title: "@kbn/resizable-layout" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/resizable-layout plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/resizable-layout'] --- import kbnResizableLayoutObj from './kbn_resizable_layout.devdocs.json'; diff --git a/api_docs/kbn_response_ops_feature_flag_service.mdx b/api_docs/kbn_response_ops_feature_flag_service.mdx index 5a7272e354eb9..323a53ab8beb8 100644 --- a/api_docs/kbn_response_ops_feature_flag_service.mdx +++ b/api_docs/kbn_response_ops_feature_flag_service.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-response-ops-feature-flag-service title: "@kbn/response-ops-feature-flag-service" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/response-ops-feature-flag-service plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/response-ops-feature-flag-service'] --- import kbnResponseOpsFeatureFlagServiceObj from './kbn_response_ops_feature_flag_service.devdocs.json'; diff --git a/api_docs/kbn_response_ops_rule_params.mdx b/api_docs/kbn_response_ops_rule_params.mdx index 36b7fbd643327..c3e71da7ac36f 100644 --- a/api_docs/kbn_response_ops_rule_params.mdx +++ b/api_docs/kbn_response_ops_rule_params.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-response-ops-rule-params title: "@kbn/response-ops-rule-params" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/response-ops-rule-params plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/response-ops-rule-params'] --- import kbnResponseOpsRuleParamsObj from './kbn_response_ops_rule_params.devdocs.json'; diff --git a/api_docs/kbn_rison.mdx b/api_docs/kbn_rison.mdx index 3308e30ea655a..fe5fd4236fe4b 100644 --- a/api_docs/kbn_rison.mdx +++ b/api_docs/kbn_rison.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-rison title: "@kbn/rison" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/rison plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/rison'] --- import kbnRisonObj from './kbn_rison.devdocs.json'; diff --git a/api_docs/kbn_rollup.mdx b/api_docs/kbn_rollup.mdx index eb9743f4c6ecc..2f7a740e3cbfe 100644 --- a/api_docs/kbn_rollup.mdx +++ b/api_docs/kbn_rollup.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-rollup title: "@kbn/rollup" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/rollup plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/rollup'] --- import kbnRollupObj from './kbn_rollup.devdocs.json'; diff --git a/api_docs/kbn_router_to_openapispec.mdx b/api_docs/kbn_router_to_openapispec.mdx index f7d3cfc18ce36..7157417647b2f 100644 --- a/api_docs/kbn_router_to_openapispec.mdx +++ b/api_docs/kbn_router_to_openapispec.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-router-to-openapispec title: "@kbn/router-to-openapispec" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/router-to-openapispec plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/router-to-openapispec'] --- import kbnRouterToOpenapispecObj from './kbn_router_to_openapispec.devdocs.json'; diff --git a/api_docs/kbn_router_utils.mdx b/api_docs/kbn_router_utils.mdx index 3a3bf17c9bf80..a916eba9f065c 100644 --- a/api_docs/kbn_router_utils.mdx +++ b/api_docs/kbn_router_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-router-utils title: "@kbn/router-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/router-utils plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/router-utils'] --- import kbnRouterUtilsObj from './kbn_router_utils.devdocs.json'; diff --git a/api_docs/kbn_rrule.mdx b/api_docs/kbn_rrule.mdx index 5bb8b55990b1f..7d311e0e8872d 100644 --- a/api_docs/kbn_rrule.mdx +++ b/api_docs/kbn_rrule.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-rrule title: "@kbn/rrule" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/rrule plugin -date: 2024-11-29 +date: 2024-12-03 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 2804ac870eba3..3899d5cc19efc 100644 --- a/api_docs/kbn_rule_data_utils.mdx +++ b/api_docs/kbn_rule_data_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-rule-data-utils title: "@kbn/rule-data-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/rule-data-utils plugin -date: 2024-11-29 +date: 2024-12-03 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 d61b7adcaf862..e6c7e1e08ae1e 100644 --- a/api_docs/kbn_saved_objects_settings.mdx +++ b/api_docs/kbn_saved_objects_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-saved-objects-settings title: "@kbn/saved-objects-settings" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/saved-objects-settings plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/saved-objects-settings'] --- import kbnSavedObjectsSettingsObj from './kbn_saved_objects_settings.devdocs.json'; diff --git a/api_docs/kbn_saved_search_component.devdocs.json b/api_docs/kbn_saved_search_component.devdocs.json new file mode 100644 index 0000000000000..faaed21b5130e --- /dev/null +++ b/api_docs/kbn_saved_search_component.devdocs.json @@ -0,0 +1,301 @@ +{ + "id": "@kbn/saved-search-component", + "client": { + "classes": [], + "functions": [ + { + "parentPluginId": "@kbn/saved-search-component", + "id": "def-public.LazySavedSearchComponent", + "type": "Function", + "tags": [], + "label": "LazySavedSearchComponent", + "description": [], + "signature": [ + "React.ForwardRefExoticComponent<", + { + "pluginId": "@kbn/saved-search-component", + "scope": "public", + "docId": "kibKbnSavedSearchComponentPluginApi", + "section": "def-public.SavedSearchComponentProps", + "text": "SavedSearchComponentProps" + }, + " & React.RefAttributes<{}>>" + ], + "path": "packages/kbn-saved-search-component/index.ts", + "deprecated": false, + "trackAdoption": false, + "returnComment": [], + "children": [ + { + "parentPluginId": "@kbn/saved-search-component", + "id": "def-public.LazySavedSearchComponent.$1", + "type": "Uncategorized", + "tags": [], + "label": "props", + "description": [], + "signature": [ + "P" + ], + "path": "node_modules/@types/react/ts5.0/index.d.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + } + ], + "interfaces": [ + { + "parentPluginId": "@kbn/saved-search-component", + "id": "def-public.SavedSearchComponentDependencies", + "type": "Interface", + "tags": [], + "label": "SavedSearchComponentDependencies", + "description": [], + "path": "packages/kbn-saved-search-component/src/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/saved-search-component", + "id": "def-public.SavedSearchComponentDependencies.embeddable", + "type": "Object", + "tags": [], + "label": "embeddable", + "description": [], + "signature": [ + { + "pluginId": "embeddable", + "scope": "public", + "docId": "kibEmbeddablePluginApi", + "section": "def-public.EmbeddableStart", + "text": "EmbeddableStart" + } + ], + "path": "packages/kbn-saved-search-component/src/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/saved-search-component", + "id": "def-public.SavedSearchComponentDependencies.searchSource", + "type": "Object", + "tags": [], + "label": "searchSource", + "description": [], + "signature": [ + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.ISearchStartSearchSource", + "text": "ISearchStartSearchSource" + } + ], + "path": "packages/kbn-saved-search-component/src/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/saved-search-component", + "id": "def-public.SavedSearchComponentDependencies.dataViews", + "type": "Object", + "tags": [], + "label": "dataViews", + "description": [], + "signature": [ + { + "pluginId": "dataViews", + "scope": "public", + "docId": "kibDataViewsPluginApi", + "section": "def-public.DataViewsServicePublic", + "text": "DataViewsServicePublic" + } + ], + "path": "packages/kbn-saved-search-component/src/types.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/saved-search-component", + "id": "def-public.SavedSearchComponentProps", + "type": "Interface", + "tags": [], + "label": "SavedSearchComponentProps", + "description": [], + "path": "packages/kbn-saved-search-component/src/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/saved-search-component", + "id": "def-public.SavedSearchComponentProps.dependencies", + "type": "Object", + "tags": [], + "label": "dependencies", + "description": [], + "signature": [ + { + "pluginId": "@kbn/saved-search-component", + "scope": "public", + "docId": "kibKbnSavedSearchComponentPluginApi", + "section": "def-public.SavedSearchComponentDependencies", + "text": "SavedSearchComponentDependencies" + } + ], + "path": "packages/kbn-saved-search-component/src/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/saved-search-component", + "id": "def-public.SavedSearchComponentProps.index", + "type": "string", + "tags": [], + "label": "index", + "description": [], + "path": "packages/kbn-saved-search-component/src/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/saved-search-component", + "id": "def-public.SavedSearchComponentProps.timeRange", + "type": "Object", + "tags": [], + "label": "timeRange", + "description": [], + "signature": [ + { + "pluginId": "@kbn/es-query", + "scope": "common", + "docId": "kibKbnEsQueryPluginApi", + "section": "def-common.TimeRange", + "text": "TimeRange" + }, + " | undefined" + ], + "path": "packages/kbn-saved-search-component/src/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/saved-search-component", + "id": "def-public.SavedSearchComponentProps.query", + "type": "Object", + "tags": [], + "label": "query", + "description": [], + "signature": [ + { + "pluginId": "@kbn/es-query", + "scope": "common", + "docId": "kibKbnEsQueryPluginApi", + "section": "def-common.Query", + "text": "Query" + }, + " | undefined" + ], + "path": "packages/kbn-saved-search-component/src/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/saved-search-component", + "id": "def-public.SavedSearchComponentProps.filters", + "type": "Array", + "tags": [], + "label": "filters", + "description": [], + "signature": [ + { + "pluginId": "@kbn/es-query", + "scope": "common", + "docId": "kibKbnEsQueryPluginApi", + "section": "def-common.Filter", + "text": "Filter" + }, + "[] | undefined" + ], + "path": "packages/kbn-saved-search-component/src/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/saved-search-component", + "id": "def-public.SavedSearchComponentProps.timestampField", + "type": "string", + "tags": [], + "label": "timestampField", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "packages/kbn-saved-search-component/src/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/saved-search-component", + "id": "def-public.SavedSearchComponentProps.height", + "type": "CompoundType", + "tags": [], + "label": "height", + "description": [], + "signature": [ + "Property", + ".Height | undefined" + ], + "path": "packages/kbn-saved-search-component/src/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/saved-search-component", + "id": "def-public.SavedSearchComponentProps.displayOptions", + "type": "Object", + "tags": [], + "label": "displayOptions", + "description": [], + "signature": [ + { + "pluginId": "discover", + "scope": "public", + "docId": "kibDiscoverPluginApi", + "section": "def-public.NonPersistedDisplayOptions", + "text": "NonPersistedDisplayOptions" + }, + " | undefined" + ], + "path": "packages/kbn-saved-search-component/src/types.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + } + ], + "enums": [], + "misc": [], + "objects": [] + }, + "server": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "common": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + } +} \ No newline at end of file diff --git a/api_docs/kbn_saved_search_component.mdx b/api_docs/kbn_saved_search_component.mdx new file mode 100644 index 0000000000000..6d72787f6d76a --- /dev/null +++ b/api_docs/kbn_saved_search_component.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: kibKbnSavedSearchComponentPluginApi +slug: /kibana-dev-docs/api/kbn-saved-search-component +title: "@kbn/saved-search-component" +image: https://source.unsplash.com/400x175/?github +description: API docs for the @kbn/saved-search-component plugin +date: 2024-12-03 +tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/saved-search-component'] +--- +import kbnSavedSearchComponentObj from './kbn_saved_search_component.devdocs.json'; + + + +Contact [@elastic/obs-ux-logs-team](https://github.com/orgs/elastic/teams/obs-ux-logs-team) for questions regarding this plugin. + +**Code health stats** + +| Public API count | Any count | Items lacking comments | Missing exports | +|-------------------|-----------|------------------------|-----------------| +| 15 | 0 | 14 | 0 | + +## Client + +### Functions + + +### Interfaces + + diff --git a/api_docs/kbn_scout.devdocs.json b/api_docs/kbn_scout.devdocs.json index 8766dbc9f9f4d..8d2b4e60a782d 100644 --- a/api_docs/kbn_scout.devdocs.json +++ b/api_docs/kbn_scout.devdocs.json @@ -17,7 +17,1369 @@ "objects": [] }, "common": { - "classes": [], + "classes": [ + { + "parentPluginId": "@kbn/scout", + "id": "def-common.Client", + "type": "Class", + "tags": [], + "label": "Client", + "description": [], + "signature": [ + "default", + " extends ", + "default" + ], + "path": "node_modules/@elastic/elasticsearch/lib/client.d.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/scout", + "id": "def-common.Client.diagnostic", + "type": "Object", + "tags": [], + "label": "diagnostic", + "description": [], + "signature": [ + "default" + ], + "path": "node_modules/@elastic/elasticsearch/lib/client.d.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/scout", + "id": "def-common.Client.name", + "type": "CompoundType", + "tags": [], + "label": "name", + "description": [], + "signature": [ + "string | symbol" + ], + "path": "node_modules/@elastic/elasticsearch/lib/client.d.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/scout", + "id": "def-common.Client.connectionPool", + "type": "Object", + "tags": [], + "label": "connectionPool", + "description": [], + "signature": [ + "default" + ], + "path": "node_modules/@elastic/elasticsearch/lib/client.d.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/scout", + "id": "def-common.Client.transport", + "type": "Object", + "tags": [], + "label": "transport", + "description": [], + "signature": [ + "default" + ], + "path": "node_modules/@elastic/elasticsearch/lib/client.d.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/scout", + "id": "def-common.Client.serializer", + "type": "Object", + "tags": [], + "label": "serializer", + "description": [], + "signature": [ + "default" + ], + "path": "node_modules/@elastic/elasticsearch/lib/client.d.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/scout", + "id": "def-common.Client.helpers", + "type": "Object", + "tags": [], + "label": "helpers", + "description": [], + "signature": [ + "default" + ], + "path": "node_modules/@elastic/elasticsearch/lib/client.d.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/scout", + "id": "def-common.Client.Unnamed", + "type": "Function", + "tags": [], + "label": "Constructor", + "description": [], + "signature": [ + "any" + ], + "path": "node_modules/@elastic/elasticsearch/lib/client.d.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/scout", + "id": "def-common.Client.Unnamed.$1", + "type": "Object", + "tags": [], + "label": "opts", + "description": [], + "signature": [ + "ClientOptions" + ], + "path": "node_modules/@elastic/elasticsearch/lib/client.d.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/scout", + "id": "def-common.Client.child", + "type": "Function", + "tags": [], + "label": "child", + "description": [], + "signature": [ + "(opts: ", + "ClientOptions", + ") => ", + "default" + ], + "path": "node_modules/@elastic/elasticsearch/lib/client.d.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/scout", + "id": "def-common.Client.child.$1", + "type": "Object", + "tags": [], + "label": "opts", + "description": [], + "signature": [ + "ClientOptions" + ], + "path": "node_modules/@elastic/elasticsearch/lib/client.d.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/scout", + "id": "def-common.Client.close", + "type": "Function", + "tags": [], + "label": "close", + "description": [], + "signature": [ + "() => Promise" + ], + "path": "node_modules/@elastic/elasticsearch/lib/client.d.ts", + "deprecated": false, + "trackAdoption": false, + "children": [], + "returnComment": [] + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/scout", + "id": "def-common.KbnClient", + "type": "Class", + "tags": [], + "label": "KbnClient", + "description": [], + "path": "packages/kbn-test/src/kbn_client/kbn_client.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/scout", + "id": "def-common.KbnClient.status", + "type": "Object", + "tags": [], + "label": "status", + "description": [], + "signature": [ + "KbnClientStatus" + ], + "path": "packages/kbn-test/src/kbn_client/kbn_client.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/scout", + "id": "def-common.KbnClient.plugins", + "type": "Object", + "tags": [], + "label": "plugins", + "description": [], + "signature": [ + "KbnClientPlugins" + ], + "path": "packages/kbn-test/src/kbn_client/kbn_client.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/scout", + "id": "def-common.KbnClient.version", + "type": "Object", + "tags": [], + "label": "version", + "description": [], + "signature": [ + "KbnClientVersion" + ], + "path": "packages/kbn-test/src/kbn_client/kbn_client.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/scout", + "id": "def-common.KbnClient.savedObjects", + "type": "Object", + "tags": [], + "label": "savedObjects", + "description": [], + "signature": [ + "KbnClientSavedObjects" + ], + "path": "packages/kbn-test/src/kbn_client/kbn_client.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/scout", + "id": "def-common.KbnClient.spaces", + "type": "Object", + "tags": [], + "label": "spaces", + "description": [], + "signature": [ + "KbnClientSpaces" + ], + "path": "packages/kbn-test/src/kbn_client/kbn_client.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/scout", + "id": "def-common.KbnClient.uiSettings", + "type": "Object", + "tags": [], + "label": "uiSettings", + "description": [], + "signature": [ + "KbnClientUiSettings" + ], + "path": "packages/kbn-test/src/kbn_client/kbn_client.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/scout", + "id": "def-common.KbnClient.importExport", + "type": "Object", + "tags": [], + "label": "importExport", + "description": [], + "signature": [ + "KbnClientImportExport" + ], + "path": "packages/kbn-test/src/kbn_client/kbn_client.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/scout", + "id": "def-common.KbnClient.Unnamed", + "type": "Function", + "tags": [], + "label": "Constructor", + "description": [ + "\nBasic Kibana server client that implements common behaviors for talking\nto the Kibana server from dev tooling." + ], + "signature": [ + "any" + ], + "path": "packages/kbn-test/src/kbn_client/kbn_client.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/scout", + "id": "def-common.KbnClient.Unnamed.$1", + "type": "Object", + "tags": [], + "label": "options", + "description": [], + "signature": [ + { + "pluginId": "@kbn/test", + "scope": "common", + "docId": "kibKbnTestPluginApi", + "section": "def-common.KbnClientOptions", + "text": "KbnClientOptions" + } + ], + "path": "packages/kbn-test/src/kbn_client/kbn_client.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/scout", + "id": "def-common.KbnClient.request", + "type": "Function", + "tags": [], + "label": "request", + "description": [ + "\nMake a direct request to the Kibana server" + ], + "signature": [ + "(options: ", + "ReqOptions", + ") => Promise<", + "AxiosResponse", + ">" + ], + "path": "packages/kbn-test/src/kbn_client/kbn_client.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/scout", + "id": "def-common.KbnClient.request.$1", + "type": "Object", + "tags": [], + "label": "options", + "description": [], + "signature": [ + "ReqOptions" + ], + "path": "packages/kbn-test/src/kbn_client/kbn_client.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/scout", + "id": "def-common.KbnClient.resolveUrl", + "type": "Function", + "tags": [], + "label": "resolveUrl", + "description": [], + "signature": [ + "(relativeUrl: string) => string" + ], + "path": "packages/kbn-test/src/kbn_client/kbn_client.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/scout", + "id": "def-common.KbnClient.resolveUrl.$1", + "type": "string", + "tags": [], + "label": "relativeUrl", + "description": [], + "signature": [ + "string" + ], + "path": "packages/kbn-test/src/kbn_client/kbn_client.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/scout", + "id": "def-common.KibanaUrl", + "type": "Class", + "tags": [], + "label": "KibanaUrl", + "description": [], + "path": "packages/kbn-scout/src/common/services/kibana_url.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/scout", + "id": "def-common.KibanaUrl.baseUrl", + "type": "Object", + "tags": [], + "label": "#baseUrl", + "description": [], + "signature": [ + "URL" + ], + "path": "packages/kbn-scout/src/common/services/kibana_url.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/scout", + "id": "def-common.KibanaUrl.Unnamed", + "type": "Function", + "tags": [], + "label": "Constructor", + "description": [], + "signature": [ + "any" + ], + "path": "packages/kbn-scout/src/common/services/kibana_url.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/scout", + "id": "def-common.KibanaUrl.Unnamed.$1", + "type": "Object", + "tags": [], + "label": "baseUrl", + "description": [], + "signature": [ + "URL" + ], + "path": "packages/kbn-scout/src/common/services/kibana_url.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/scout", + "id": "def-common.KibanaUrl.get", + "type": "Function", + "tags": [], + "label": "get", + "description": [ + "\nGet an absolute URL based on Kibana's URL" + ], + "signature": [ + "(rel?: string | undefined, options?: ", + "PathOptions", + " | undefined) => string" + ], + "path": "packages/kbn-scout/src/common/services/kibana_url.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/scout", + "id": "def-common.KibanaUrl.get.$1", + "type": "string", + "tags": [], + "label": "rel", + "description": [ + "relative url, resolved relative to Kibana's url" + ], + "signature": [ + "string | undefined" + ], + "path": "packages/kbn-scout/src/common/services/kibana_url.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": false + }, + { + "parentPluginId": "@kbn/scout", + "id": "def-common.KibanaUrl.get.$2", + "type": "Object", + "tags": [], + "label": "options", + "description": [ + "optional modifications to apply to the URL" + ], + "signature": [ + "PathOptions", + " | undefined" + ], + "path": "packages/kbn-scout/src/common/services/kibana_url.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": false + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/scout", + "id": "def-common.KibanaUrl.app", + "type": "Function", + "tags": [], + "label": "app", + "description": [ + "\nGet the URL for an app" + ], + "signature": [ + "(appName: string, options?: ", + "PathOptions", + " | undefined) => string" + ], + "path": "packages/kbn-scout/src/common/services/kibana_url.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/scout", + "id": "def-common.KibanaUrl.app.$1", + "type": "string", + "tags": [], + "label": "appName", + "description": [ + "name of the app to get the URL for" + ], + "signature": [ + "string" + ], + "path": "packages/kbn-scout/src/common/services/kibana_url.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/scout", + "id": "def-common.KibanaUrl.app.$2", + "type": "Object", + "tags": [], + "label": "options", + "description": [ + "optional modifications to apply to the URL" + ], + "signature": [ + "PathOptions", + " | undefined" + ], + "path": "packages/kbn-scout/src/common/services/kibana_url.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": false + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/scout", + "id": "def-common.KibanaUrl.toString", + "type": "Function", + "tags": [], + "label": "toString", + "description": [], + "signature": [ + "() => string" + ], + "path": "packages/kbn-scout/src/common/services/kibana_url.ts", + "deprecated": false, + "trackAdoption": false, + "children": [], + "returnComment": [] + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/scout", + "id": "def-common.SamlSessionManager", + "type": "Class", + "tags": [], + "label": "SamlSessionManager", + "description": [ + "\nManages cookies associated with user roles" + ], + "path": "packages/kbn-test/src/auth/session_manager.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/scout", + "id": "def-common.SamlSessionManager.Unnamed", + "type": "Function", + "tags": [], + "label": "Constructor", + "description": [], + "signature": [ + "any" + ], + "path": "packages/kbn-test/src/auth/session_manager.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/scout", + "id": "def-common.SamlSessionManager.Unnamed.$1", + "type": "Object", + "tags": [], + "label": "options", + "description": [], + "signature": [ + { + "pluginId": "@kbn/test", + "scope": "common", + "docId": "kibKbnTestPluginApi", + "section": "def-common.SamlSessionManagerOptions", + "text": "SamlSessionManagerOptions" + } + ], + "path": "packages/kbn-test/src/auth/session_manager.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/scout", + "id": "def-common.SamlSessionManager.getApiCredentialsForRole", + "type": "Function", + "tags": [], + "label": "getApiCredentialsForRole", + "description": [], + "signature": [ + "(role: string, options?: ", + { + "pluginId": "@kbn/test", + "scope": "common", + "docId": "kibKbnTestPluginApi", + "section": "def-common.GetCookieOptions", + "text": "GetCookieOptions" + }, + " | undefined) => Promise<{ Cookie: string; }>" + ], + "path": "packages/kbn-test/src/auth/session_manager.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/scout", + "id": "def-common.SamlSessionManager.getApiCredentialsForRole.$1", + "type": "string", + "tags": [], + "label": "role", + "description": [], + "signature": [ + "string" + ], + "path": "packages/kbn-test/src/auth/session_manager.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/scout", + "id": "def-common.SamlSessionManager.getApiCredentialsForRole.$2", + "type": "Object", + "tags": [], + "label": "options", + "description": [], + "signature": [ + { + "pluginId": "@kbn/test", + "scope": "common", + "docId": "kibKbnTestPluginApi", + "section": "def-common.GetCookieOptions", + "text": "GetCookieOptions" + }, + " | undefined" + ], + "path": "packages/kbn-test/src/auth/session_manager.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": false + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/scout", + "id": "def-common.SamlSessionManager.getInteractiveUserSessionCookieWithRoleScope", + "type": "Function", + "tags": [], + "label": "getInteractiveUserSessionCookieWithRoleScope", + "description": [], + "signature": [ + "(role: string, options?: ", + { + "pluginId": "@kbn/test", + "scope": "common", + "docId": "kibKbnTestPluginApi", + "section": "def-common.GetCookieOptions", + "text": "GetCookieOptions" + }, + " | undefined) => Promise" + ], + "path": "packages/kbn-test/src/auth/session_manager.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/scout", + "id": "def-common.SamlSessionManager.getInteractiveUserSessionCookieWithRoleScope.$1", + "type": "string", + "tags": [], + "label": "role", + "description": [], + "signature": [ + "string" + ], + "path": "packages/kbn-test/src/auth/session_manager.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/scout", + "id": "def-common.SamlSessionManager.getInteractiveUserSessionCookieWithRoleScope.$2", + "type": "Object", + "tags": [], + "label": "options", + "description": [], + "signature": [ + { + "pluginId": "@kbn/test", + "scope": "common", + "docId": "kibKbnTestPluginApi", + "section": "def-common.GetCookieOptions", + "text": "GetCookieOptions" + }, + " | undefined" + ], + "path": "packages/kbn-test/src/auth/session_manager.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": false + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/scout", + "id": "def-common.SamlSessionManager.getEmail", + "type": "Function", + "tags": [], + "label": "getEmail", + "description": [], + "signature": [ + "(role: string) => Promise" + ], + "path": "packages/kbn-test/src/auth/session_manager.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/scout", + "id": "def-common.SamlSessionManager.getEmail.$1", + "type": "string", + "tags": [], + "label": "role", + "description": [], + "signature": [ + "string" + ], + "path": "packages/kbn-test/src/auth/session_manager.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/scout", + "id": "def-common.SamlSessionManager.getUserData", + "type": "Function", + "tags": [], + "label": "getUserData", + "description": [], + "signature": [ + "(role: string) => Promise<", + "UserProfile", + ">" + ], + "path": "packages/kbn-test/src/auth/session_manager.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/scout", + "id": "def-common.SamlSessionManager.getUserData.$1", + "type": "string", + "tags": [], + "label": "role", + "description": [], + "signature": [ + "string" + ], + "path": "packages/kbn-test/src/auth/session_manager.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/scout", + "id": "def-common.ToolingLog", + "type": "Class", + "tags": [], + "label": "ToolingLog", + "description": [], + "signature": [ + { + "pluginId": "@kbn/tooling-log", + "scope": "common", + "docId": "kibKbnToolingLogPluginApi", + "section": "def-common.ToolingLog", + "text": "ToolingLog" + }, + " implements ", + { + "pluginId": "@kbn/some-dev-log", + "scope": "common", + "docId": "kibKbnSomeDevLogPluginApi", + "section": "def-common.SomeDevLog", + "text": "SomeDevLog" + } + ], + "path": "packages/kbn-tooling-log/src/tooling_log.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/scout", + "id": "def-common.ToolingLog.Unnamed", + "type": "Function", + "tags": [], + "label": "Constructor", + "description": [], + "signature": [ + "any" + ], + "path": "packages/kbn-tooling-log/src/tooling_log.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/scout", + "id": "def-common.ToolingLog.Unnamed.$1", + "type": "Object", + "tags": [], + "label": "writerConfig", + "description": [], + "signature": [ + { + "pluginId": "@kbn/tooling-log", + "scope": "common", + "docId": "kibKbnToolingLogPluginApi", + "section": "def-common.ToolingLogTextWriterConfig", + "text": "ToolingLogTextWriterConfig" + }, + " | undefined" + ], + "path": "packages/kbn-tooling-log/src/tooling_log.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": false + }, + { + "parentPluginId": "@kbn/scout", + "id": "def-common.ToolingLog.Unnamed.$2", + "type": "Object", + "tags": [], + "label": "options", + "description": [], + "signature": [ + { + "pluginId": "@kbn/tooling-log", + "scope": "common", + "docId": "kibKbnToolingLogPluginApi", + "section": "def-common.ToolingLogOptions", + "text": "ToolingLogOptions" + }, + " | undefined" + ], + "path": "packages/kbn-tooling-log/src/tooling_log.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": false + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/scout", + "id": "def-common.ToolingLog.getIndent", + "type": "Function", + "tags": [], + "label": "getIndent", + "description": [ + "\nGet the current indentation level of the ToolingLog" + ], + "signature": [ + "() => number" + ], + "path": "packages/kbn-tooling-log/src/tooling_log.ts", + "deprecated": false, + "trackAdoption": false, + "children": [], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/scout", + "id": "def-common.ToolingLog.indent", + "type": "Function", + "tags": [], + "label": "indent", + "description": [], + "signature": [ + "{ (delta: number): void; (delta: number, block: () => Promise): Promise; (delta: number, block: () => T): T; }" + ], + "path": "packages/kbn-tooling-log/src/tooling_log.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/scout", + "id": "def-common.ToolingLog.indent.$1", + "type": "number", + "tags": [], + "label": "delta", + "description": [], + "signature": [ + "number" + ], + "path": "packages/kbn-tooling-log/src/tooling_log.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/scout", + "id": "def-common.ToolingLog.indent.$2", + "type": "Function", + "tags": [], + "label": "block", + "description": [], + "signature": [ + "(() => T | Promise) | undefined" + ], + "path": "packages/kbn-tooling-log/src/tooling_log.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": false + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/scout", + "id": "def-common.ToolingLog.verbose", + "type": "Function", + "tags": [], + "label": "verbose", + "description": [], + "signature": [ + "(...args: any[]) => void" + ], + "path": "packages/kbn-tooling-log/src/tooling_log.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/scout", + "id": "def-common.ToolingLog.verbose.$1", + "type": "Array", + "tags": [], + "label": "args", + "description": [], + "signature": [ + "any[]" + ], + "path": "packages/kbn-tooling-log/src/tooling_log.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/scout", + "id": "def-common.ToolingLog.debug", + "type": "Function", + "tags": [], + "label": "debug", + "description": [], + "signature": [ + "(...args: any[]) => void" + ], + "path": "packages/kbn-tooling-log/src/tooling_log.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/scout", + "id": "def-common.ToolingLog.debug.$1", + "type": "Array", + "tags": [], + "label": "args", + "description": [], + "signature": [ + "any[]" + ], + "path": "packages/kbn-tooling-log/src/tooling_log.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/scout", + "id": "def-common.ToolingLog.info", + "type": "Function", + "tags": [], + "label": "info", + "description": [], + "signature": [ + "(...args: any[]) => void" + ], + "path": "packages/kbn-tooling-log/src/tooling_log.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/scout", + "id": "def-common.ToolingLog.info.$1", + "type": "Array", + "tags": [], + "label": "args", + "description": [], + "signature": [ + "any[]" + ], + "path": "packages/kbn-tooling-log/src/tooling_log.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/scout", + "id": "def-common.ToolingLog.success", + "type": "Function", + "tags": [], + "label": "success", + "description": [], + "signature": [ + "(...args: any[]) => void" + ], + "path": "packages/kbn-tooling-log/src/tooling_log.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/scout", + "id": "def-common.ToolingLog.success.$1", + "type": "Array", + "tags": [], + "label": "args", + "description": [], + "signature": [ + "any[]" + ], + "path": "packages/kbn-tooling-log/src/tooling_log.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/scout", + "id": "def-common.ToolingLog.warning", + "type": "Function", + "tags": [], + "label": "warning", + "description": [], + "signature": [ + "(...args: any[]) => void" + ], + "path": "packages/kbn-tooling-log/src/tooling_log.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/scout", + "id": "def-common.ToolingLog.warning.$1", + "type": "Array", + "tags": [], + "label": "args", + "description": [], + "signature": [ + "any[]" + ], + "path": "packages/kbn-tooling-log/src/tooling_log.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/scout", + "id": "def-common.ToolingLog.error", + "type": "Function", + "tags": [], + "label": "error", + "description": [], + "signature": [ + "(error: string | Error) => void" + ], + "path": "packages/kbn-tooling-log/src/tooling_log.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/scout", + "id": "def-common.ToolingLog.error.$1", + "type": "CompoundType", + "tags": [], + "label": "error", + "description": [], + "signature": [ + "string | Error" + ], + "path": "packages/kbn-tooling-log/src/tooling_log.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/scout", + "id": "def-common.ToolingLog.write", + "type": "Function", + "tags": [], + "label": "write", + "description": [], + "signature": [ + "(...args: any[]) => void" + ], + "path": "packages/kbn-tooling-log/src/tooling_log.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/scout", + "id": "def-common.ToolingLog.write.$1", + "type": "Array", + "tags": [], + "label": "args", + "description": [], + "signature": [ + "any[]" + ], + "path": "packages/kbn-tooling-log/src/tooling_log.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/scout", + "id": "def-common.ToolingLog.getWriters", + "type": "Function", + "tags": [], + "label": "getWriters", + "description": [], + "signature": [ + "() => ", + { + "pluginId": "@kbn/tooling-log", + "scope": "common", + "docId": "kibKbnToolingLogPluginApi", + "section": "def-common.Writer", + "text": "Writer" + }, + "[]" + ], + "path": "packages/kbn-tooling-log/src/tooling_log.ts", + "deprecated": false, + "trackAdoption": false, + "children": [], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/scout", + "id": "def-common.ToolingLog.setWriters", + "type": "Function", + "tags": [], + "label": "setWriters", + "description": [], + "signature": [ + "(writers: ", + { + "pluginId": "@kbn/tooling-log", + "scope": "common", + "docId": "kibKbnToolingLogPluginApi", + "section": "def-common.Writer", + "text": "Writer" + }, + "[]) => void" + ], + "path": "packages/kbn-tooling-log/src/tooling_log.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/scout", + "id": "def-common.ToolingLog.setWriters.$1", + "type": "Array", + "tags": [], + "label": "writers", + "description": [], + "signature": [ + { + "pluginId": "@kbn/tooling-log", + "scope": "common", + "docId": "kibKbnToolingLogPluginApi", + "section": "def-common.Writer", + "text": "Writer" + }, + "[]" + ], + "path": "packages/kbn-tooling-log/src/tooling_log.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/scout", + "id": "def-common.ToolingLog.getWritten$", + "type": "Function", + "tags": [], + "label": "getWritten$", + "description": [], + "signature": [ + "() => ", + "Observable", + "<", + { + "pluginId": "@kbn/tooling-log", + "scope": "common", + "docId": "kibKbnToolingLogPluginApi", + "section": "def-common.Message", + "text": "Message" + }, + ">" + ], + "path": "packages/kbn-tooling-log/src/tooling_log.ts", + "deprecated": false, + "trackAdoption": false, + "children": [], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/scout", + "id": "def-common.ToolingLog.withType", + "type": "Function", + "tags": [], + "label": "withType", + "description": [ + "\nCreate a new ToolingLog which sets a different \"type\", allowing messages to be filtered out by \"source\"" + ], + "signature": [ + "(type: string) => ", + { + "pluginId": "@kbn/tooling-log", + "scope": "common", + "docId": "kibKbnToolingLogPluginApi", + "section": "def-common.ToolingLog", + "text": "ToolingLog" + } + ], + "path": "packages/kbn-tooling-log/src/tooling_log.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/scout", + "id": "def-common.ToolingLog.withType.$1", + "type": "string", + "tags": [], + "label": "type", + "description": [ + "A string that will be passed along with messages from this logger which can be used to filter messages with `ignoreSources`" + ], + "signature": [ + "string" + ], + "path": "packages/kbn-tooling-log/src/tooling_log.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] + } + ], + "initialIsOpen": false + } + ], "functions": [ { "parentPluginId": "@kbn/scout", @@ -289,7 +1651,13 @@ "text": "ScoutPage" }, "; kbnUrl: ", - "KibanaUrl", + { + "pluginId": "@kbn/scout", + "scope": "common", + "docId": "kibKbnScoutPluginApi", + "section": "def-common.KibanaUrl", + "text": "KibanaUrl" + }, "; } & ", { "pluginId": "@kbn/scout", @@ -319,6 +1687,84 @@ } ], "interfaces": [ + { + "parentPluginId": "@kbn/scout", + "id": "def-common.EsArchiverFixture", + "type": "Interface", + "tags": [], + "label": "EsArchiverFixture", + "description": [], + "path": "packages/kbn-scout/src/playwright/fixtures/types/worker_scope.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/scout", + "id": "def-common.EsArchiverFixture.loadIfNeeded", + "type": "Function", + "tags": [], + "label": "loadIfNeeded", + "description": [], + "signature": [ + "(name: string, performance?: ", + { + "pluginId": "@kbn/es-archiver", + "scope": "common", + "docId": "kibKbnEsArchiverPluginApi", + "section": "def-common.LoadActionPerfOptions", + "text": "LoadActionPerfOptions" + }, + " | undefined) => Promise>" + ], + "path": "packages/kbn-scout/src/playwright/fixtures/types/worker_scope.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/scout", + "id": "def-common.EsArchiverFixture.loadIfNeeded.$1", + "type": "string", + "tags": [], + "label": "name", + "description": [], + "signature": [ + "string" + ], + "path": "packages/kbn-scout/src/playwright/fixtures/types/worker_scope.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/scout", + "id": "def-common.EsArchiverFixture.loadIfNeeded.$2", + "type": "Object", + "tags": [], + "label": "performance", + "description": [], + "signature": [ + { + "pluginId": "@kbn/es-archiver", + "scope": "common", + "docId": "kibKbnEsArchiverPluginApi", + "section": "def-common.LoadActionPerfOptions", + "text": "LoadActionPerfOptions" + }, + " | undefined" + ], + "path": "packages/kbn-scout/src/playwright/fixtures/types/worker_scope.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": false + } + ], + "returnComment": [] + } + ], + "initialIsOpen": false + }, { "parentPluginId": "@kbn/scout", "id": "def-common.PageObjects", @@ -357,6 +1803,34 @@ "path": "packages/kbn-scout/src/playwright/page_objects/index.ts", "deprecated": false, "trackAdoption": false + }, + { + "parentPluginId": "@kbn/scout", + "id": "def-common.PageObjects.dashboard", + "type": "Object", + "tags": [], + "label": "dashboard", + "description": [], + "signature": [ + "DashboardApp" + ], + "path": "packages/kbn-scout/src/playwright/page_objects/index.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/scout", + "id": "def-common.PageObjects.filterBar", + "type": "Object", + "tags": [], + "label": "filterBar", + "description": [], + "signature": [ + "FilterBar" + ], + "path": "packages/kbn-scout/src/playwright/page_objects/index.ts", + "deprecated": false, + "trackAdoption": false } ], "initialIsOpen": false @@ -448,13 +1922,17 @@ "Page", " & { gotoApp: (appName: string, options?: { referer?: string | undefined; timeout?: number | undefined; waitUntil?: \"load\" | \"domcontentloaded\" | \"networkidle\" | \"commit\" | undefined; } | undefined) => Promise<", "Response", - " | null>; testSubj: { check: (selector: string, options?: { force?: boolean | undefined; noWaitAfter?: boolean | undefined; position?: { x: number; y: number; } | undefined; strict?: boolean | undefined; timeout?: number | undefined; trial?: boolean | undefined; } | undefined) => Promise; click: (selector: string, options?: { button?: \"right\" | \"left\" | \"middle\" | undefined; clickCount?: number | undefined; delay?: number | undefined; force?: boolean | undefined; modifiers?: (\"Alt\" | \"Control\" | \"Meta\" | \"Shift\" | \"ControlOrMeta\")[] | undefined; noWaitAfter?: boolean | undefined; position?: { x: number; y: number; } | undefined; strict?: boolean | undefined; timeout?: number | undefined; trial?: boolean | undefined; } | undefined) => Promise; dblclick: (selector: string, options?: { button?: \"right\" | \"left\" | \"middle\" | undefined; delay?: number | undefined; force?: boolean | undefined; modifiers?: (\"Alt\" | \"Control\" | \"Meta\" | \"Shift\" | \"ControlOrMeta\")[] | undefined; noWaitAfter?: boolean | undefined; position?: { x: number; y: number; } | undefined; strict?: boolean | undefined; timeout?: number | undefined; trial?: boolean | undefined; } | undefined) => Promise; fill: (selector: string, value: string, options?: { force?: boolean | undefined; noWaitAfter?: boolean | undefined; strict?: boolean | undefined; timeout?: number | undefined; } | undefined) => Promise; focus: (selector: string, options?: { strict?: boolean | undefined; timeout?: number | undefined; } | undefined) => Promise; getAttribute: (selector: string, name: string, options?: { strict?: boolean | undefined; timeout?: number | undefined; } | undefined) => Promise; hover: (selector: string, options?: { force?: boolean | undefined; modifiers?: (\"Alt\" | \"Control\" | \"Meta\" | \"Shift\" | \"ControlOrMeta\")[] | undefined; noWaitAfter?: boolean | undefined; position?: { x: number; y: number; } | undefined; strict?: boolean | undefined; timeout?: number | undefined; trial?: boolean | undefined; } | undefined) => Promise; innerText: (selector: string, options?: { strict?: boolean | undefined; timeout?: number | undefined; } | undefined) => Promise; isEnabled: (selector: string, options?: { strict?: boolean | undefined; timeout?: number | undefined; } | undefined) => Promise; isChecked: (selector: string, options?: { strict?: boolean | undefined; timeout?: number | undefined; } | undefined) => Promise; isHidden: (selector: string, options?: { strict?: boolean | undefined; timeout?: number | undefined; } | undefined) => Promise; locator: (selector: string, options?: { has?: ", + " | null>; waitForLoadingIndicatorHidden: () => Promise<", + "ElementHandle", + " | null>; testSubj: { check: (selector: string, options?: { force?: boolean | undefined; noWaitAfter?: boolean | undefined; position?: { x: number; y: number; } | undefined; strict?: boolean | undefined; timeout?: number | undefined; trial?: boolean | undefined; } | undefined) => Promise; click: (selector: string, options?: { button?: \"right\" | \"left\" | \"middle\" | undefined; clickCount?: number | undefined; delay?: number | undefined; force?: boolean | undefined; modifiers?: (\"Alt\" | \"Control\" | \"Meta\" | \"Shift\" | \"ControlOrMeta\")[] | undefined; noWaitAfter?: boolean | undefined; position?: { x: number; y: number; } | undefined; strict?: boolean | undefined; timeout?: number | undefined; trial?: boolean | undefined; } | undefined) => Promise; dblclick: (selector: string, options?: { button?: \"right\" | \"left\" | \"middle\" | undefined; delay?: number | undefined; force?: boolean | undefined; modifiers?: (\"Alt\" | \"Control\" | \"Meta\" | \"Shift\" | \"ControlOrMeta\")[] | undefined; noWaitAfter?: boolean | undefined; position?: { x: number; y: number; } | undefined; strict?: boolean | undefined; timeout?: number | undefined; trial?: boolean | undefined; } | undefined) => Promise; fill: (selector: string, value: string, options?: { force?: boolean | undefined; noWaitAfter?: boolean | undefined; strict?: boolean | undefined; timeout?: number | undefined; } | undefined) => Promise; focus: (selector: string, options?: { strict?: boolean | undefined; timeout?: number | undefined; } | undefined) => Promise; getAttribute: (selector: string, name: string, options?: { strict?: boolean | undefined; timeout?: number | undefined; } | undefined) => Promise; hover: (selector: string, options?: { force?: boolean | undefined; modifiers?: (\"Alt\" | \"Control\" | \"Meta\" | \"Shift\" | \"ControlOrMeta\")[] | undefined; noWaitAfter?: boolean | undefined; position?: { x: number; y: number; } | undefined; strict?: boolean | undefined; timeout?: number | undefined; trial?: boolean | undefined; } | undefined) => Promise; innerText: (selector: string, options?: { strict?: boolean | undefined; timeout?: number | undefined; } | undefined) => Promise; isEnabled: (selector: string, options?: { strict?: boolean | undefined; timeout?: number | undefined; } | undefined) => Promise; isChecked: (selector: string, options?: { strict?: boolean | undefined; timeout?: number | undefined; } | undefined) => Promise; isHidden: (selector: string, options?: { strict?: boolean | undefined; timeout?: number | undefined; } | undefined) => Promise; isVisible: (selector: string, options?: { strict?: boolean | undefined; timeout?: number | undefined; } | undefined) => Promise; locator: (selector: string, options?: { has?: ", "Locator", " | undefined; hasNot?: ", "Locator", " | undefined; hasNotText?: string | RegExp | undefined; hasText?: string | RegExp | undefined; } | undefined) => ", "Locator", - "; }; }" + "; waitForSelector: (selector: string, options?: PageWaitForSelectorOptions | undefined) => Promise<", + "ElementHandle", + " | null>; typeWithDelay: (selector: string, text: string, options?: { delay: number; } | undefined) => Promise; clearInput: (selector: string) => Promise; }; }" ], "path": "packages/kbn-scout/src/playwright/fixtures/types/test_scope.ts", "deprecated": false, @@ -583,7 +2061,13 @@ "label": "kbnUrl", "description": [], "signature": [ - "KibanaUrl" + { + "pluginId": "@kbn/scout", + "scope": "common", + "docId": "kibKbnScoutPluginApi", + "section": "def-common.KibanaUrl", + "text": "KibanaUrl" + } ], "path": "packages/kbn-scout/src/playwright/fixtures/types/worker_scope.ts", "deprecated": false, @@ -623,6 +2107,20 @@ "deprecated": false, "trackAdoption": false }, + { + "parentPluginId": "@kbn/scout", + "id": "def-common.ScoutWorkerFixtures.uiSettings", + "type": "Object", + "tags": [], + "label": "uiSettings", + "description": [], + "signature": [ + "UiSettingsFixture" + ], + "path": "packages/kbn-scout/src/playwright/fixtures/types/worker_scope.ts", + "deprecated": false, + "trackAdoption": false + }, { "parentPluginId": "@kbn/scout", "id": "def-common.ScoutWorkerFixtures.esArchiver", @@ -631,7 +2129,13 @@ "label": "esArchiver", "description": [], "signature": [ - "EsArchiverFixture" + { + "pluginId": "@kbn/scout", + "scope": "common", + "docId": "kibKbnScoutPluginApi", + "section": "def-common.EsArchiverFixture", + "text": "EsArchiverFixture" + } ], "path": "packages/kbn-scout/src/playwright/fixtures/types/worker_scope.ts", "deprecated": false, @@ -669,18 +2173,24 @@ "type": "Type", "tags": [], "label": "ScoutPage", - "description": [], + "description": [ + "\nExtends the Playwright 'Page' interface with methods specific to Kibana.\nReasons to use 'ReturnType' instead of Explicit Typings:\n- DRY Principle: automatically stays in sync with the Playwright API, reducing maintenance overhead.\n- Future-Proofing: If Playwright changes the return type of methods, these types will update accordingly.\nRecommendation: define Explicit Types as return types only if methods (e.g. 'typeWithDelay')\nhave any additional logic or Kibana-specific behavior." + ], "signature": [ "Page", " & { gotoApp: (appName: string, options?: { referer?: string | undefined; timeout?: number | undefined; waitUntil?: \"load\" | \"domcontentloaded\" | \"networkidle\" | \"commit\" | undefined; } | undefined) => Promise<", "Response", - " | null>; testSubj: { check: (selector: string, options?: { force?: boolean | undefined; noWaitAfter?: boolean | undefined; position?: { x: number; y: number; } | undefined; strict?: boolean | undefined; timeout?: number | undefined; trial?: boolean | undefined; } | undefined) => Promise; click: (selector: string, options?: { button?: \"right\" | \"left\" | \"middle\" | undefined; clickCount?: number | undefined; delay?: number | undefined; force?: boolean | undefined; modifiers?: (\"Alt\" | \"Control\" | \"Meta\" | \"Shift\" | \"ControlOrMeta\")[] | undefined; noWaitAfter?: boolean | undefined; position?: { x: number; y: number; } | undefined; strict?: boolean | undefined; timeout?: number | undefined; trial?: boolean | undefined; } | undefined) => Promise; dblclick: (selector: string, options?: { button?: \"right\" | \"left\" | \"middle\" | undefined; delay?: number | undefined; force?: boolean | undefined; modifiers?: (\"Alt\" | \"Control\" | \"Meta\" | \"Shift\" | \"ControlOrMeta\")[] | undefined; noWaitAfter?: boolean | undefined; position?: { x: number; y: number; } | undefined; strict?: boolean | undefined; timeout?: number | undefined; trial?: boolean | undefined; } | undefined) => Promise; fill: (selector: string, value: string, options?: { force?: boolean | undefined; noWaitAfter?: boolean | undefined; strict?: boolean | undefined; timeout?: number | undefined; } | undefined) => Promise; focus: (selector: string, options?: { strict?: boolean | undefined; timeout?: number | undefined; } | undefined) => Promise; getAttribute: (selector: string, name: string, options?: { strict?: boolean | undefined; timeout?: number | undefined; } | undefined) => Promise; hover: (selector: string, options?: { force?: boolean | undefined; modifiers?: (\"Alt\" | \"Control\" | \"Meta\" | \"Shift\" | \"ControlOrMeta\")[] | undefined; noWaitAfter?: boolean | undefined; position?: { x: number; y: number; } | undefined; strict?: boolean | undefined; timeout?: number | undefined; trial?: boolean | undefined; } | undefined) => Promise; innerText: (selector: string, options?: { strict?: boolean | undefined; timeout?: number | undefined; } | undefined) => Promise; isEnabled: (selector: string, options?: { strict?: boolean | undefined; timeout?: number | undefined; } | undefined) => Promise; isChecked: (selector: string, options?: { strict?: boolean | undefined; timeout?: number | undefined; } | undefined) => Promise; isHidden: (selector: string, options?: { strict?: boolean | undefined; timeout?: number | undefined; } | undefined) => Promise; locator: (selector: string, options?: { has?: ", + " | null>; waitForLoadingIndicatorHidden: () => Promise<", + "ElementHandle", + " | null>; testSubj: { check: (selector: string, options?: { force?: boolean | undefined; noWaitAfter?: boolean | undefined; position?: { x: number; y: number; } | undefined; strict?: boolean | undefined; timeout?: number | undefined; trial?: boolean | undefined; } | undefined) => Promise; click: (selector: string, options?: { button?: \"right\" | \"left\" | \"middle\" | undefined; clickCount?: number | undefined; delay?: number | undefined; force?: boolean | undefined; modifiers?: (\"Alt\" | \"Control\" | \"Meta\" | \"Shift\" | \"ControlOrMeta\")[] | undefined; noWaitAfter?: boolean | undefined; position?: { x: number; y: number; } | undefined; strict?: boolean | undefined; timeout?: number | undefined; trial?: boolean | undefined; } | undefined) => Promise; dblclick: (selector: string, options?: { button?: \"right\" | \"left\" | \"middle\" | undefined; delay?: number | undefined; force?: boolean | undefined; modifiers?: (\"Alt\" | \"Control\" | \"Meta\" | \"Shift\" | \"ControlOrMeta\")[] | undefined; noWaitAfter?: boolean | undefined; position?: { x: number; y: number; } | undefined; strict?: boolean | undefined; timeout?: number | undefined; trial?: boolean | undefined; } | undefined) => Promise; fill: (selector: string, value: string, options?: { force?: boolean | undefined; noWaitAfter?: boolean | undefined; strict?: boolean | undefined; timeout?: number | undefined; } | undefined) => Promise; focus: (selector: string, options?: { strict?: boolean | undefined; timeout?: number | undefined; } | undefined) => Promise; getAttribute: (selector: string, name: string, options?: { strict?: boolean | undefined; timeout?: number | undefined; } | undefined) => Promise; hover: (selector: string, options?: { force?: boolean | undefined; modifiers?: (\"Alt\" | \"Control\" | \"Meta\" | \"Shift\" | \"ControlOrMeta\")[] | undefined; noWaitAfter?: boolean | undefined; position?: { x: number; y: number; } | undefined; strict?: boolean | undefined; timeout?: number | undefined; trial?: boolean | undefined; } | undefined) => Promise; innerText: (selector: string, options?: { strict?: boolean | undefined; timeout?: number | undefined; } | undefined) => Promise; isEnabled: (selector: string, options?: { strict?: boolean | undefined; timeout?: number | undefined; } | undefined) => Promise; isChecked: (selector: string, options?: { strict?: boolean | undefined; timeout?: number | undefined; } | undefined) => Promise; isHidden: (selector: string, options?: { strict?: boolean | undefined; timeout?: number | undefined; } | undefined) => Promise; isVisible: (selector: string, options?: { strict?: boolean | undefined; timeout?: number | undefined; } | undefined) => Promise; locator: (selector: string, options?: { has?: ", "Locator", " | undefined; hasNot?: ", "Locator", " | undefined; hasNotText?: string | RegExp | undefined; hasText?: string | RegExp | undefined; } | undefined) => ", "Locator", - "; }; }" + "; waitForSelector: (selector: string, options?: PageWaitForSelectorOptions | undefined) => Promise<", + "ElementHandle", + " | null>; typeWithDelay: (selector: string, text: string, options?: { delay: number; } | undefined) => Promise; clearInput: (selector: string) => Promise; }; }" ], "path": "packages/kbn-scout/src/playwright/fixtures/types/test_scope.ts", "deprecated": false, diff --git a/api_docs/kbn_scout.mdx b/api_docs/kbn_scout.mdx index d6f307e323758..b868c759fe850 100644 --- a/api_docs/kbn_scout.mdx +++ b/api_docs/kbn_scout.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-scout title: "@kbn/scout" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/scout plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/scout'] --- import kbnScoutObj from './kbn_scout.devdocs.json'; @@ -21,13 +21,16 @@ Contact [@elastic/appex-qa](https://github.com/orgs/elastic/teams/appex-qa) for | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 34 | 0 | 26 | 5 | +| 119 | 0 | 86 | 8 | ## Common ### Functions +### Classes + + ### Interfaces diff --git a/api_docs/kbn_screenshotting_server.mdx b/api_docs/kbn_screenshotting_server.mdx index 269fae68fa07d..be432e83d6061 100644 --- a/api_docs/kbn_screenshotting_server.mdx +++ b/api_docs/kbn_screenshotting_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-screenshotting-server title: "@kbn/screenshotting-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/screenshotting-server plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/screenshotting-server'] --- import kbnScreenshottingServerObj from './kbn_screenshotting_server.devdocs.json'; diff --git a/api_docs/kbn_search_api_keys_components.mdx b/api_docs/kbn_search_api_keys_components.mdx index c91db726180ba..4f4ef836fc8d5 100644 --- a/api_docs/kbn_search_api_keys_components.mdx +++ b/api_docs/kbn_search_api_keys_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-search-api-keys-components title: "@kbn/search-api-keys-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/search-api-keys-components plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/search-api-keys-components'] --- import kbnSearchApiKeysComponentsObj from './kbn_search_api_keys_components.devdocs.json'; diff --git a/api_docs/kbn_search_api_keys_server.mdx b/api_docs/kbn_search_api_keys_server.mdx index 53ffccb7bd83c..d065d49232bdc 100644 --- a/api_docs/kbn_search_api_keys_server.mdx +++ b/api_docs/kbn_search_api_keys_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-search-api-keys-server title: "@kbn/search-api-keys-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/search-api-keys-server plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/search-api-keys-server'] --- import kbnSearchApiKeysServerObj from './kbn_search_api_keys_server.devdocs.json'; diff --git a/api_docs/kbn_search_api_panels.mdx b/api_docs/kbn_search_api_panels.mdx index 8f36f685a1398..0cf7b6a852222 100644 --- a/api_docs/kbn_search_api_panels.mdx +++ b/api_docs/kbn_search_api_panels.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-search-api-panels title: "@kbn/search-api-panels" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/search-api-panels plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/search-api-panels'] --- import kbnSearchApiPanelsObj from './kbn_search_api_panels.devdocs.json'; diff --git a/api_docs/kbn_search_connectors.devdocs.json b/api_docs/kbn_search_connectors.devdocs.json index a4721ab941fbd..31b9ff22f7e0d 100644 --- a/api_docs/kbn_search_connectors.devdocs.json +++ b/api_docs/kbn_search_connectors.devdocs.json @@ -1338,6 +1338,98 @@ "returnComment": [], "initialIsOpen": false }, + { + "parentPluginId": "@kbn/search-connectors", + "id": "def-common.generateConnectorName", + "type": "Function", + "tags": [], + "label": "generateConnectorName", + "description": [], + "signature": [ + "(client: ", + { + "pluginId": "@kbn/core-elasticsearch-server", + "scope": "server", + "docId": "kibKbnCoreElasticsearchServerPluginApi", + "section": "def-server.ElasticsearchClient", + "text": "ElasticsearchClient" + }, + ", connectorType: string, isNative: boolean, userConnectorName?: string | undefined) => Promise<{ connectorName: string; indexName: string; }>" + ], + "path": "packages/kbn-search-connectors/lib/generate_connector_name.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/search-connectors", + "id": "def-common.generateConnectorName.$1", + "type": "Object", + "tags": [], + "label": "client", + "description": [], + "signature": [ + { + "pluginId": "@kbn/core-elasticsearch-server", + "scope": "server", + "docId": "kibKbnCoreElasticsearchServerPluginApi", + "section": "def-server.ElasticsearchClient", + "text": "ElasticsearchClient" + } + ], + "path": "packages/kbn-search-connectors/lib/generate_connector_name.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/search-connectors", + "id": "def-common.generateConnectorName.$2", + "type": "string", + "tags": [], + "label": "connectorType", + "description": [], + "signature": [ + "string" + ], + "path": "packages/kbn-search-connectors/lib/generate_connector_name.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/search-connectors", + "id": "def-common.generateConnectorName.$3", + "type": "boolean", + "tags": [], + "label": "isNative", + "description": [], + "signature": [ + "boolean" + ], + "path": "packages/kbn-search-connectors/lib/generate_connector_name.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/search-connectors", + "id": "def-common.generateConnectorName.$4", + "type": "string", + "tags": [], + "label": "userConnectorName", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "packages/kbn-search-connectors/lib/generate_connector_name.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": false + } + ], + "returnComment": [], + "initialIsOpen": false + }, { "parentPluginId": "@kbn/search-connectors", "id": "def-common.getConnectorsDict", @@ -7161,6 +7253,21 @@ "deprecated": false, "trackAdoption": false, "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/search-connectors", + "id": "def-common.MANAGED_CONNECTOR_INDEX_PREFIX", + "type": "string", + "tags": [], + "label": "MANAGED_CONNECTOR_INDEX_PREFIX", + "description": [], + "signature": [ + "\"content-\"" + ], + "path": "packages/kbn-search-connectors/constants/connectors.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false } ], "objects": [ diff --git a/api_docs/kbn_search_connectors.mdx b/api_docs/kbn_search_connectors.mdx index 3a1022272aac4..5ba6722443d61 100644 --- a/api_docs/kbn_search_connectors.mdx +++ b/api_docs/kbn_search_connectors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-search-connectors title: "@kbn/search-connectors" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/search-connectors plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/search-connectors'] --- import kbnSearchConnectorsObj from './kbn_search_connectors.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/search-kibana](https://github.com/orgs/elastic/teams/search-ki | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 3948 | 0 | 3948 | 0 | +| 3954 | 0 | 3954 | 0 | ## Common diff --git a/api_docs/kbn_search_errors.mdx b/api_docs/kbn_search_errors.mdx index 8633e87605634..ed60763f601ef 100644 --- a/api_docs/kbn_search_errors.mdx +++ b/api_docs/kbn_search_errors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-search-errors title: "@kbn/search-errors" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/search-errors plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/search-errors'] --- import kbnSearchErrorsObj from './kbn_search_errors.devdocs.json'; diff --git a/api_docs/kbn_search_index_documents.mdx b/api_docs/kbn_search_index_documents.mdx index 179aada42d1f8..f5d8aa98d839e 100644 --- a/api_docs/kbn_search_index_documents.mdx +++ b/api_docs/kbn_search_index_documents.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-search-index-documents title: "@kbn/search-index-documents" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/search-index-documents plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/search-index-documents'] --- import kbnSearchIndexDocumentsObj from './kbn_search_index_documents.devdocs.json'; diff --git a/api_docs/kbn_search_response_warnings.mdx b/api_docs/kbn_search_response_warnings.mdx index 2a0b6393b85f0..2171084dde531 100644 --- a/api_docs/kbn_search_response_warnings.mdx +++ b/api_docs/kbn_search_response_warnings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-search-response-warnings title: "@kbn/search-response-warnings" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/search-response-warnings plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/search-response-warnings'] --- import kbnSearchResponseWarningsObj from './kbn_search_response_warnings.devdocs.json'; diff --git a/api_docs/kbn_search_shared_ui.mdx b/api_docs/kbn_search_shared_ui.mdx index 5046df6114a5e..ebad34cd2bd63 100644 --- a/api_docs/kbn_search_shared_ui.mdx +++ b/api_docs/kbn_search_shared_ui.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-search-shared-ui title: "@kbn/search-shared-ui" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/search-shared-ui plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/search-shared-ui'] --- import kbnSearchSharedUiObj from './kbn_search_shared_ui.devdocs.json'; diff --git a/api_docs/kbn_search_types.mdx b/api_docs/kbn_search_types.mdx index 04873f8b4827c..4ead6d8c9968a 100644 --- a/api_docs/kbn_search_types.mdx +++ b/api_docs/kbn_search_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-search-types title: "@kbn/search-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/search-types plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/search-types'] --- import kbnSearchTypesObj from './kbn_search_types.devdocs.json'; diff --git a/api_docs/kbn_security_api_key_management.mdx b/api_docs/kbn_security_api_key_management.mdx index f16ff4c7f6cb8..3b3612d40743d 100644 --- a/api_docs/kbn_security_api_key_management.mdx +++ b/api_docs/kbn_security_api_key_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-api-key-management title: "@kbn/security-api-key-management" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-api-key-management plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-api-key-management'] --- import kbnSecurityApiKeyManagementObj from './kbn_security_api_key_management.devdocs.json'; diff --git a/api_docs/kbn_security_authorization_core.mdx b/api_docs/kbn_security_authorization_core.mdx index 80a0eef25456e..c9ed463683ca7 100644 --- a/api_docs/kbn_security_authorization_core.mdx +++ b/api_docs/kbn_security_authorization_core.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-authorization-core title: "@kbn/security-authorization-core" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-authorization-core plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-authorization-core'] --- import kbnSecurityAuthorizationCoreObj from './kbn_security_authorization_core.devdocs.json'; diff --git a/api_docs/kbn_security_authorization_core_common.mdx b/api_docs/kbn_security_authorization_core_common.mdx index 45085705f9dc0..74f2c37abcd95 100644 --- a/api_docs/kbn_security_authorization_core_common.mdx +++ b/api_docs/kbn_security_authorization_core_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-authorization-core-common title: "@kbn/security-authorization-core-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-authorization-core-common plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-authorization-core-common'] --- import kbnSecurityAuthorizationCoreCommonObj from './kbn_security_authorization_core_common.devdocs.json'; diff --git a/api_docs/kbn_security_form_components.mdx b/api_docs/kbn_security_form_components.mdx index 8aff9267953b1..b7cf6dbe337d9 100644 --- a/api_docs/kbn_security_form_components.mdx +++ b/api_docs/kbn_security_form_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-form-components title: "@kbn/security-form-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-form-components plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-form-components'] --- import kbnSecurityFormComponentsObj from './kbn_security_form_components.devdocs.json'; diff --git a/api_docs/kbn_security_hardening.mdx b/api_docs/kbn_security_hardening.mdx index 49172eabf7de7..59150e002d372 100644 --- a/api_docs/kbn_security_hardening.mdx +++ b/api_docs/kbn_security_hardening.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-hardening title: "@kbn/security-hardening" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-hardening plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-hardening'] --- import kbnSecurityHardeningObj from './kbn_security_hardening.devdocs.json'; diff --git a/api_docs/kbn_security_plugin_types_common.mdx b/api_docs/kbn_security_plugin_types_common.mdx index 37ac56b717abc..7860df573efe2 100644 --- a/api_docs/kbn_security_plugin_types_common.mdx +++ b/api_docs/kbn_security_plugin_types_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-plugin-types-common title: "@kbn/security-plugin-types-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-plugin-types-common plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-plugin-types-common'] --- import kbnSecurityPluginTypesCommonObj from './kbn_security_plugin_types_common.devdocs.json'; diff --git a/api_docs/kbn_security_plugin_types_public.mdx b/api_docs/kbn_security_plugin_types_public.mdx index fab11395449ad..a80602c8ca044 100644 --- a/api_docs/kbn_security_plugin_types_public.mdx +++ b/api_docs/kbn_security_plugin_types_public.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-plugin-types-public title: "@kbn/security-plugin-types-public" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-plugin-types-public plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-plugin-types-public'] --- import kbnSecurityPluginTypesPublicObj from './kbn_security_plugin_types_public.devdocs.json'; diff --git a/api_docs/kbn_security_plugin_types_server.mdx b/api_docs/kbn_security_plugin_types_server.mdx index a60a1f2ae1199..dacb26ea39d3c 100644 --- a/api_docs/kbn_security_plugin_types_server.mdx +++ b/api_docs/kbn_security_plugin_types_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-plugin-types-server title: "@kbn/security-plugin-types-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-plugin-types-server plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-plugin-types-server'] --- import kbnSecurityPluginTypesServerObj from './kbn_security_plugin_types_server.devdocs.json'; diff --git a/api_docs/kbn_security_role_management_model.mdx b/api_docs/kbn_security_role_management_model.mdx index cd455b3aeab1b..0227136a820fe 100644 --- a/api_docs/kbn_security_role_management_model.mdx +++ b/api_docs/kbn_security_role_management_model.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-role-management-model title: "@kbn/security-role-management-model" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-role-management-model plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-role-management-model'] --- import kbnSecurityRoleManagementModelObj from './kbn_security_role_management_model.devdocs.json'; diff --git a/api_docs/kbn_security_solution_distribution_bar.devdocs.json b/api_docs/kbn_security_solution_distribution_bar.devdocs.json index edcd3cad12f9b..51fdf64ef88c7 100644 --- a/api_docs/kbn_security_solution_distribution_bar.devdocs.json +++ b/api_docs/kbn_security_solution_distribution_bar.devdocs.json @@ -84,7 +84,7 @@ "distribution data points" ], "signature": [ - "{ key: string; count: number; color: string; label?: React.ReactNode; }[]" + "{ key: string; count: number; color: string; label?: React.ReactNode; isCurrentFilter?: boolean | undefined; filter?: (() => void) | undefined; reset?: ((event: React.MouseEvent) => void) | undefined; }[]" ], "path": "x-pack/packages/security-solution/distribution_bar/src/distribution_bar.tsx", "deprecated": false, diff --git a/api_docs/kbn_security_solution_distribution_bar.mdx b/api_docs/kbn_security_solution_distribution_bar.mdx index 5742410a78c31..6db68ac78df81 100644 --- a/api_docs/kbn_security_solution_distribution_bar.mdx +++ b/api_docs/kbn_security_solution_distribution_bar.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-solution-distribution-bar title: "@kbn/security-solution-distribution-bar" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-solution-distribution-bar plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-solution-distribution-bar'] --- import kbnSecuritySolutionDistributionBarObj from './kbn_security_solution_distribution_bar.devdocs.json'; diff --git a/api_docs/kbn_security_solution_features.mdx b/api_docs/kbn_security_solution_features.mdx index 376bae01ef582..cfae5b98640c1 100644 --- a/api_docs/kbn_security_solution_features.mdx +++ b/api_docs/kbn_security_solution_features.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-solution-features title: "@kbn/security-solution-features" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-solution-features plugin -date: 2024-11-29 +date: 2024-12-03 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 eb5432593eee0..a6c6a0bc8b4cc 100644 --- a/api_docs/kbn_security_solution_navigation.mdx +++ b/api_docs/kbn_security_solution_navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-solution-navigation title: "@kbn/security-solution-navigation" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-solution-navigation plugin -date: 2024-11-29 +date: 2024-12-03 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 be4da2232d2bb..b59dc38d0d65f 100644 --- a/api_docs/kbn_security_solution_side_nav.mdx +++ b/api_docs/kbn_security_solution_side_nav.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-solution-side-nav title: "@kbn/security-solution-side-nav" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-solution-side-nav plugin -date: 2024-11-29 +date: 2024-12-03 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 3239220fe65fe..51a54e68c6d39 100644 --- a/api_docs/kbn_security_solution_storybook_config.mdx +++ b/api_docs/kbn_security_solution_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-solution-storybook-config title: "@kbn/security-solution-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-solution-storybook-config plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-solution-storybook-config'] --- import kbnSecuritySolutionStorybookConfigObj from './kbn_security_solution_storybook_config.devdocs.json'; diff --git a/api_docs/kbn_security_ui_components.mdx b/api_docs/kbn_security_ui_components.mdx index 3358ff89524b7..995a86bd52251 100644 --- a/api_docs/kbn_security_ui_components.mdx +++ b/api_docs/kbn_security_ui_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-ui-components title: "@kbn/security-ui-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-ui-components plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-ui-components'] --- import kbnSecurityUiComponentsObj from './kbn_security_ui_components.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_autocomplete.mdx b/api_docs/kbn_securitysolution_autocomplete.mdx index adc29bb11b2f3..375acf6485700 100644 --- a/api_docs/kbn_securitysolution_autocomplete.mdx +++ b/api_docs/kbn_securitysolution_autocomplete.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-autocomplete title: "@kbn/securitysolution-autocomplete" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-autocomplete plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-autocomplete'] --- import kbnSecuritysolutionAutocompleteObj from './kbn_securitysolution_autocomplete.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_data_table.mdx b/api_docs/kbn_securitysolution_data_table.mdx index b81fb86b638bd..c8fbe41adc821 100644 --- a/api_docs/kbn_securitysolution_data_table.mdx +++ b/api_docs/kbn_securitysolution_data_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-data-table title: "@kbn/securitysolution-data-table" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-data-table plugin -date: 2024-11-29 +date: 2024-12-03 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 a125379f33879..29c7acff0d35b 100644 --- a/api_docs/kbn_securitysolution_ecs.mdx +++ b/api_docs/kbn_securitysolution_ecs.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-ecs title: "@kbn/securitysolution-ecs" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-ecs plugin -date: 2024-11-29 +date: 2024-12-03 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 54c961abbfdaa..7c918c80d9e82 100644 --- a/api_docs/kbn_securitysolution_es_utils.mdx +++ b/api_docs/kbn_securitysolution_es_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-es-utils title: "@kbn/securitysolution-es-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-es-utils plugin -date: 2024-11-29 +date: 2024-12-03 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 5e38b6fcc3bba..ea26ddab6a94d 100644 --- a/api_docs/kbn_securitysolution_exception_list_components.mdx +++ b/api_docs/kbn_securitysolution_exception_list_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-exception-list-components title: "@kbn/securitysolution-exception-list-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-exception-list-components plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-exception-list-components'] --- import kbnSecuritysolutionExceptionListComponentsObj from './kbn_securitysolution_exception_list_components.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_hook_utils.mdx b/api_docs/kbn_securitysolution_hook_utils.mdx index 17d887579b7fb..3c9d620a2b6fd 100644 --- a/api_docs/kbn_securitysolution_hook_utils.mdx +++ b/api_docs/kbn_securitysolution_hook_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-hook-utils title: "@kbn/securitysolution-hook-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-hook-utils plugin -date: 2024-11-29 +date: 2024-12-03 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 1d93837d92168..1cadbad642b59 100644 --- a/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-alerting-types title: "@kbn/securitysolution-io-ts-alerting-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-alerting-types plugin -date: 2024-11-29 +date: 2024-12-03 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 1218112d5c3d1..c97c65e926681 100644 --- a/api_docs/kbn_securitysolution_io_ts_list_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_list_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-list-types title: "@kbn/securitysolution-io-ts-list-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-list-types plugin -date: 2024-11-29 +date: 2024-12-03 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 6f8eb023a9fa3..475670953a925 100644 --- a/api_docs/kbn_securitysolution_io_ts_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-types title: "@kbn/securitysolution-io-ts-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-types plugin -date: 2024-11-29 +date: 2024-12-03 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 a03aaf56d0972..35eabcf16f602 100644 --- a/api_docs/kbn_securitysolution_io_ts_utils.mdx +++ b/api_docs/kbn_securitysolution_io_ts_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-utils title: "@kbn/securitysolution-io-ts-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-utils plugin -date: 2024-11-29 +date: 2024-12-03 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 d9301a3fd07cc..5acbde47bdf9a 100644 --- a/api_docs/kbn_securitysolution_list_api.mdx +++ b/api_docs/kbn_securitysolution_list_api.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-api title: "@kbn/securitysolution-list-api" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-api plugin -date: 2024-11-29 +date: 2024-12-03 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 8754640304daa..65cd4a1e4db0d 100644 --- a/api_docs/kbn_securitysolution_list_constants.mdx +++ b/api_docs/kbn_securitysolution_list_constants.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-constants title: "@kbn/securitysolution-list-constants" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-constants plugin -date: 2024-11-29 +date: 2024-12-03 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 cb83af9823756..47034d9238fd1 100644 --- a/api_docs/kbn_securitysolution_list_hooks.mdx +++ b/api_docs/kbn_securitysolution_list_hooks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-hooks title: "@kbn/securitysolution-list-hooks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-hooks plugin -date: 2024-11-29 +date: 2024-12-03 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 58989e2db6bb5..f3596fe402d03 100644 --- a/api_docs/kbn_securitysolution_list_utils.mdx +++ b/api_docs/kbn_securitysolution_list_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-utils title: "@kbn/securitysolution-list-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-utils plugin -date: 2024-11-29 +date: 2024-12-03 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 427bc451da782..796441a88f2fb 100644 --- a/api_docs/kbn_securitysolution_rules.mdx +++ b/api_docs/kbn_securitysolution_rules.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-rules title: "@kbn/securitysolution-rules" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-rules plugin -date: 2024-11-29 +date: 2024-12-03 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 a32c8f0806948..b69ebb507b467 100644 --- a/api_docs/kbn_securitysolution_t_grid.mdx +++ b/api_docs/kbn_securitysolution_t_grid.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-t-grid title: "@kbn/securitysolution-t-grid" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-t-grid plugin -date: 2024-11-29 +date: 2024-12-03 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 08af0850dddd3..3bd451984fd2e 100644 --- a/api_docs/kbn_securitysolution_utils.mdx +++ b/api_docs/kbn_securitysolution_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-utils title: "@kbn/securitysolution-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-utils plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-utils'] --- import kbnSecuritysolutionUtilsObj from './kbn_securitysolution_utils.devdocs.json'; diff --git a/api_docs/kbn_server_http_tools.mdx b/api_docs/kbn_server_http_tools.mdx index 28c5541a9f937..e321b98542f9f 100644 --- a/api_docs/kbn_server_http_tools.mdx +++ b/api_docs/kbn_server_http_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-server-http-tools title: "@kbn/server-http-tools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/server-http-tools plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/server-http-tools'] --- import kbnServerHttpToolsObj from './kbn_server_http_tools.devdocs.json'; diff --git a/api_docs/kbn_server_route_repository.mdx b/api_docs/kbn_server_route_repository.mdx index b756f0045a264..c7f27f9b9f5b5 100644 --- a/api_docs/kbn_server_route_repository.mdx +++ b/api_docs/kbn_server_route_repository.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-server-route-repository title: "@kbn/server-route-repository" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/server-route-repository plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/server-route-repository'] --- import kbnServerRouteRepositoryObj from './kbn_server_route_repository.devdocs.json'; diff --git a/api_docs/kbn_server_route_repository_client.mdx b/api_docs/kbn_server_route_repository_client.mdx index 234f4a625ce24..38a373079d662 100644 --- a/api_docs/kbn_server_route_repository_client.mdx +++ b/api_docs/kbn_server_route_repository_client.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-server-route-repository-client title: "@kbn/server-route-repository-client" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/server-route-repository-client plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/server-route-repository-client'] --- import kbnServerRouteRepositoryClientObj from './kbn_server_route_repository_client.devdocs.json'; diff --git a/api_docs/kbn_server_route_repository_utils.mdx b/api_docs/kbn_server_route_repository_utils.mdx index 18406baf5a62e..e439098ba3498 100644 --- a/api_docs/kbn_server_route_repository_utils.mdx +++ b/api_docs/kbn_server_route_repository_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-server-route-repository-utils title: "@kbn/server-route-repository-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/server-route-repository-utils plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/server-route-repository-utils'] --- import kbnServerRouteRepositoryUtilsObj from './kbn_server_route_repository_utils.devdocs.json'; diff --git a/api_docs/kbn_serverless_common_settings.mdx b/api_docs/kbn_serverless_common_settings.mdx index 8ed3e154ecee7..7f064985631c8 100644 --- a/api_docs/kbn_serverless_common_settings.mdx +++ b/api_docs/kbn_serverless_common_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-serverless-common-settings title: "@kbn/serverless-common-settings" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/serverless-common-settings plugin -date: 2024-11-29 +date: 2024-12-03 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 c668e12e093f5..d22ce4172aa69 100644 --- a/api_docs/kbn_serverless_observability_settings.mdx +++ b/api_docs/kbn_serverless_observability_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-serverless-observability-settings title: "@kbn/serverless-observability-settings" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/serverless-observability-settings plugin -date: 2024-11-29 +date: 2024-12-03 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 c061ebda9b737..5963967d8bcf7 100644 --- a/api_docs/kbn_serverless_project_switcher.mdx +++ b/api_docs/kbn_serverless_project_switcher.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-serverless-project-switcher title: "@kbn/serverless-project-switcher" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/serverless-project-switcher plugin -date: 2024-11-29 +date: 2024-12-03 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 6230d8885310d..f8a1e6cc37fdc 100644 --- a/api_docs/kbn_serverless_search_settings.mdx +++ b/api_docs/kbn_serverless_search_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-serverless-search-settings title: "@kbn/serverless-search-settings" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/serverless-search-settings plugin -date: 2024-11-29 +date: 2024-12-03 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 e504ff5e1165b..3442c34bdbb85 100644 --- a/api_docs/kbn_serverless_security_settings.mdx +++ b/api_docs/kbn_serverless_security_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-serverless-security-settings title: "@kbn/serverless-security-settings" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/serverless-security-settings plugin -date: 2024-11-29 +date: 2024-12-03 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 d77ea8baa21b1..a174fe461afa2 100644 --- a/api_docs/kbn_serverless_storybook_config.mdx +++ b/api_docs/kbn_serverless_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-serverless-storybook-config title: "@kbn/serverless-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/serverless-storybook-config plugin -date: 2024-11-29 +date: 2024-12-03 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 8a96abcc882b0..75eddfcf4e298 100644 --- a/api_docs/kbn_shared_svg.mdx +++ b/api_docs/kbn_shared_svg.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-svg title: "@kbn/shared-svg" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-svg plugin -date: 2024-11-29 +date: 2024-12-03 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 87351004356eb..07f0127523f52 100644 --- a/api_docs/kbn_shared_ux_avatar_solution.mdx +++ b/api_docs/kbn_shared_ux_avatar_solution.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-avatar-solution title: "@kbn/shared-ux-avatar-solution" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-avatar-solution plugin -date: 2024-11-29 +date: 2024-12-03 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 71e5b78119139..a4aa5096b5024 100644 --- a/api_docs/kbn_shared_ux_button_exit_full_screen.mdx +++ b/api_docs/kbn_shared_ux_button_exit_full_screen.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-button-exit-full-screen title: "@kbn/shared-ux-button-exit-full-screen" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-button-exit-full-screen plugin -date: 2024-11-29 +date: 2024-12-03 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 088718965bc70..28ae6716f3ee9 100644 --- a/api_docs/kbn_shared_ux_button_toolbar.mdx +++ b/api_docs/kbn_shared_ux_button_toolbar.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-button-toolbar title: "@kbn/shared-ux-button-toolbar" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-button-toolbar plugin -date: 2024-11-29 +date: 2024-12-03 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 72a9d3e477cf2..e0021c7cc2165 100644 --- a/api_docs/kbn_shared_ux_card_no_data.mdx +++ b/api_docs/kbn_shared_ux_card_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-card-no-data title: "@kbn/shared-ux-card-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-card-no-data plugin -date: 2024-11-29 +date: 2024-12-03 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 b3979e843967e..9ec03f02229b8 100644 --- a/api_docs/kbn_shared_ux_card_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_card_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-card-no-data-mocks title: "@kbn/shared-ux-card-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-card-no-data-mocks plugin -date: 2024-11-29 +date: 2024-12-03 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 1ff372fd67edc..76154e77fe208 100644 --- a/api_docs/kbn_shared_ux_chrome_navigation.mdx +++ b/api_docs/kbn_shared_ux_chrome_navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-chrome-navigation title: "@kbn/shared-ux-chrome-navigation" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-chrome-navigation plugin -date: 2024-11-29 +date: 2024-12-03 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 f503d8c537b86..a17e903b64496 100644 --- a/api_docs/kbn_shared_ux_error_boundary.mdx +++ b/api_docs/kbn_shared_ux_error_boundary.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-error-boundary title: "@kbn/shared-ux-error-boundary" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-error-boundary plugin -date: 2024-11-29 +date: 2024-12-03 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 70b1d66a93ffa..d9b5c7ee64b38 100644 --- a/api_docs/kbn_shared_ux_file_context.mdx +++ b/api_docs/kbn_shared_ux_file_context.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-context title: "@kbn/shared-ux-file-context" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-context plugin -date: 2024-11-29 +date: 2024-12-03 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 df4aecb97179b..7dd85fe4f2e9b 100644 --- a/api_docs/kbn_shared_ux_file_image.mdx +++ b/api_docs/kbn_shared_ux_file_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-image title: "@kbn/shared-ux-file-image" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-image plugin -date: 2024-11-29 +date: 2024-12-03 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 65aeff56e3b17..fe89aed708712 100644 --- a/api_docs/kbn_shared_ux_file_image_mocks.mdx +++ b/api_docs/kbn_shared_ux_file_image_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-image-mocks title: "@kbn/shared-ux-file-image-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-image-mocks plugin -date: 2024-11-29 +date: 2024-12-03 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 dfa0901535053..6db103816744f 100644 --- a/api_docs/kbn_shared_ux_file_mocks.mdx +++ b/api_docs/kbn_shared_ux_file_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-mocks title: "@kbn/shared-ux-file-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-mocks plugin -date: 2024-11-29 +date: 2024-12-03 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 941064ee96a20..db98855c73e14 100644 --- a/api_docs/kbn_shared_ux_file_picker.mdx +++ b/api_docs/kbn_shared_ux_file_picker.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-picker title: "@kbn/shared-ux-file-picker" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-picker plugin -date: 2024-11-29 +date: 2024-12-03 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 bab455388139a..5aaa50af518fd 100644 --- a/api_docs/kbn_shared_ux_file_types.mdx +++ b/api_docs/kbn_shared_ux_file_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-types title: "@kbn/shared-ux-file-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-types plugin -date: 2024-11-29 +date: 2024-12-03 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 50011321a9c29..900dd0cc61236 100644 --- a/api_docs/kbn_shared_ux_file_upload.mdx +++ b/api_docs/kbn_shared_ux_file_upload.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-upload title: "@kbn/shared-ux-file-upload" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-upload plugin -date: 2024-11-29 +date: 2024-12-03 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 113c763279da7..c165fada0a6b8 100644 --- a/api_docs/kbn_shared_ux_file_util.mdx +++ b/api_docs/kbn_shared_ux_file_util.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-util title: "@kbn/shared-ux-file-util" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-util plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-util'] --- import kbnSharedUxFileUtilObj from './kbn_shared_ux_file_util.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_link_redirect_app.mdx b/api_docs/kbn_shared_ux_link_redirect_app.mdx index 4451f89a340c2..fb041bb4b4dff 100644 --- a/api_docs/kbn_shared_ux_link_redirect_app.mdx +++ b/api_docs/kbn_shared_ux_link_redirect_app.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-link-redirect-app title: "@kbn/shared-ux-link-redirect-app" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-link-redirect-app plugin -date: 2024-11-29 +date: 2024-12-03 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 53a4cf0e554f9..64c89f8895884 100644 --- a/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx +++ b/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-link-redirect-app-mocks title: "@kbn/shared-ux-link-redirect-app-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-link-redirect-app-mocks plugin -date: 2024-11-29 +date: 2024-12-03 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 1a9cb10981405..45b634682af66 100644 --- a/api_docs/kbn_shared_ux_markdown.mdx +++ b/api_docs/kbn_shared_ux_markdown.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-markdown title: "@kbn/shared-ux-markdown" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-markdown plugin -date: 2024-11-29 +date: 2024-12-03 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 42c719b26d617..99b41b41931c3 100644 --- a/api_docs/kbn_shared_ux_markdown_mocks.mdx +++ b/api_docs/kbn_shared_ux_markdown_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-markdown-mocks title: "@kbn/shared-ux-markdown-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-markdown-mocks plugin -date: 2024-11-29 +date: 2024-12-03 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 be40b509f1806..c5b24bded152a 100644 --- a/api_docs/kbn_shared_ux_page_analytics_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_analytics_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-analytics-no-data title: "@kbn/shared-ux-page-analytics-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-analytics-no-data plugin -date: 2024-11-29 +date: 2024-12-03 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 04085106c9b2d..2c2fc5d749455 100644 --- a/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-analytics-no-data-mocks title: "@kbn/shared-ux-page-analytics-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-analytics-no-data-mocks plugin -date: 2024-11-29 +date: 2024-12-03 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 f2136891ca882..1de155e2e8a79 100644 --- a/api_docs/kbn_shared_ux_page_kibana_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-no-data title: "@kbn/shared-ux-page-kibana-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-no-data plugin -date: 2024-11-29 +date: 2024-12-03 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 88ff4693f392b..1283451195537 100644 --- a/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-no-data-mocks title: "@kbn/shared-ux-page-kibana-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-no-data-mocks plugin -date: 2024-11-29 +date: 2024-12-03 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 a512f20ac0b63..8827e97e3052b 100644 --- a/api_docs/kbn_shared_ux_page_kibana_template.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_template.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-template title: "@kbn/shared-ux-page-kibana-template" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-template plugin -date: 2024-11-29 +date: 2024-12-03 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 a4cfb0d64dab2..69a3478aed4b7 100644 --- a/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-template-mocks title: "@kbn/shared-ux-page-kibana-template-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-template-mocks plugin -date: 2024-11-29 +date: 2024-12-03 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 53472233fc2d6..be2cff9d73bd0 100644 --- a/api_docs/kbn_shared_ux_page_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data title: "@kbn/shared-ux-page-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data plugin -date: 2024-11-29 +date: 2024-12-03 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 e3eaa64da6fbb..81784c4767202 100644 --- a/api_docs/kbn_shared_ux_page_no_data_config.mdx +++ b/api_docs/kbn_shared_ux_page_no_data_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data-config title: "@kbn/shared-ux-page-no-data-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data-config plugin -date: 2024-11-29 +date: 2024-12-03 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 1d7dbd7a034d0..a57150fe66db4 100644 --- a/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data-config-mocks title: "@kbn/shared-ux-page-no-data-config-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data-config-mocks plugin -date: 2024-11-29 +date: 2024-12-03 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 e0e91ed815a60..079c87c939d2c 100644 --- a/api_docs/kbn_shared_ux_page_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data-mocks title: "@kbn/shared-ux-page-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data-mocks plugin -date: 2024-11-29 +date: 2024-12-03 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 e33aa992c35d2..6d4583ce83a9b 100644 --- a/api_docs/kbn_shared_ux_page_solution_nav.mdx +++ b/api_docs/kbn_shared_ux_page_solution_nav.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-solution-nav title: "@kbn/shared-ux-page-solution-nav" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-solution-nav plugin -date: 2024-11-29 +date: 2024-12-03 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 f326bc30b4322..18b7993305585 100644 --- a/api_docs/kbn_shared_ux_prompt_no_data_views.mdx +++ b/api_docs/kbn_shared_ux_prompt_no_data_views.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-prompt-no-data-views title: "@kbn/shared-ux-prompt-no-data-views" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-prompt-no-data-views plugin -date: 2024-11-29 +date: 2024-12-03 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 39369a3afa063..97f657a264c89 100644 --- a/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx +++ b/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-prompt-no-data-views-mocks title: "@kbn/shared-ux-prompt-no-data-views-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-prompt-no-data-views-mocks plugin -date: 2024-11-29 +date: 2024-12-03 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 623eccec1b793..7e4a649020b6d 100644 --- a/api_docs/kbn_shared_ux_prompt_not_found.mdx +++ b/api_docs/kbn_shared_ux_prompt_not_found.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-prompt-not-found title: "@kbn/shared-ux-prompt-not-found" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-prompt-not-found plugin -date: 2024-11-29 +date: 2024-12-03 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 1110f2bb3aa54..e0fad918bab42 100644 --- a/api_docs/kbn_shared_ux_router.mdx +++ b/api_docs/kbn_shared_ux_router.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-router title: "@kbn/shared-ux-router" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-router plugin -date: 2024-11-29 +date: 2024-12-03 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 25036972f17ac..c90d09d43a625 100644 --- a/api_docs/kbn_shared_ux_router_mocks.mdx +++ b/api_docs/kbn_shared_ux_router_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-router-mocks title: "@kbn/shared-ux-router-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-router-mocks plugin -date: 2024-11-29 +date: 2024-12-03 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 99819ca4d5e93..820ab7568a2fb 100644 --- a/api_docs/kbn_shared_ux_storybook_config.mdx +++ b/api_docs/kbn_shared_ux_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-storybook-config title: "@kbn/shared-ux-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-storybook-config plugin -date: 2024-11-29 +date: 2024-12-03 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 c02e9843d8ab8..f19e0a6f0d20b 100644 --- a/api_docs/kbn_shared_ux_storybook_mock.mdx +++ b/api_docs/kbn_shared_ux_storybook_mock.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-storybook-mock title: "@kbn/shared-ux-storybook-mock" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-storybook-mock plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-storybook-mock'] --- import kbnSharedUxStorybookMockObj from './kbn_shared_ux_storybook_mock.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_tabbed_modal.mdx b/api_docs/kbn_shared_ux_tabbed_modal.mdx index f60807b71be66..96f5752bb324e 100644 --- a/api_docs/kbn_shared_ux_tabbed_modal.mdx +++ b/api_docs/kbn_shared_ux_tabbed_modal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-tabbed-modal title: "@kbn/shared-ux-tabbed-modal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-tabbed-modal plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-tabbed-modal'] --- import kbnSharedUxTabbedModalObj from './kbn_shared_ux_tabbed_modal.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_table_persist.mdx b/api_docs/kbn_shared_ux_table_persist.mdx index 7438f3c2cd620..0263713730b97 100644 --- a/api_docs/kbn_shared_ux_table_persist.mdx +++ b/api_docs/kbn_shared_ux_table_persist.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-table-persist title: "@kbn/shared-ux-table-persist" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-table-persist plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-table-persist'] --- import kbnSharedUxTablePersistObj from './kbn_shared_ux_table_persist.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_utility.mdx b/api_docs/kbn_shared_ux_utility.mdx index e497c11e3a6b7..2a99930e98c06 100644 --- a/api_docs/kbn_shared_ux_utility.mdx +++ b/api_docs/kbn_shared_ux_utility.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-utility title: "@kbn/shared-ux-utility" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-utility plugin -date: 2024-11-29 +date: 2024-12-03 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.devdocs.json b/api_docs/kbn_slo_schema.devdocs.json index 13f17bcf471b8..57d2f788dc036 100644 --- a/api_docs/kbn_slo_schema.devdocs.json +++ b/api_docs/kbn_slo_schema.devdocs.json @@ -606,7 +606,7 @@ "label": "CreateSLOInput", "description": [], "signature": [ - "{ name: string; description: string; indicator: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.synthetics.availability\"; params: { monitorIds: { value: string; label: string; }[]; index: string; } & { tags?: { value: string; label: string; }[] | undefined; projects?: { value: string; label: string; }[] | undefined; filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; good: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; }; total: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.metric.custom\"; params: { index: string; good: { metrics: (({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; }; total: { metrics: (({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.metric.timeslice\"; params: { index: string; metric: { metrics: (({ name: string; aggregation: \"min\" | \"max\" | \"sum\" | \"avg\" | \"cardinality\" | \"last_value\" | \"std_deviation\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"percentile\"; field: string; percentile: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; threshold: number; comparator: \"GT\" | \"GTE\" | \"LT\" | \"LTE\"; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.histogram.custom\"; params: { index: string; timestampField: string; good: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }); total: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }); } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; }; timeWindow: { duration: string; type: \"rolling\"; } | { duration: string; type: \"calendarAligned\"; }; budgetingMethod: \"occurrences\" | \"timeslices\"; objective: { target: number; } & { timesliceTarget?: number | undefined; timesliceWindow?: string | undefined; }; } & { id?: string | undefined; settings?: { syncDelay?: string | undefined; frequency?: string | undefined; preventInitialBackfill?: boolean | undefined; } | undefined; tags?: string[] | undefined; groupBy?: string | string[] | undefined; revision?: number | undefined; }" + "{ name: string; description: string; indicator: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.synthetics.availability\"; params: { monitorIds: { value: string; label: string; }[]; index: string; } & { tags?: { value: string; label: string; }[] | undefined; projects?: { value: string; label: string; }[] | undefined; filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; good: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; }; total: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.metric.custom\"; params: { index: string; good: { metrics: (({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; }; total: { metrics: (({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.metric.timeslice\"; params: { index: string; metric: { metrics: (({ name: string; aggregation: \"min\" | \"max\" | \"sum\" | \"avg\" | \"cardinality\" | \"last_value\" | \"std_deviation\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"percentile\"; field: string; percentile: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; threshold: number; comparator: \"GT\" | \"GTE\" | \"LT\" | \"LTE\"; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.histogram.custom\"; params: { index: string; timestampField: string; good: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }); total: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }); } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; }; timeWindow: { duration: string; type: \"rolling\"; } | { duration: string; type: \"calendarAligned\"; }; budgetingMethod: \"occurrences\" | \"timeslices\"; objective: { target: number; } & { timesliceTarget?: number | undefined; timesliceWindow?: string | undefined; }; } & { id?: string | undefined; settings?: { syncDelay?: string | undefined; frequency?: string | undefined; preventInitialBackfill?: boolean | undefined; syncField?: string | null | undefined; } | undefined; tags?: string[] | undefined; groupBy?: string | string[] | undefined; revision?: number | undefined; }" ], "path": "x-pack/packages/kbn-slo-schema/src/rest_specs/routes/create.ts", "deprecated": false, @@ -661,7 +661,7 @@ "section": "def-common.Duration", "text": "Duration" }, - " | undefined; preventInitialBackfill?: boolean | undefined; } | undefined; tags?: string[] | undefined; groupBy?: string | string[] | undefined; revision?: number | undefined; }" + " | undefined; preventInitialBackfill?: boolean | undefined; syncField?: string | null | undefined; } | undefined; tags?: string[] | undefined; groupBy?: string | string[] | undefined; revision?: number | undefined; }" ], "path": "x-pack/packages/kbn-slo-schema/src/rest_specs/routes/create.ts", "deprecated": false, @@ -835,7 +835,7 @@ "label": "FindSLODefinitionsResponse", "description": [], "signature": [ - "{ page: number; perPage: number; total: number; results: { id: string; name: string; description: string; indicator: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.synthetics.availability\"; params: { monitorIds: { value: string; label: string; }[]; index: string; } & { tags?: { value: string; label: string; }[] | undefined; projects?: { value: string; label: string; }[] | undefined; filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; good: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; }; total: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.metric.custom\"; params: { index: string; good: { metrics: (({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; }; total: { metrics: (({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.metric.timeslice\"; params: { index: string; metric: { metrics: (({ name: string; aggregation: \"min\" | \"max\" | \"sum\" | \"avg\" | \"cardinality\" | \"last_value\" | \"std_deviation\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"percentile\"; field: string; percentile: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; threshold: number; comparator: \"GT\" | \"GTE\" | \"LT\" | \"LTE\"; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.histogram.custom\"; params: { index: string; timestampField: string; good: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }); total: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }); } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; }; timeWindow: { duration: string; type: \"rolling\"; } | { duration: string; type: \"calendarAligned\"; }; budgetingMethod: \"occurrences\" | \"timeslices\"; objective: { target: number; } & { timesliceTarget?: number | undefined; timesliceWindow?: string | undefined; }; settings: { syncDelay: string; frequency: string; preventInitialBackfill: boolean; }; revision: number; enabled: boolean; tags: string[]; createdAt: string; updatedAt: string; groupBy: string | string[]; version: number; }[]; }" + "{ page: number; perPage: number; total: number; results: { id: string; name: string; description: string; indicator: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.synthetics.availability\"; params: { monitorIds: { value: string; label: string; }[]; index: string; } & { tags?: { value: string; label: string; }[] | undefined; projects?: { value: string; label: string; }[] | undefined; filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; good: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; }; total: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.metric.custom\"; params: { index: string; good: { metrics: (({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; }; total: { metrics: (({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.metric.timeslice\"; params: { index: string; metric: { metrics: (({ name: string; aggregation: \"min\" | \"max\" | \"sum\" | \"avg\" | \"cardinality\" | \"last_value\" | \"std_deviation\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"percentile\"; field: string; percentile: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; threshold: number; comparator: \"GT\" | \"GTE\" | \"LT\" | \"LTE\"; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.histogram.custom\"; params: { index: string; timestampField: string; good: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }); total: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }); } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; }; timeWindow: { duration: string; type: \"rolling\"; } | { duration: string; type: \"calendarAligned\"; }; budgetingMethod: \"occurrences\" | \"timeslices\"; objective: { target: number; } & { timesliceTarget?: number | undefined; timesliceWindow?: string | undefined; }; settings: { syncDelay: string; frequency: string; preventInitialBackfill: boolean; } & { syncField?: string | null | undefined; }; revision: number; enabled: boolean; tags: string[]; createdAt: string; updatedAt: string; groupBy: string | string[]; version: number; }[]; }" ], "path": "x-pack/packages/kbn-slo-schema/src/rest_specs/routes/find_definition.ts", "deprecated": false, @@ -895,7 +895,7 @@ "label": "FindSLOResponse", "description": [], "signature": [ - "{ page: number; perPage: number; total: number; results: ({ id: string; name: string; description: string; indicator: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.synthetics.availability\"; params: { monitorIds: { value: string; label: string; }[]; index: string; } & { tags?: { value: string; label: string; }[] | undefined; projects?: { value: string; label: string; }[] | undefined; filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; good: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; }; total: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.metric.custom\"; params: { index: string; good: { metrics: (({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; }; total: { metrics: (({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.metric.timeslice\"; params: { index: string; metric: { metrics: (({ name: string; aggregation: \"min\" | \"max\" | \"sum\" | \"avg\" | \"cardinality\" | \"last_value\" | \"std_deviation\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"percentile\"; field: string; percentile: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; threshold: number; comparator: \"GT\" | \"GTE\" | \"LT\" | \"LTE\"; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.histogram.custom\"; params: { index: string; timestampField: string; good: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }); total: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }); } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; }; timeWindow: { duration: string; type: \"rolling\"; } | { duration: string; type: \"calendarAligned\"; }; budgetingMethod: \"occurrences\" | \"timeslices\"; objective: { target: number; } & { timesliceTarget?: number | undefined; timesliceWindow?: string | undefined; }; settings: { syncDelay: string; frequency: string; preventInitialBackfill: boolean; }; revision: number; enabled: boolean; tags: string[]; createdAt: string; updatedAt: string; groupBy: string | string[]; version: number; } & { summary: { status: \"HEALTHY\" | \"NO_DATA\" | \"DEGRADING\" | \"VIOLATED\"; sliValue: number; errorBudget: { initial: number; consumed: number; remaining: number; isEstimated: boolean; }; fiveMinuteBurnRate: number; oneHourBurnRate: number; oneDayBurnRate: number; } & { summaryUpdatedAt?: string | null | undefined; }; groupings: { [x: string]: string | number; }; } & { instanceId?: string | undefined; meta?: { synthetics?: { monitorId: string; locationId: string; configId: string; } | undefined; } | undefined; remote?: { remoteName: string; kibanaUrl: string; } | undefined; })[]; }" + "{ page: number; perPage: number; total: number; results: ({ id: string; name: string; description: string; indicator: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.synthetics.availability\"; params: { monitorIds: { value: string; label: string; }[]; index: string; } & { tags?: { value: string; label: string; }[] | undefined; projects?: { value: string; label: string; }[] | undefined; filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; good: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; }; total: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.metric.custom\"; params: { index: string; good: { metrics: (({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; }; total: { metrics: (({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.metric.timeslice\"; params: { index: string; metric: { metrics: (({ name: string; aggregation: \"min\" | \"max\" | \"sum\" | \"avg\" | \"cardinality\" | \"last_value\" | \"std_deviation\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"percentile\"; field: string; percentile: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; threshold: number; comparator: \"GT\" | \"GTE\" | \"LT\" | \"LTE\"; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.histogram.custom\"; params: { index: string; timestampField: string; good: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }); total: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }); } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; }; timeWindow: { duration: string; type: \"rolling\"; } | { duration: string; type: \"calendarAligned\"; }; budgetingMethod: \"occurrences\" | \"timeslices\"; objective: { target: number; } & { timesliceTarget?: number | undefined; timesliceWindow?: string | undefined; }; settings: { syncDelay: string; frequency: string; preventInitialBackfill: boolean; } & { syncField?: string | null | undefined; }; revision: number; enabled: boolean; tags: string[]; createdAt: string; updatedAt: string; groupBy: string | string[]; version: number; } & { summary: { status: \"HEALTHY\" | \"NO_DATA\" | \"DEGRADING\" | \"VIOLATED\"; sliValue: number; errorBudget: { initial: number; consumed: number; remaining: number; isEstimated: boolean; }; fiveMinuteBurnRate: number; oneHourBurnRate: number; oneDayBurnRate: number; } & { summaryUpdatedAt?: string | null | undefined; }; groupings: { [x: string]: string | number; }; } & { instanceId?: string | undefined; meta?: { synthetics?: { monitorId: string; locationId: string; configId: string; } | undefined; } | undefined; remote?: { remoteName: string; kibanaUrl: string; } | undefined; })[]; }" ], "path": "x-pack/packages/kbn-slo-schema/src/rest_specs/routes/find.ts", "deprecated": false, @@ -993,7 +993,7 @@ "label": "GetSLOResponse", "description": [], "signature": [ - "{ id: string; name: string; description: string; indicator: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.synthetics.availability\"; params: { monitorIds: { value: string; label: string; }[]; index: string; } & { tags?: { value: string; label: string; }[] | undefined; projects?: { value: string; label: string; }[] | undefined; filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; good: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; }; total: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.metric.custom\"; params: { index: string; good: { metrics: (({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; }; total: { metrics: (({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.metric.timeslice\"; params: { index: string; metric: { metrics: (({ name: string; aggregation: \"min\" | \"max\" | \"sum\" | \"avg\" | \"cardinality\" | \"last_value\" | \"std_deviation\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"percentile\"; field: string; percentile: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; threshold: number; comparator: \"GT\" | \"GTE\" | \"LT\" | \"LTE\"; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.histogram.custom\"; params: { index: string; timestampField: string; good: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }); total: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }); } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; }; timeWindow: { duration: string; type: \"rolling\"; } | { duration: string; type: \"calendarAligned\"; }; budgetingMethod: \"occurrences\" | \"timeslices\"; objective: { target: number; } & { timesliceTarget?: number | undefined; timesliceWindow?: string | undefined; }; settings: { syncDelay: string; frequency: string; preventInitialBackfill: boolean; }; revision: number; enabled: boolean; tags: string[]; createdAt: string; updatedAt: string; groupBy: string | string[]; version: number; } & { summary: { status: \"HEALTHY\" | \"NO_DATA\" | \"DEGRADING\" | \"VIOLATED\"; sliValue: number; errorBudget: { initial: number; consumed: number; remaining: number; isEstimated: boolean; }; fiveMinuteBurnRate: number; oneHourBurnRate: number; oneDayBurnRate: number; } & { summaryUpdatedAt?: string | null | undefined; }; groupings: { [x: string]: string | number; }; } & { instanceId?: string | undefined; meta?: { synthetics?: { monitorId: string; locationId: string; configId: string; } | undefined; } | undefined; remote?: { remoteName: string; kibanaUrl: string; } | undefined; }" + "{ id: string; name: string; description: string; indicator: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.synthetics.availability\"; params: { monitorIds: { value: string; label: string; }[]; index: string; } & { tags?: { value: string; label: string; }[] | undefined; projects?: { value: string; label: string; }[] | undefined; filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; good: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; }; total: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.metric.custom\"; params: { index: string; good: { metrics: (({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; }; total: { metrics: (({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.metric.timeslice\"; params: { index: string; metric: { metrics: (({ name: string; aggregation: \"min\" | \"max\" | \"sum\" | \"avg\" | \"cardinality\" | \"last_value\" | \"std_deviation\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"percentile\"; field: string; percentile: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; threshold: number; comparator: \"GT\" | \"GTE\" | \"LT\" | \"LTE\"; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.histogram.custom\"; params: { index: string; timestampField: string; good: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }); total: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }); } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; }; timeWindow: { duration: string; type: \"rolling\"; } | { duration: string; type: \"calendarAligned\"; }; budgetingMethod: \"occurrences\" | \"timeslices\"; objective: { target: number; } & { timesliceTarget?: number | undefined; timesliceWindow?: string | undefined; }; settings: { syncDelay: string; frequency: string; preventInitialBackfill: boolean; } & { syncField?: string | null | undefined; }; revision: number; enabled: boolean; tags: string[]; createdAt: string; updatedAt: string; groupBy: string | string[]; version: number; } & { summary: { status: \"HEALTHY\" | \"NO_DATA\" | \"DEGRADING\" | \"VIOLATED\"; sliValue: number; errorBudget: { initial: number; consumed: number; remaining: number; isEstimated: boolean; }; fiveMinuteBurnRate: number; oneHourBurnRate: number; oneDayBurnRate: number; } & { summaryUpdatedAt?: string | null | undefined; }; groupings: { [x: string]: string | number; }; } & { instanceId?: string | undefined; meta?: { synthetics?: { monitorId: string; locationId: string; configId: string; } | undefined; } | undefined; remote?: { remoteName: string; kibanaUrl: string; } | undefined; }" ], "path": "x-pack/packages/kbn-slo-schema/src/rest_specs/routes/get.ts", "deprecated": false, @@ -1263,7 +1263,7 @@ "label": "ResetSLOResponse", "description": [], "signature": [ - "{ id: string; name: string; description: string; indicator: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.synthetics.availability\"; params: { monitorIds: { value: string; label: string; }[]; index: string; } & { tags?: { value: string; label: string; }[] | undefined; projects?: { value: string; label: string; }[] | undefined; filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; good: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; }; total: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.metric.custom\"; params: { index: string; good: { metrics: (({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; }; total: { metrics: (({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.metric.timeslice\"; params: { index: string; metric: { metrics: (({ name: string; aggregation: \"min\" | \"max\" | \"sum\" | \"avg\" | \"cardinality\" | \"last_value\" | \"std_deviation\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"percentile\"; field: string; percentile: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; threshold: number; comparator: \"GT\" | \"GTE\" | \"LT\" | \"LTE\"; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.histogram.custom\"; params: { index: string; timestampField: string; good: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }); total: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }); } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; }; timeWindow: { duration: string; type: \"rolling\"; } | { duration: string; type: \"calendarAligned\"; }; budgetingMethod: \"occurrences\" | \"timeslices\"; objective: { target: number; } & { timesliceTarget?: number | undefined; timesliceWindow?: string | undefined; }; settings: { syncDelay: string; frequency: string; preventInitialBackfill: boolean; }; revision: number; enabled: boolean; tags: string[]; createdAt: string; updatedAt: string; groupBy: string | string[]; version: number; }" + "{ id: string; name: string; description: string; indicator: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.synthetics.availability\"; params: { monitorIds: { value: string; label: string; }[]; index: string; } & { tags?: { value: string; label: string; }[] | undefined; projects?: { value: string; label: string; }[] | undefined; filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; good: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; }; total: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.metric.custom\"; params: { index: string; good: { metrics: (({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; }; total: { metrics: (({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.metric.timeslice\"; params: { index: string; metric: { metrics: (({ name: string; aggregation: \"min\" | \"max\" | \"sum\" | \"avg\" | \"cardinality\" | \"last_value\" | \"std_deviation\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"percentile\"; field: string; percentile: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; threshold: number; comparator: \"GT\" | \"GTE\" | \"LT\" | \"LTE\"; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.histogram.custom\"; params: { index: string; timestampField: string; good: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }); total: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }); } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; }; timeWindow: { duration: string; type: \"rolling\"; } | { duration: string; type: \"calendarAligned\"; }; budgetingMethod: \"occurrences\" | \"timeslices\"; objective: { target: number; } & { timesliceTarget?: number | undefined; timesliceWindow?: string | undefined; }; settings: { syncDelay: string; frequency: string; preventInitialBackfill: boolean; } & { syncField?: string | null | undefined; }; revision: number; enabled: boolean; tags: string[]; createdAt: string; updatedAt: string; groupBy: string | string[]; version: number; }" ], "path": "x-pack/packages/kbn-slo-schema/src/rest_specs/routes/reset.ts", "deprecated": false, @@ -1278,7 +1278,7 @@ "label": "SLODefinitionResponse", "description": [], "signature": [ - "{ id: string; name: string; description: string; indicator: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.synthetics.availability\"; params: { monitorIds: { value: string; label: string; }[]; index: string; } & { tags?: { value: string; label: string; }[] | undefined; projects?: { value: string; label: string; }[] | undefined; filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; good: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; }; total: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.metric.custom\"; params: { index: string; good: { metrics: (({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; }; total: { metrics: (({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.metric.timeslice\"; params: { index: string; metric: { metrics: (({ name: string; aggregation: \"min\" | \"max\" | \"sum\" | \"avg\" | \"cardinality\" | \"last_value\" | \"std_deviation\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"percentile\"; field: string; percentile: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; threshold: number; comparator: \"GT\" | \"GTE\" | \"LT\" | \"LTE\"; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.histogram.custom\"; params: { index: string; timestampField: string; good: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }); total: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }); } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; }; timeWindow: { duration: string; type: \"rolling\"; } | { duration: string; type: \"calendarAligned\"; }; budgetingMethod: \"occurrences\" | \"timeslices\"; objective: { target: number; } & { timesliceTarget?: number | undefined; timesliceWindow?: string | undefined; }; settings: { syncDelay: string; frequency: string; preventInitialBackfill: boolean; }; revision: number; enabled: boolean; tags: string[]; createdAt: string; updatedAt: string; groupBy: string | string[]; version: number; }" + "{ id: string; name: string; description: string; indicator: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.synthetics.availability\"; params: { monitorIds: { value: string; label: string; }[]; index: string; } & { tags?: { value: string; label: string; }[] | undefined; projects?: { value: string; label: string; }[] | undefined; filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; good: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; }; total: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.metric.custom\"; params: { index: string; good: { metrics: (({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; }; total: { metrics: (({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.metric.timeslice\"; params: { index: string; metric: { metrics: (({ name: string; aggregation: \"min\" | \"max\" | \"sum\" | \"avg\" | \"cardinality\" | \"last_value\" | \"std_deviation\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"percentile\"; field: string; percentile: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; threshold: number; comparator: \"GT\" | \"GTE\" | \"LT\" | \"LTE\"; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.histogram.custom\"; params: { index: string; timestampField: string; good: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }); total: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }); } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; }; timeWindow: { duration: string; type: \"rolling\"; } | { duration: string; type: \"calendarAligned\"; }; budgetingMethod: \"occurrences\" | \"timeslices\"; objective: { target: number; } & { timesliceTarget?: number | undefined; timesliceWindow?: string | undefined; }; settings: { syncDelay: string; frequency: string; preventInitialBackfill: boolean; } & { syncField?: string | null | undefined; }; revision: number; enabled: boolean; tags: string[]; createdAt: string; updatedAt: string; groupBy: string | string[]; version: number; }" ], "path": "x-pack/packages/kbn-slo-schema/src/rest_specs/slo.ts", "deprecated": false, @@ -1293,7 +1293,7 @@ "label": "SLOWithSummaryResponse", "description": [], "signature": [ - "{ id: string; name: string; description: string; indicator: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.synthetics.availability\"; params: { monitorIds: { value: string; label: string; }[]; index: string; } & { tags?: { value: string; label: string; }[] | undefined; projects?: { value: string; label: string; }[] | undefined; filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; good: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; }; total: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.metric.custom\"; params: { index: string; good: { metrics: (({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; }; total: { metrics: (({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.metric.timeslice\"; params: { index: string; metric: { metrics: (({ name: string; aggregation: \"min\" | \"max\" | \"sum\" | \"avg\" | \"cardinality\" | \"last_value\" | \"std_deviation\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"percentile\"; field: string; percentile: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; threshold: number; comparator: \"GT\" | \"GTE\" | \"LT\" | \"LTE\"; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.histogram.custom\"; params: { index: string; timestampField: string; good: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }); total: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }); } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; }; timeWindow: { duration: string; type: \"rolling\"; } | { duration: string; type: \"calendarAligned\"; }; budgetingMethod: \"occurrences\" | \"timeslices\"; objective: { target: number; } & { timesliceTarget?: number | undefined; timesliceWindow?: string | undefined; }; settings: { syncDelay: string; frequency: string; preventInitialBackfill: boolean; }; revision: number; enabled: boolean; tags: string[]; createdAt: string; updatedAt: string; groupBy: string | string[]; version: number; } & { summary: { status: \"HEALTHY\" | \"NO_DATA\" | \"DEGRADING\" | \"VIOLATED\"; sliValue: number; errorBudget: { initial: number; consumed: number; remaining: number; isEstimated: boolean; }; fiveMinuteBurnRate: number; oneHourBurnRate: number; oneDayBurnRate: number; } & { summaryUpdatedAt?: string | null | undefined; }; groupings: { [x: string]: string | number; }; } & { instanceId?: string | undefined; meta?: { synthetics?: { monitorId: string; locationId: string; configId: string; } | undefined; } | undefined; remote?: { remoteName: string; kibanaUrl: string; } | undefined; }" + "{ id: string; name: string; description: string; indicator: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.synthetics.availability\"; params: { monitorIds: { value: string; label: string; }[]; index: string; } & { tags?: { value: string; label: string; }[] | undefined; projects?: { value: string; label: string; }[] | undefined; filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; good: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; }; total: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.metric.custom\"; params: { index: string; good: { metrics: (({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; }; total: { metrics: (({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.metric.timeslice\"; params: { index: string; metric: { metrics: (({ name: string; aggregation: \"min\" | \"max\" | \"sum\" | \"avg\" | \"cardinality\" | \"last_value\" | \"std_deviation\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"percentile\"; field: string; percentile: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; threshold: number; comparator: \"GT\" | \"GTE\" | \"LT\" | \"LTE\"; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.histogram.custom\"; params: { index: string; timestampField: string; good: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }); total: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }); } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; }; timeWindow: { duration: string; type: \"rolling\"; } | { duration: string; type: \"calendarAligned\"; }; budgetingMethod: \"occurrences\" | \"timeslices\"; objective: { target: number; } & { timesliceTarget?: number | undefined; timesliceWindow?: string | undefined; }; settings: { syncDelay: string; frequency: string; preventInitialBackfill: boolean; } & { syncField?: string | null | undefined; }; revision: number; enabled: boolean; tags: string[]; createdAt: string; updatedAt: string; groupBy: string | string[]; version: number; } & { summary: { status: \"HEALTHY\" | \"NO_DATA\" | \"DEGRADING\" | \"VIOLATED\"; sliValue: number; errorBudget: { initial: number; consumed: number; remaining: number; isEstimated: boolean; }; fiveMinuteBurnRate: number; oneHourBurnRate: number; oneDayBurnRate: number; } & { summaryUpdatedAt?: string | null | undefined; }; groupings: { [x: string]: string | number; }; } & { instanceId?: string | undefined; meta?: { synthetics?: { monitorId: string; locationId: string; configId: string; } | undefined; } | undefined; remote?: { remoteName: string; kibanaUrl: string; } | undefined; }" ], "path": "x-pack/packages/kbn-slo-schema/src/rest_specs/slo.ts", "deprecated": false, @@ -1398,7 +1398,7 @@ "label": "UpdateSLOInput", "description": [], "signature": [ - "{ name?: string | undefined; description?: string | undefined; indicator?: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.synthetics.availability\"; params: { monitorIds: { value: string; label: string; }[]; index: string; } & { tags?: { value: string; label: string; }[] | undefined; projects?: { value: string; label: string; }[] | undefined; filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; good: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; }; total: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.metric.custom\"; params: { index: string; good: { metrics: (({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; }; total: { metrics: (({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.metric.timeslice\"; params: { index: string; metric: { metrics: (({ name: string; aggregation: \"min\" | \"max\" | \"sum\" | \"avg\" | \"cardinality\" | \"last_value\" | \"std_deviation\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"percentile\"; field: string; percentile: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; threshold: number; comparator: \"GT\" | \"GTE\" | \"LT\" | \"LTE\"; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.histogram.custom\"; params: { index: string; timestampField: string; good: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }); total: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }); } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | undefined; timeWindow?: { duration: string; type: \"rolling\"; } | { duration: string; type: \"calendarAligned\"; } | undefined; budgetingMethod?: \"occurrences\" | \"timeslices\" | undefined; objective?: ({ target: number; } & { timesliceTarget?: number | undefined; timesliceWindow?: string | undefined; }) | undefined; settings?: { syncDelay?: string | undefined; frequency?: string | undefined; preventInitialBackfill?: boolean | undefined; } | undefined; tags?: string[] | undefined; groupBy?: string | string[] | undefined; }" + "{ name?: string | undefined; description?: string | undefined; indicator?: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.synthetics.availability\"; params: { monitorIds: { value: string; label: string; }[]; index: string; } & { tags?: { value: string; label: string; }[] | undefined; projects?: { value: string; label: string; }[] | undefined; filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; good: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; }; total: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.metric.custom\"; params: { index: string; good: { metrics: (({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; }; total: { metrics: (({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.metric.timeslice\"; params: { index: string; metric: { metrics: (({ name: string; aggregation: \"min\" | \"max\" | \"sum\" | \"avg\" | \"cardinality\" | \"last_value\" | \"std_deviation\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"percentile\"; field: string; percentile: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; threshold: number; comparator: \"GT\" | \"GTE\" | \"LT\" | \"LTE\"; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.histogram.custom\"; params: { index: string; timestampField: string; good: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }); total: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }); } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | undefined; timeWindow?: { duration: string; type: \"rolling\"; } | { duration: string; type: \"calendarAligned\"; } | undefined; budgetingMethod?: \"occurrences\" | \"timeslices\" | undefined; objective?: ({ target: number; } & { timesliceTarget?: number | undefined; timesliceWindow?: string | undefined; }) | undefined; settings?: { syncDelay?: string | undefined; frequency?: string | undefined; preventInitialBackfill?: boolean | undefined; syncField?: string | null | undefined; } | undefined; tags?: string[] | undefined; groupBy?: string | string[] | undefined; }" ], "path": "x-pack/packages/kbn-slo-schema/src/rest_specs/routes/update.ts", "deprecated": false, @@ -1453,7 +1453,7 @@ "section": "def-common.Duration", "text": "Duration" }, - " | undefined; preventInitialBackfill?: boolean | undefined; } | undefined; tags?: string[] | undefined; groupBy?: string | string[] | undefined; }" + " | undefined; preventInitialBackfill?: boolean | undefined; syncField?: string | null | undefined; } | undefined; tags?: string[] | undefined; groupBy?: string | string[] | undefined; }" ], "path": "x-pack/packages/kbn-slo-schema/src/rest_specs/routes/update.ts", "deprecated": false, @@ -1468,7 +1468,7 @@ "label": "UpdateSLOResponse", "description": [], "signature": [ - "{ id: string; name: string; description: string; indicator: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.synthetics.availability\"; params: { monitorIds: { value: string; label: string; }[]; index: string; } & { tags?: { value: string; label: string; }[] | undefined; projects?: { value: string; label: string; }[] | undefined; filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; good: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; }; total: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.metric.custom\"; params: { index: string; good: { metrics: (({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; }; total: { metrics: (({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.metric.timeslice\"; params: { index: string; metric: { metrics: (({ name: string; aggregation: \"min\" | \"max\" | \"sum\" | \"avg\" | \"cardinality\" | \"last_value\" | \"std_deviation\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"percentile\"; field: string; percentile: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; threshold: number; comparator: \"GT\" | \"GTE\" | \"LT\" | \"LTE\"; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.histogram.custom\"; params: { index: string; timestampField: string; good: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }); total: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }); } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; }; timeWindow: { duration: string; type: \"rolling\"; } | { duration: string; type: \"calendarAligned\"; }; budgetingMethod: \"occurrences\" | \"timeslices\"; objective: { target: number; } & { timesliceTarget?: number | undefined; timesliceWindow?: string | undefined; }; settings: { syncDelay: string; frequency: string; preventInitialBackfill: boolean; }; revision: number; enabled: boolean; tags: string[]; createdAt: string; updatedAt: string; groupBy: string | string[]; version: number; }" + "{ id: string; name: string; description: string; indicator: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.synthetics.availability\"; params: { monitorIds: { value: string; label: string; }[]; index: string; } & { tags?: { value: string; label: string; }[] | undefined; projects?: { value: string; label: string; }[] | undefined; filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; good: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; }; total: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.metric.custom\"; params: { index: string; good: { metrics: (({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; }; total: { metrics: (({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.metric.timeslice\"; params: { index: string; metric: { metrics: (({ name: string; aggregation: \"min\" | \"max\" | \"sum\" | \"avg\" | \"cardinality\" | \"last_value\" | \"std_deviation\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"percentile\"; field: string; percentile: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; threshold: number; comparator: \"GT\" | \"GTE\" | \"LT\" | \"LTE\"; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.histogram.custom\"; params: { index: string; timestampField: string; good: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }); total: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }); } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; }; timeWindow: { duration: string; type: \"rolling\"; } | { duration: string; type: \"calendarAligned\"; }; budgetingMethod: \"occurrences\" | \"timeslices\"; objective: { target: number; } & { timesliceTarget?: number | undefined; timesliceWindow?: string | undefined; }; settings: { syncDelay: string; frequency: string; preventInitialBackfill: boolean; } & { syncField?: string | null | undefined; }; revision: number; enabled: boolean; tags: string[]; createdAt: string; updatedAt: string; groupBy: string | string[]; version: number; }" ], "path": "x-pack/packages/kbn-slo-schema/src/rest_specs/routes/update.ts", "deprecated": false, @@ -3250,7 +3250,13 @@ }, ", string, unknown>; preventInitialBackfill: ", "BooleanC", - "; }>; tags: ", + "; syncField: ", + "UnionC", + "<[", + "StringC", + ", ", + "NullC", + "]>; }>; tags: ", "ArrayC", "<", "StringC", @@ -5171,6 +5177,8 @@ "text": "Duration" }, ", string, unknown>; }>]>; settings: ", + "IntersectionC", + "<[", "TypeC", "<{ syncDelay: ", "Type", @@ -5194,7 +5202,15 @@ }, ", string, unknown>; preventInitialBackfill: ", "BooleanC", - "; }>; revision: ", + "; }>, ", + "PartialC", + "<{ syncField: ", + "UnionC", + "<[", + "StringC", + ", ", + "NullC", + "]>; }>]>; revision: ", "NumberC", "; enabled: ", "BooleanC", @@ -6811,6 +6827,8 @@ "text": "Duration" }, ", string, unknown>; }>]>; settings: ", + "IntersectionC", + "<[", "TypeC", "<{ syncDelay: ", "Type", @@ -6834,7 +6852,15 @@ }, ", string, unknown>; preventInitialBackfill: ", "BooleanC", - "; }>; revision: ", + "; }>, ", + "PartialC", + "<{ syncField: ", + "UnionC", + "<[", + "StringC", + ", ", + "NullC", + "]>; }>]>; revision: ", "NumberC", "; enabled: ", "BooleanC", @@ -9945,6 +9971,8 @@ "text": "Duration" }, ", string, unknown>; }>]>; settings: ", + "IntersectionC", + "<[", "TypeC", "<{ syncDelay: ", "Type", @@ -9968,7 +9996,15 @@ }, ", string, unknown>; preventInitialBackfill: ", "BooleanC", - "; }>; revision: ", + "; }>, ", + "PartialC", + "<{ syncField: ", + "UnionC", + "<[", + "StringC", + ", ", + "NullC", + "]>; }>]>; revision: ", "NumberC", "; enabled: ", "BooleanC", @@ -12867,7 +12903,13 @@ }, ", string, unknown>; preventInitialBackfill: ", "BooleanC", - "; }>" + "; syncField: ", + "UnionC", + "<[", + "StringC", + ", ", + "NullC", + "]>; }>" ], "path": "x-pack/packages/kbn-slo-schema/src/schema/slo.ts", "deprecated": false, @@ -14444,6 +14486,8 @@ "text": "Duration" }, ", string, unknown>; }>]>; settings: ", + "IntersectionC", + "<[", "TypeC", "<{ syncDelay: ", "Type", @@ -14467,7 +14511,15 @@ }, ", string, unknown>; preventInitialBackfill: ", "BooleanC", - "; }>; revision: ", + "; }>, ", + "PartialC", + "<{ syncField: ", + "UnionC", + "<[", + "StringC", + ", ", + "NullC", + "]>; }>]>; revision: ", "NumberC", "; enabled: ", "BooleanC", @@ -14554,6 +14606,8 @@ "label": "settingsSchema", "description": [], "signature": [ + "IntersectionC", + "<[", "TypeC", "<{ syncDelay: ", "Type", @@ -14577,7 +14631,15 @@ }, ", string, unknown>; preventInitialBackfill: ", "BooleanC", - "; }>" + "; }>, ", + "PartialC", + "<{ syncField: ", + "UnionC", + "<[", + "StringC", + ", ", + "NullC", + "]>; }>]>" ], "path": "x-pack/packages/kbn-slo-schema/src/schema/slo.ts", "deprecated": false, @@ -15982,6 +16044,8 @@ "text": "Duration" }, ", string, unknown>; }>]>; settings: ", + "IntersectionC", + "<[", "TypeC", "<{ syncDelay: ", "Type", @@ -16005,7 +16069,15 @@ }, ", string, unknown>; preventInitialBackfill: ", "BooleanC", - "; }>; revision: ", + "; }>, ", + "PartialC", + "<{ syncField: ", + "UnionC", + "<[", + "StringC", + ", ", + "NullC", + "]>; }>]>; revision: ", "NumberC", "; enabled: ", "BooleanC", @@ -17562,6 +17634,8 @@ "text": "Duration" }, ", string, unknown>; }>]>; settings: ", + "IntersectionC", + "<[", "TypeC", "<{ syncDelay: ", "Type", @@ -17585,7 +17659,15 @@ }, ", string, unknown>; preventInitialBackfill: ", "BooleanC", - "; }>; revision: ", + "; }>, ", + "PartialC", + "<{ syncField: ", + "UnionC", + "<[", + "StringC", + ", ", + "NullC", + "]>; }>]>; revision: ", "NumberC", "; enabled: ", "BooleanC", @@ -20241,7 +20323,13 @@ }, ", string, unknown>; preventInitialBackfill: ", "BooleanC", - "; }>; tags: ", + "; syncField: ", + "UnionC", + "<[", + "StringC", + ", ", + "NullC", + "]>; }>; tags: ", "ArrayC", "<", "StringC", @@ -21664,6 +21752,8 @@ "text": "Duration" }, ", string, unknown>; }>]>; settings: ", + "IntersectionC", + "<[", "TypeC", "<{ syncDelay: ", "Type", @@ -21687,7 +21777,15 @@ }, ", string, unknown>; preventInitialBackfill: ", "BooleanC", - "; }>; revision: ", + "; }>, ", + "PartialC", + "<{ syncField: ", + "UnionC", + "<[", + "StringC", + ", ", + "NullC", + "]>; }>]>; revision: ", "NumberC", "; enabled: ", "BooleanC", diff --git a/api_docs/kbn_slo_schema.mdx b/api_docs/kbn_slo_schema.mdx index a29ad78916e6c..acb6a8173eebd 100644 --- a/api_docs/kbn_slo_schema.mdx +++ b/api_docs/kbn_slo_schema.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-slo-schema title: "@kbn/slo-schema" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/slo-schema plugin -date: 2024-11-29 +date: 2024-12-03 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 4da9a4c85c4aa..1c0edd62e378a 100644 --- a/api_docs/kbn_some_dev_log.mdx +++ b/api_docs/kbn_some_dev_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-some-dev-log title: "@kbn/some-dev-log" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/some-dev-log plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/some-dev-log'] --- import kbnSomeDevLogObj from './kbn_some_dev_log.devdocs.json'; diff --git a/api_docs/kbn_sort_predicates.mdx b/api_docs/kbn_sort_predicates.mdx index 31255c11224f5..92284a5b23c21 100644 --- a/api_docs/kbn_sort_predicates.mdx +++ b/api_docs/kbn_sort_predicates.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-sort-predicates title: "@kbn/sort-predicates" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/sort-predicates plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/sort-predicates'] --- import kbnSortPredicatesObj from './kbn_sort_predicates.devdocs.json'; diff --git a/api_docs/kbn_sse_utils.mdx b/api_docs/kbn_sse_utils.mdx index 4a51e30ccabef..59a5694310014 100644 --- a/api_docs/kbn_sse_utils.mdx +++ b/api_docs/kbn_sse_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-sse-utils title: "@kbn/sse-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/sse-utils plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/sse-utils'] --- import kbnSseUtilsObj from './kbn_sse_utils.devdocs.json'; diff --git a/api_docs/kbn_sse_utils_client.mdx b/api_docs/kbn_sse_utils_client.mdx index 94ca9b64f57a7..938c72543d30f 100644 --- a/api_docs/kbn_sse_utils_client.mdx +++ b/api_docs/kbn_sse_utils_client.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-sse-utils-client title: "@kbn/sse-utils-client" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/sse-utils-client plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/sse-utils-client'] --- import kbnSseUtilsClientObj from './kbn_sse_utils_client.devdocs.json'; diff --git a/api_docs/kbn_sse_utils_server.mdx b/api_docs/kbn_sse_utils_server.mdx index 153a514bb4d8e..b644dd00225be 100644 --- a/api_docs/kbn_sse_utils_server.mdx +++ b/api_docs/kbn_sse_utils_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-sse-utils-server title: "@kbn/sse-utils-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/sse-utils-server plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/sse-utils-server'] --- import kbnSseUtilsServerObj from './kbn_sse_utils_server.devdocs.json'; diff --git a/api_docs/kbn_std.mdx b/api_docs/kbn_std.mdx index 36492089bd2d6..381a352aa0af6 100644 --- a/api_docs/kbn_std.mdx +++ b/api_docs/kbn_std.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-std title: "@kbn/std" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/std plugin -date: 2024-11-29 +date: 2024-12-03 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 7536d0040a989..a6775c662e9ba 100644 --- a/api_docs/kbn_stdio_dev_helpers.mdx +++ b/api_docs/kbn_stdio_dev_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-stdio-dev-helpers title: "@kbn/stdio-dev-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/stdio-dev-helpers plugin -date: 2024-11-29 +date: 2024-12-03 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 a8a0a0375c380..1fc5797c7af79 100644 --- a/api_docs/kbn_storybook.mdx +++ b/api_docs/kbn_storybook.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-storybook title: "@kbn/storybook" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/storybook plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/storybook'] --- import kbnStorybookObj from './kbn_storybook.devdocs.json'; diff --git a/api_docs/kbn_synthetics_e2e.mdx b/api_docs/kbn_synthetics_e2e.mdx index 2230d5c3ec6de..711deb91b9bbe 100644 --- a/api_docs/kbn_synthetics_e2e.mdx +++ b/api_docs/kbn_synthetics_e2e.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-synthetics-e2e title: "@kbn/synthetics-e2e" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/synthetics-e2e plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/synthetics-e2e'] --- import kbnSyntheticsE2eObj from './kbn_synthetics_e2e.devdocs.json'; diff --git a/api_docs/kbn_synthetics_private_location.mdx b/api_docs/kbn_synthetics_private_location.mdx index 2822532d80a83..af24792bd8bfd 100644 --- a/api_docs/kbn_synthetics_private_location.mdx +++ b/api_docs/kbn_synthetics_private_location.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-synthetics-private-location title: "@kbn/synthetics-private-location" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/synthetics-private-location plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/synthetics-private-location'] --- import kbnSyntheticsPrivateLocationObj from './kbn_synthetics_private_location.devdocs.json'; diff --git a/api_docs/kbn_telemetry_tools.mdx b/api_docs/kbn_telemetry_tools.mdx index adfd41e554e43..334f1857e3fa4 100644 --- a/api_docs/kbn_telemetry_tools.mdx +++ b/api_docs/kbn_telemetry_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-telemetry-tools title: "@kbn/telemetry-tools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/telemetry-tools plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/telemetry-tools'] --- import kbnTelemetryToolsObj from './kbn_telemetry_tools.devdocs.json'; diff --git a/api_docs/kbn_test.mdx b/api_docs/kbn_test.mdx index b6f23b44c5d64..7d2f6d15b2500 100644 --- a/api_docs/kbn_test.mdx +++ b/api_docs/kbn_test.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test title: "@kbn/test" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test'] --- import kbnTestObj from './kbn_test.devdocs.json'; diff --git a/api_docs/kbn_test_eui_helpers.mdx b/api_docs/kbn_test_eui_helpers.mdx index 81f9d9f4173ad..f7625b6d00353 100644 --- a/api_docs/kbn_test_eui_helpers.mdx +++ b/api_docs/kbn_test_eui_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test-eui-helpers title: "@kbn/test-eui-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test-eui-helpers plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test-eui-helpers'] --- import kbnTestEuiHelpersObj from './kbn_test_eui_helpers.devdocs.json'; diff --git a/api_docs/kbn_test_jest_helpers.mdx b/api_docs/kbn_test_jest_helpers.mdx index 03734b5386d96..fb69f623ea84d 100644 --- a/api_docs/kbn_test_jest_helpers.mdx +++ b/api_docs/kbn_test_jest_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test-jest-helpers title: "@kbn/test-jest-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test-jest-helpers plugin -date: 2024-11-29 +date: 2024-12-03 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.devdocs.json b/api_docs/kbn_test_subj_selector.devdocs.json index 2ab9cc3c4a7a3..dafcf5ceb970e 100644 --- a/api_docs/kbn_test_subj_selector.devdocs.json +++ b/api_docs/kbn_test_subj_selector.devdocs.json @@ -26,7 +26,7 @@ "tags": [], "label": "subj", "description": [ - "\nConverts a testSubject selector into a CSS selector.\n\ntestSubject selector syntax rules:\n\n - `data-test-subj` values can include spaces\n\n - prefixing a value with `*` will allow matching a `data-test-subj` attribute containing at least one occurrence of value within the string.\n - example: `*foo`\n - css equivalent: `[data-test-subj*=\"foo\"]`\n - DOM match example:
data-test-subj=\"bar-foo\"
\n\n - prefixing a value with `~` will allow matching a `data-test-subj` attribute represented as a whitespace-separated list of words, one of which is exactly value\n - example: `~foo`\n - css equivalent: `[data-test-subj~=\"foo\"]`\n - DOM match example:
data-test-subj=\"foo bar\"
\n\n - the `>` character is used between two values to indicate that the value on the right must match an element inside an element matched by the value on the left\n - example: `foo > bar`\n - css equivalent: `[data-test-subj=foo] [data-test-subj=bar]`\n - DOM match example:\n
data-test-subj=\"foo\"\n
data-test-subj=\"bar\"
\n
\n\n - the `&` character is used between two values to indicate that the value on both sides must both match the element\n - example: `foo & bar`\n - css equivalent: `[data-test-subj=foo][data-test-subj=bar]`\n - DOM match example:
data-test-subj=\"foo bar\"
" + "\nConverts a testSubject selector into a CSS selector.\n\ntestSubject selector syntax rules:\n\n - `data-test-subj` values can include spaces\n\n - prefixing a value with `*` will allow matching a `data-test-subj` attribute containing at least one occurrence of value within the string.\n - example: `*foo`\n - css equivalent: `[data-test-subj*=\"foo\"]`\n - DOM match example:
\n\n - prefixing a value with `^` will allow matching a `data-test-subj` attribute beginning with the specified value.\n - example: `^foo`\n - css equivalent: `[data-test-subj^=\"foo\"]`\n - DOM match example:
\n\n - prefixing a value with `~` will allow matching a `data-test-subj` attribute represented as a whitespace-separated list of words, one of which is exactly value\n - example: `~foo`\n - css equivalent: `[data-test-subj~=\"foo\"]`\n - DOM match example:
\n\n - the `>` character is used between two values to indicate that the value on the right must match an element inside an element matched by the value on the left\n - example: `foo > bar`\n - css equivalent: `[data-test-subj=foo] [data-test-subj=bar]`\n - DOM match example:\n
\n
\n
\n\n - the `&` character is used between two values to indicate that the value on both sides must both match the element\n - example: `foo & bar`\n - css equivalent: `[data-test-subj=foo][data-test-subj=bar]`\n - DOM match example:
" ], "signature": [ "(selector: string) => string" diff --git a/api_docs/kbn_test_subj_selector.mdx b/api_docs/kbn_test_subj_selector.mdx index 92d6b1e1b372f..02c286b503a3c 100644 --- a/api_docs/kbn_test_subj_selector.mdx +++ b/api_docs/kbn_test_subj_selector.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test-subj-selector title: "@kbn/test-subj-selector" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test-subj-selector plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test-subj-selector'] --- import kbnTestSubjSelectorObj from './kbn_test_subj_selector.devdocs.json'; diff --git a/api_docs/kbn_timerange.mdx b/api_docs/kbn_timerange.mdx index d8d0516a5611e..acc61504485a3 100644 --- a/api_docs/kbn_timerange.mdx +++ b/api_docs/kbn_timerange.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-timerange title: "@kbn/timerange" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/timerange plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/timerange'] --- import kbnTimerangeObj from './kbn_timerange.devdocs.json'; diff --git a/api_docs/kbn_tooling_log.mdx b/api_docs/kbn_tooling_log.mdx index b67e827e3337f..edf7f58b4bdac 100644 --- a/api_docs/kbn_tooling_log.mdx +++ b/api_docs/kbn_tooling_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-tooling-log title: "@kbn/tooling-log" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/tooling-log plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/tooling-log'] --- import kbnToolingLogObj from './kbn_tooling_log.devdocs.json'; diff --git a/api_docs/kbn_transpose_utils.mdx b/api_docs/kbn_transpose_utils.mdx index 769fd48e829d6..6c930f1bafb85 100644 --- a/api_docs/kbn_transpose_utils.mdx +++ b/api_docs/kbn_transpose_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-transpose-utils title: "@kbn/transpose-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/transpose-utils plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/transpose-utils'] --- import kbnTransposeUtilsObj from './kbn_transpose_utils.devdocs.json'; diff --git a/api_docs/kbn_triggers_actions_ui_types.mdx b/api_docs/kbn_triggers_actions_ui_types.mdx index 0a63592a75a72..f7d11a0f01fc7 100644 --- a/api_docs/kbn_triggers_actions_ui_types.mdx +++ b/api_docs/kbn_triggers_actions_ui_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-triggers-actions-ui-types title: "@kbn/triggers-actions-ui-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/triggers-actions-ui-types plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/triggers-actions-ui-types'] --- import kbnTriggersActionsUiTypesObj from './kbn_triggers_actions_ui_types.devdocs.json'; diff --git a/api_docs/kbn_try_in_console.mdx b/api_docs/kbn_try_in_console.mdx index 89fcc73e437d3..0783a6380f402 100644 --- a/api_docs/kbn_try_in_console.mdx +++ b/api_docs/kbn_try_in_console.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-try-in-console title: "@kbn/try-in-console" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/try-in-console plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/try-in-console'] --- import kbnTryInConsoleObj from './kbn_try_in_console.devdocs.json'; diff --git a/api_docs/kbn_ts_projects.mdx b/api_docs/kbn_ts_projects.mdx index 76693e9d497df..e0587ede01cf2 100644 --- a/api_docs/kbn_ts_projects.mdx +++ b/api_docs/kbn_ts_projects.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ts-projects title: "@kbn/ts-projects" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ts-projects plugin -date: 2024-11-29 +date: 2024-12-03 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 6b206bb1dc522..4c60563b2291f 100644 --- a/api_docs/kbn_typed_react_router_config.mdx +++ b/api_docs/kbn_typed_react_router_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-typed-react-router-config title: "@kbn/typed-react-router-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/typed-react-router-config plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/typed-react-router-config'] --- import kbnTypedReactRouterConfigObj from './kbn_typed_react_router_config.devdocs.json'; diff --git a/api_docs/kbn_ui_actions_browser.mdx b/api_docs/kbn_ui_actions_browser.mdx index d842bf9a496e0..dad32cac09d53 100644 --- a/api_docs/kbn_ui_actions_browser.mdx +++ b/api_docs/kbn_ui_actions_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ui-actions-browser title: "@kbn/ui-actions-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ui-actions-browser plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ui-actions-browser'] --- import kbnUiActionsBrowserObj from './kbn_ui_actions_browser.devdocs.json'; diff --git a/api_docs/kbn_ui_shared_deps_src.mdx b/api_docs/kbn_ui_shared_deps_src.mdx index 3f9e93be63a87..a340b03cf1a98 100644 --- a/api_docs/kbn_ui_shared_deps_src.mdx +++ b/api_docs/kbn_ui_shared_deps_src.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ui-shared-deps-src title: "@kbn/ui-shared-deps-src" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ui-shared-deps-src plugin -date: 2024-11-29 +date: 2024-12-03 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 fdf410629acb1..9dabec875b0bb 100644 --- a/api_docs/kbn_ui_theme.mdx +++ b/api_docs/kbn_ui_theme.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ui-theme title: "@kbn/ui-theme" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ui-theme plugin -date: 2024-11-29 +date: 2024-12-03 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.devdocs.json b/api_docs/kbn_unified_data_table.devdocs.json index 1398b8b7116ac..0a59133908c68 100644 --- a/api_docs/kbn_unified_data_table.devdocs.json +++ b/api_docs/kbn_unified_data_table.devdocs.json @@ -823,7 +823,7 @@ "label": "UnifiedDataTable", "description": [], "signature": [ - "({ ariaLabelledBy, columns, columnsMeta, showColumnTokens, canDragAndDropColumns, configHeaderRowHeight, headerRowHeightState, onUpdateHeaderRowHeight, controlColumnIds, rowAdditionalLeadingControls, dataView, loadingState, onFilter, onResize, onSetColumns, onSort, rows, searchDescription, searchTitle, settings, showTimeCol, showFullScreenButton, sort, useNewFieldsApi, isSortEnabled, isPaginationEnabled, cellActionsTriggerId, cellActionsMetadata, cellActionsHandling, visibleCellActions, className, rowHeightState, onUpdateRowHeight, maxAllowedSampleSize, sampleSizeState, onUpdateSampleSize, isPlainRecord, rowsPerPageState, onUpdateRowsPerPage, onFieldEdited, services, renderCustomGridBody, renderCustomToolbar, externalControlColumns, trailingControlColumns, totalHits, onFetchMoreRecords, renderDocumentView, setExpandedDoc, expandedDoc, configRowHeight, showMultiFields, maxDocFieldsDisplayed, externalAdditionalControls, rowsPerPageOptions, externalCustomRenderers, additionalFieldGroups, consumer, componentsTourSteps, gridStyleOverride, rowLineHeightOverride, customGridColumnsConfiguration, enableComparisonMode, cellContext, renderCellPopover, getRowIndicator, dataGridDensityState, onUpdateDataGridDensity, }: ", + "({ ariaLabelledBy, columns, columnsMeta, showColumnTokens, canDragAndDropColumns, configHeaderRowHeight, headerRowHeightState, onUpdateHeaderRowHeight, controlColumnIds, rowAdditionalLeadingControls, dataView, loadingState, onFilter, onResize, onSetColumns, onSort, rows, searchDescription, searchTitle, settings, showTimeCol, showFullScreenButton, sort, useNewFieldsApi, isSortEnabled, isPaginationEnabled, cellActionsTriggerId, cellActionsMetadata, cellActionsHandling, visibleCellActions, className, rowHeightState, onUpdateRowHeight, maxAllowedSampleSize, sampleSizeState, onUpdateSampleSize, isPlainRecord, rowsPerPageState, onUpdateRowsPerPage, onFieldEdited, services, renderCustomGridBody, renderCustomToolbar, externalControlColumns, trailingControlColumns, totalHits, onFetchMoreRecords, renderDocumentView, setExpandedDoc, expandedDoc, configRowHeight, showMultiFields, maxDocFieldsDisplayed, externalAdditionalControls, rowsPerPageOptions, externalCustomRenderers, additionalFieldGroups, consumer, componentsTourSteps, gridStyleOverride, rowLineHeightOverride, customGridColumnsConfiguration, enableComparisonMode, cellContext, renderCellPopover, getRowIndicator, dataGridDensityState, onUpdateDataGridDensity, onUpdatePageIndex, }: ", { "pluginId": "@kbn/unified-data-table", "scope": "public", @@ -842,7 +842,7 @@ "id": "def-public.UnifiedDataTable.$1", "type": "Object", "tags": [], - "label": "{\n ariaLabelledBy,\n columns,\n columnsMeta,\n showColumnTokens,\n canDragAndDropColumns,\n configHeaderRowHeight,\n headerRowHeightState,\n onUpdateHeaderRowHeight,\n controlColumnIds = CONTROL_COLUMN_IDS_DEFAULT,\n rowAdditionalLeadingControls,\n dataView,\n loadingState,\n onFilter,\n onResize,\n onSetColumns,\n onSort,\n rows,\n searchDescription,\n searchTitle,\n settings,\n showTimeCol,\n showFullScreenButton = true,\n sort,\n useNewFieldsApi,\n isSortEnabled = true,\n isPaginationEnabled = true,\n cellActionsTriggerId,\n cellActionsMetadata,\n cellActionsHandling = 'replace',\n visibleCellActions,\n className,\n rowHeightState,\n onUpdateRowHeight,\n maxAllowedSampleSize,\n sampleSizeState,\n onUpdateSampleSize,\n isPlainRecord = false,\n rowsPerPageState,\n onUpdateRowsPerPage,\n onFieldEdited,\n services,\n renderCustomGridBody,\n renderCustomToolbar,\n externalControlColumns, // TODO: deprecate in favor of rowAdditionalLeadingControls\n trailingControlColumns, // TODO: deprecate in favor of rowAdditionalLeadingControls\n totalHits,\n onFetchMoreRecords,\n renderDocumentView,\n setExpandedDoc,\n expandedDoc,\n configRowHeight,\n showMultiFields = true,\n maxDocFieldsDisplayed = 50,\n externalAdditionalControls,\n rowsPerPageOptions,\n externalCustomRenderers,\n additionalFieldGroups,\n consumer = 'discover',\n componentsTourSteps,\n gridStyleOverride,\n rowLineHeightOverride,\n customGridColumnsConfiguration,\n enableComparisonMode,\n cellContext,\n renderCellPopover,\n getRowIndicator,\n dataGridDensityState,\n onUpdateDataGridDensity,\n}", + "label": "{\n ariaLabelledBy,\n columns,\n columnsMeta,\n showColumnTokens,\n canDragAndDropColumns,\n configHeaderRowHeight,\n headerRowHeightState,\n onUpdateHeaderRowHeight,\n controlColumnIds = CONTROL_COLUMN_IDS_DEFAULT,\n rowAdditionalLeadingControls,\n dataView,\n loadingState,\n onFilter,\n onResize,\n onSetColumns,\n onSort,\n rows,\n searchDescription,\n searchTitle,\n settings,\n showTimeCol,\n showFullScreenButton = true,\n sort,\n useNewFieldsApi,\n isSortEnabled = true,\n isPaginationEnabled = true,\n cellActionsTriggerId,\n cellActionsMetadata,\n cellActionsHandling = 'replace',\n visibleCellActions,\n className,\n rowHeightState,\n onUpdateRowHeight,\n maxAllowedSampleSize,\n sampleSizeState,\n onUpdateSampleSize,\n isPlainRecord = false,\n rowsPerPageState,\n onUpdateRowsPerPage,\n onFieldEdited,\n services,\n renderCustomGridBody,\n renderCustomToolbar,\n externalControlColumns, // TODO: deprecate in favor of rowAdditionalLeadingControls\n trailingControlColumns, // TODO: deprecate in favor of rowAdditionalLeadingControls\n totalHits,\n onFetchMoreRecords,\n renderDocumentView,\n setExpandedDoc,\n expandedDoc,\n configRowHeight,\n showMultiFields = true,\n maxDocFieldsDisplayed = 50,\n externalAdditionalControls,\n rowsPerPageOptions,\n externalCustomRenderers,\n additionalFieldGroups,\n consumer = 'discover',\n componentsTourSteps,\n gridStyleOverride,\n rowLineHeightOverride,\n customGridColumnsConfiguration,\n enableComparisonMode,\n cellContext,\n renderCellPopover,\n getRowIndicator,\n dataGridDensityState,\n onUpdateDataGridDensity,\n onUpdatePageIndex,\n}", "description": [], "signature": [ { @@ -1962,6 +1962,40 @@ ], "returnComment": [] }, + { + "parentPluginId": "@kbn/unified-data-table", + "id": "def-public.UnifiedDataTableProps.onUpdatePageIndex", + "type": "Function", + "tags": [], + "label": "onUpdatePageIndex", + "description": [ + "\n\nthis callback is triggered when user navigates to a different page\n" + ], + "signature": [ + "((pageIndex: number) => void) | undefined" + ], + "path": "packages/kbn-unified-data-table/src/components/data_table.tsx", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/unified-data-table", + "id": "def-public.UnifiedDataTableProps.onUpdatePageIndex.$1", + "type": "number", + "tags": [], + "label": "pageIndex", + "description": [], + "signature": [ + "number" + ], + "path": "packages/kbn-unified-data-table/src/components/data_table.tsx", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] + }, { "parentPluginId": "@kbn/unified-data-table", "id": "def-public.UnifiedDataTableProps.maxAllowedSampleSize", @@ -3144,7 +3178,7 @@ "label": "CustomCellRenderer", "description": [], "signature": [ - "{ [x: string]: (props: ", + "{ [x: string]: React.FunctionComponent<", { "pluginId": "@kbn/unified-data-table", "scope": "public", @@ -3152,7 +3186,7 @@ "section": "def-public.DataGridCellValueElementProps", "text": "DataGridCellValueElementProps" }, - ") => React.ReactElement>; }" + ">; }" ], "path": "packages/kbn-unified-data-table/src/types.ts", "deprecated": false, diff --git a/api_docs/kbn_unified_data_table.mdx b/api_docs/kbn_unified_data_table.mdx index 3c44f24710e3e..b8313c9fd1fd6 100644 --- a/api_docs/kbn_unified_data_table.mdx +++ b/api_docs/kbn_unified_data_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-unified-data-table title: "@kbn/unified-data-table" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/unified-data-table plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/unified-data-table'] --- import kbnUnifiedDataTableObj from './kbn_unified_data_table.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/k | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 184 | 0 | 108 | 1 | +| 186 | 0 | 109 | 1 | ## Client diff --git a/api_docs/kbn_unified_doc_viewer.mdx b/api_docs/kbn_unified_doc_viewer.mdx index 8a34e7a018e4f..a0b82df40b47f 100644 --- a/api_docs/kbn_unified_doc_viewer.mdx +++ b/api_docs/kbn_unified_doc_viewer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-unified-doc-viewer title: "@kbn/unified-doc-viewer" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/unified-doc-viewer plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/unified-doc-viewer'] --- import kbnUnifiedDocViewerObj from './kbn_unified_doc_viewer.devdocs.json'; diff --git a/api_docs/kbn_unified_field_list.mdx b/api_docs/kbn_unified_field_list.mdx index 0333518a51b43..c1f54be675e47 100644 --- a/api_docs/kbn_unified_field_list.mdx +++ b/api_docs/kbn_unified_field_list.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-unified-field-list title: "@kbn/unified-field-list" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/unified-field-list plugin -date: 2024-11-29 +date: 2024-12-03 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 326cada600fbb..1db7abc927de5 100644 --- a/api_docs/kbn_unsaved_changes_badge.mdx +++ b/api_docs/kbn_unsaved_changes_badge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-unsaved-changes-badge title: "@kbn/unsaved-changes-badge" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/unsaved-changes-badge plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/unsaved-changes-badge'] --- import kbnUnsavedChangesBadgeObj from './kbn_unsaved_changes_badge.devdocs.json'; diff --git a/api_docs/kbn_unsaved_changes_prompt.mdx b/api_docs/kbn_unsaved_changes_prompt.mdx index 7e4fdf1e27702..56383bcf3c70b 100644 --- a/api_docs/kbn_unsaved_changes_prompt.mdx +++ b/api_docs/kbn_unsaved_changes_prompt.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-unsaved-changes-prompt title: "@kbn/unsaved-changes-prompt" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/unsaved-changes-prompt plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/unsaved-changes-prompt'] --- import kbnUnsavedChangesPromptObj from './kbn_unsaved_changes_prompt.devdocs.json'; diff --git a/api_docs/kbn_use_tracked_promise.mdx b/api_docs/kbn_use_tracked_promise.mdx index 6d3dfacdafd0d..5222c704661ab 100644 --- a/api_docs/kbn_use_tracked_promise.mdx +++ b/api_docs/kbn_use_tracked_promise.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-use-tracked-promise title: "@kbn/use-tracked-promise" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/use-tracked-promise plugin -date: 2024-11-29 +date: 2024-12-03 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 89d394f1a6dc6..cd218a070b837 100644 --- a/api_docs/kbn_user_profile_components.mdx +++ b/api_docs/kbn_user_profile_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-user-profile-components title: "@kbn/user-profile-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/user-profile-components plugin -date: 2024-11-29 +date: 2024-12-03 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 7e6c617b683eb..87ecf211ccc4c 100644 --- a/api_docs/kbn_utility_types.mdx +++ b/api_docs/kbn_utility_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utility-types title: "@kbn/utility-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utility-types plugin -date: 2024-11-29 +date: 2024-12-03 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 0f7e4223dfe0d..4b49518487ea0 100644 --- a/api_docs/kbn_utility_types_jest.mdx +++ b/api_docs/kbn_utility_types_jest.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utility-types-jest title: "@kbn/utility-types-jest" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utility-types-jest plugin -date: 2024-11-29 +date: 2024-12-03 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 74e6e7fbdf9b4..3dec60b9418d8 100644 --- a/api_docs/kbn_utils.mdx +++ b/api_docs/kbn_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utils title: "@kbn/utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utils plugin -date: 2024-11-29 +date: 2024-12-03 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 6c1ad3ef222be..c68e7f789a972 100644 --- a/api_docs/kbn_visualization_ui_components.mdx +++ b/api_docs/kbn_visualization_ui_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-visualization-ui-components title: "@kbn/visualization-ui-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/visualization-ui-components plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/visualization-ui-components'] --- import kbnVisualizationUiComponentsObj from './kbn_visualization_ui_components.devdocs.json'; diff --git a/api_docs/kbn_visualization_utils.mdx b/api_docs/kbn_visualization_utils.mdx index f5af8bca75d84..c2fcf6978f621 100644 --- a/api_docs/kbn_visualization_utils.mdx +++ b/api_docs/kbn_visualization_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-visualization-utils title: "@kbn/visualization-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/visualization-utils plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/visualization-utils'] --- import kbnVisualizationUtilsObj from './kbn_visualization_utils.devdocs.json'; diff --git a/api_docs/kbn_xstate_utils.mdx b/api_docs/kbn_xstate_utils.mdx index 533b40de39a14..231e5ddd1e1a5 100644 --- a/api_docs/kbn_xstate_utils.mdx +++ b/api_docs/kbn_xstate_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-xstate-utils title: "@kbn/xstate-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/xstate-utils plugin -date: 2024-11-29 +date: 2024-12-03 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 7e0fa09e877b7..0517fbdcc6409 100644 --- a/api_docs/kbn_yarn_lock_validator.mdx +++ b/api_docs/kbn_yarn_lock_validator.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-yarn-lock-validator title: "@kbn/yarn-lock-validator" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/yarn-lock-validator plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/yarn-lock-validator'] --- import kbnYarnLockValidatorObj from './kbn_yarn_lock_validator.devdocs.json'; diff --git a/api_docs/kbn_zod.mdx b/api_docs/kbn_zod.mdx index 305494ae9c968..086e598844ac2 100644 --- a/api_docs/kbn_zod.mdx +++ b/api_docs/kbn_zod.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-zod title: "@kbn/zod" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/zod plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/zod'] --- import kbnZodObj from './kbn_zod.devdocs.json'; diff --git a/api_docs/kbn_zod_helpers.mdx b/api_docs/kbn_zod_helpers.mdx index d88c88da1c001..963af679b9ae0 100644 --- a/api_docs/kbn_zod_helpers.mdx +++ b/api_docs/kbn_zod_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-zod-helpers title: "@kbn/zod-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/zod-helpers plugin -date: 2024-11-29 +date: 2024-12-03 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 2244a539e1426..5aa289d152798 100644 --- a/api_docs/kibana_overview.mdx +++ b/api_docs/kibana_overview.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaOverview title: "kibanaOverview" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaOverview plugin -date: 2024-11-29 +date: 2024-12-03 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 7dedae531ebab..5d988082e379e 100644 --- a/api_docs/kibana_react.mdx +++ b/api_docs/kibana_react.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaReact title: "kibanaReact" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaReact plugin -date: 2024-11-29 +date: 2024-12-03 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 3ec31794a5330..6787003f78943 100644 --- a/api_docs/kibana_utils.mdx +++ b/api_docs/kibana_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaUtils title: "kibanaUtils" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaUtils plugin -date: 2024-11-29 +date: 2024-12-03 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 0dfcc15565e4a..5c57711ffd9d7 100644 --- a/api_docs/kubernetes_security.mdx +++ b/api_docs/kubernetes_security.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kubernetesSecurity title: "kubernetesSecurity" image: https://source.unsplash.com/400x175/?github description: API docs for the kubernetesSecurity plugin -date: 2024-11-29 +date: 2024-12-03 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 bf631293a8860..013522ad1bafa 100644 --- a/api_docs/lens.devdocs.json +++ b/api_docs/lens.devdocs.json @@ -361,15 +361,7 @@ "section": "def-common.PaletteOutput", "text": "PaletteOutput" }, - "<{ [key: string]: unknown; }> | undefined; title?: string | undefined; description?: string | undefined; hidePanelTitles?: boolean | undefined; executionContext?: ", - { - "pluginId": "@kbn/core-execution-context-common", - "scope": "common", - "docId": "kibKbnCoreExecutionContextCommonPluginApi", - "section": "def-common.KibanaExecutionContext", - "text": "KibanaExecutionContext" - }, - " | undefined; style?: React.CSSProperties | undefined; className?: string | undefined; noPadding?: boolean | undefined; viewMode?: ", + "<{ [key: string]: unknown; }> | undefined; title?: string | undefined; description?: string | undefined; hidePanelTitles?: boolean | undefined; className?: string | undefined; style?: React.CSSProperties | undefined; viewMode?: ", { "pluginId": "@kbn/presentation-publishing", "scope": "public", @@ -377,6 +369,14 @@ "section": "def-public.ViewMode", "text": "ViewMode" }, + " | undefined; executionContext?: ", + { + "pluginId": "@kbn/core-execution-context-common", + "scope": "common", + "docId": "kibKbnCoreExecutionContextCommonPluginApi", + "section": "def-common.KibanaExecutionContext", + "text": "KibanaExecutionContext" + }, " | undefined; enhancements?: { dynamicActions: ", { "pluginId": "uiActionsEnhanced", @@ -567,7 +567,7 @@ "section": "def-public.ViewMode", "text": "ViewMode" }, - " | undefined; noPadding?: boolean | undefined; isNewPanel?: boolean | undefined; attributes: { title: string; description?: string | undefined; state: { datasourceStates: Record; visualization: unknown; query: ", + " | undefined; isNewPanel?: boolean | undefined; attributes: { title: string; description?: string | undefined; state: { datasourceStates: Record; visualization: unknown; query: ", { "pluginId": "@kbn/es-query", "scope": "common", @@ -903,7 +903,7 @@ "section": "def-public.ViewMode", "text": "ViewMode" }, - " | undefined; noPadding?: boolean | undefined; isNewPanel?: boolean | undefined; attributes: { title: string; description?: string | undefined; state: { datasourceStates: Record; visualization: unknown; query: ", + " | undefined; isNewPanel?: boolean | undefined; attributes: { title: string; description?: string | undefined; state: { datasourceStates: Record; visualization: unknown; query: ", { "pluginId": "@kbn/es-query", "scope": "common", @@ -1135,7 +1135,7 @@ "section": "def-public.ViewMode", "text": "ViewMode" }, - " | undefined; noPadding?: boolean | undefined; isNewPanel?: boolean | undefined; attributes: { title: string; description?: string | undefined; state: { datasourceStates: Record; visualization: unknown; query: ", + " | undefined; isNewPanel?: boolean | undefined; attributes: { title: string; description?: string | undefined; state: { datasourceStates: Record; visualization: unknown; query: ", { "pluginId": "@kbn/es-query", "scope": "common", @@ -6868,7 +6868,7 @@ "section": "def-public.ViewMode", "text": "ViewMode" }, - " | undefined; noPadding?: boolean | undefined; isNewPanel?: boolean | undefined; attributes: { title: string; description?: string | undefined; references: ", + " | undefined; isNewPanel?: boolean | undefined; attributes: { title: string; description?: string | undefined; references: ", { "pluginId": "@kbn/core-saved-objects-common", "scope": "common", @@ -7382,7 +7382,7 @@ }, " | undefined; textBased?: ", "TextBasedPersistedState", - " | undefined; }; visualization: unknown; }; }; abortController?: AbortController | undefined; withDefaultActions?: boolean | undefined; extraActions?: ", + " | undefined; }; visualization: unknown; }; }; abortController?: AbortController | undefined; noPadding?: boolean | undefined; withDefaultActions?: boolean | undefined; extraActions?: ", { "pluginId": "uiActions", "scope": "public", @@ -7667,7 +7667,7 @@ "section": "def-public.ViewMode", "text": "ViewMode" }, - " | undefined; noPadding?: boolean | undefined; isNewPanel?: boolean | undefined; attributes: { title: string; description?: string | undefined; references: ", + " | undefined; isNewPanel?: boolean | undefined; attributes: { title: string; description?: string | undefined; references: ", { "pluginId": "@kbn/core-saved-objects-common", "scope": "common", @@ -8181,7 +8181,7 @@ }, " | undefined; textBased?: ", "TextBasedPersistedState", - " | undefined; }; visualization: unknown; }; }; abortController?: AbortController | undefined; withDefaultActions?: boolean | undefined; extraActions?: ", + " | undefined; }; visualization: unknown; }; }; abortController?: AbortController | undefined; noPadding?: boolean | undefined; withDefaultActions?: boolean | undefined; extraActions?: ", { "pluginId": "uiActions", "scope": "public", @@ -8539,15 +8539,7 @@ "section": "def-common.PaletteOutput", "text": "PaletteOutput" }, - "<{ [key: string]: unknown; }> | undefined; title?: string | undefined; description?: string | undefined; hidePanelTitles?: boolean | undefined; executionContext?: ", - { - "pluginId": "@kbn/core-execution-context-common", - "scope": "common", - "docId": "kibKbnCoreExecutionContextCommonPluginApi", - "section": "def-common.KibanaExecutionContext", - "text": "KibanaExecutionContext" - }, - " | undefined; style?: React.CSSProperties | undefined; className?: string | undefined; noPadding?: boolean | undefined; viewMode?: ", + "<{ [key: string]: unknown; }> | undefined; title?: string | undefined; description?: string | undefined; hidePanelTitles?: boolean | undefined; className?: string | undefined; style?: React.CSSProperties | undefined; viewMode?: ", { "pluginId": "@kbn/presentation-publishing", "scope": "public", @@ -8555,6 +8547,14 @@ "section": "def-public.ViewMode", "text": "ViewMode" }, + " | undefined; executionContext?: ", + { + "pluginId": "@kbn/core-execution-context-common", + "scope": "common", + "docId": "kibKbnCoreExecutionContextCommonPluginApi", + "section": "def-common.KibanaExecutionContext", + "text": "KibanaExecutionContext" + }, " | undefined; enhancements?: { dynamicActions: ", { "pluginId": "uiActionsEnhanced", @@ -8791,15 +8791,7 @@ "section": "def-common.PaletteOutput", "text": "PaletteOutput" }, - "<{ [key: string]: unknown; }> | undefined; title?: string | undefined; description?: string | undefined; hidePanelTitles?: boolean | undefined; executionContext?: ", - { - "pluginId": "@kbn/core-execution-context-common", - "scope": "common", - "docId": "kibKbnCoreExecutionContextCommonPluginApi", - "section": "def-common.KibanaExecutionContext", - "text": "KibanaExecutionContext" - }, - " | undefined; style?: React.CSSProperties | undefined; className?: string | undefined; noPadding?: boolean | undefined; viewMode?: ", + "<{ [key: string]: unknown; }> | undefined; title?: string | undefined; description?: string | undefined; hidePanelTitles?: boolean | undefined; className?: string | undefined; style?: React.CSSProperties | undefined; viewMode?: ", { "pluginId": "@kbn/presentation-publishing", "scope": "public", @@ -8807,6 +8799,14 @@ "section": "def-public.ViewMode", "text": "ViewMode" }, + " | undefined; executionContext?: ", + { + "pluginId": "@kbn/core-execution-context-common", + "scope": "common", + "docId": "kibKbnCoreExecutionContextCommonPluginApi", + "section": "def-common.KibanaExecutionContext", + "text": "KibanaExecutionContext" + }, " | undefined; enhancements?: { dynamicActions: ", { "pluginId": "uiActionsEnhanced", @@ -16068,7 +16068,7 @@ "section": "def-public.ViewMode", "text": "ViewMode" }, - " | undefined; noPadding?: boolean | undefined; isNewPanel?: boolean | undefined; attributes: { title: string; description?: string | undefined; references: ", + " | undefined; isNewPanel?: boolean | undefined; attributes: { title: string; description?: string | undefined; references: ", { "pluginId": "@kbn/core-saved-objects-common", "scope": "common", @@ -16582,7 +16582,7 @@ }, " | undefined; textBased?: ", "TextBasedPersistedState", - " | undefined; }; visualization: unknown; }; }; abortController?: AbortController | undefined; withDefaultActions?: boolean | undefined; extraActions?: ", + " | undefined; }; visualization: unknown; }; }; abortController?: AbortController | undefined; noPadding?: boolean | undefined; withDefaultActions?: boolean | undefined; extraActions?: ", { "pluginId": "uiActions", "scope": "public", @@ -16852,7 +16852,7 @@ "section": "def-public.ViewMode", "text": "ViewMode" }, - " | undefined; noPadding?: boolean | undefined; isNewPanel?: boolean | undefined; attributes: { title: string; description?: string | undefined; references: ", + " | undefined; isNewPanel?: boolean | undefined; attributes: { title: string; description?: string | undefined; references: ", { "pluginId": "@kbn/core-saved-objects-common", "scope": "common", @@ -17366,7 +17366,7 @@ }, " | undefined; textBased?: ", "TextBasedPersistedState", - " | undefined; }; visualization: unknown; }; }; abortController?: AbortController | undefined; withDefaultActions?: boolean | undefined; extraActions?: ", + " | undefined; }; visualization: unknown; }; }; abortController?: AbortController | undefined; noPadding?: boolean | undefined; withDefaultActions?: boolean | undefined; extraActions?: ", { "pluginId": "uiActions", "scope": "public", @@ -17985,15 +17985,7 @@ "section": "def-common.PaletteOutput", "text": "PaletteOutput" }, - "<{ [key: string]: unknown; }> | undefined; title?: string | undefined; description?: string | undefined; hidePanelTitles?: boolean | undefined; executionContext?: ", - { - "pluginId": "@kbn/core-execution-context-common", - "scope": "common", - "docId": "kibKbnCoreExecutionContextCommonPluginApi", - "section": "def-common.KibanaExecutionContext", - "text": "KibanaExecutionContext" - }, - " | undefined; style?: React.CSSProperties | undefined; className?: string | undefined; noPadding?: boolean | undefined; viewMode?: ", + "<{ [key: string]: unknown; }> | undefined; title?: string | undefined; description?: string | undefined; hidePanelTitles?: boolean | undefined; className?: string | undefined; style?: React.CSSProperties | undefined; viewMode?: ", { "pluginId": "@kbn/presentation-publishing", "scope": "public", @@ -18001,6 +17993,14 @@ "section": "def-public.ViewMode", "text": "ViewMode" }, + " | undefined; executionContext?: ", + { + "pluginId": "@kbn/core-execution-context-common", + "scope": "common", + "docId": "kibKbnCoreExecutionContextCommonPluginApi", + "section": "def-common.KibanaExecutionContext", + "text": "KibanaExecutionContext" + }, " | undefined; enhancements?: { dynamicActions: ", { "pluginId": "uiActionsEnhanced", @@ -18191,7 +18191,7 @@ "section": "def-public.ViewMode", "text": "ViewMode" }, - " | undefined; noPadding?: boolean | undefined; isNewPanel?: boolean | undefined; attributes: { title: string; description?: string | undefined; state: { datasourceStates: Record; visualization: unknown; query: ", + " | undefined; isNewPanel?: boolean | undefined; attributes: { title: string; description?: string | undefined; state: { datasourceStates: Record; visualization: unknown; query: ", { "pluginId": "@kbn/es-query", "scope": "common", @@ -18527,7 +18527,7 @@ "section": "def-public.ViewMode", "text": "ViewMode" }, - " | undefined; noPadding?: boolean | undefined; isNewPanel?: boolean | undefined; attributes: { title: string; description?: string | undefined; state: { datasourceStates: Record; visualization: unknown; query: ", + " | undefined; isNewPanel?: boolean | undefined; attributes: { title: string; description?: string | undefined; state: { datasourceStates: Record; visualization: unknown; query: ", { "pluginId": "@kbn/es-query", "scope": "common", @@ -18759,7 +18759,7 @@ "section": "def-public.ViewMode", "text": "ViewMode" }, - " | undefined; noPadding?: boolean | undefined; isNewPanel?: boolean | undefined; attributes: { title: string; description?: string | undefined; state: { datasourceStates: Record; visualization: unknown; query: ", + " | undefined; isNewPanel?: boolean | undefined; attributes: { title: string; description?: string | undefined; state: { datasourceStates: Record; visualization: unknown; query: ", { "pluginId": "@kbn/es-query", "scope": "common", @@ -20539,15 +20539,7 @@ "section": "def-common.PaletteOutput", "text": "PaletteOutput" }, - "<{ [key: string]: unknown; }> | undefined; title?: string | undefined; description?: string | undefined; hidePanelTitles?: boolean | undefined; executionContext?: ", - { - "pluginId": "@kbn/core-execution-context-common", - "scope": "common", - "docId": "kibKbnCoreExecutionContextCommonPluginApi", - "section": "def-common.KibanaExecutionContext", - "text": "KibanaExecutionContext" - }, - " | undefined; style?: React.CSSProperties | undefined; className?: string | undefined; noPadding?: boolean | undefined; viewMode?: ", + "<{ [key: string]: unknown; }> | undefined; title?: string | undefined; description?: string | undefined; hidePanelTitles?: boolean | undefined; className?: string | undefined; style?: React.CSSProperties | undefined; viewMode?: ", { "pluginId": "@kbn/presentation-publishing", "scope": "public", @@ -20555,6 +20547,14 @@ "section": "def-public.ViewMode", "text": "ViewMode" }, + " | undefined; executionContext?: ", + { + "pluginId": "@kbn/core-execution-context-common", + "scope": "common", + "docId": "kibKbnCoreExecutionContextCommonPluginApi", + "section": "def-common.KibanaExecutionContext", + "text": "KibanaExecutionContext" + }, " | undefined; enhancements?: { dynamicActions: ", { "pluginId": "uiActionsEnhanced", @@ -20745,7 +20745,7 @@ "section": "def-public.ViewMode", "text": "ViewMode" }, - " | undefined; noPadding?: boolean | undefined; isNewPanel?: boolean | undefined; attributes: { title: string; description?: string | undefined; state: { datasourceStates: Record; visualization: unknown; query: ", + " | undefined; isNewPanel?: boolean | undefined; attributes: { title: string; description?: string | undefined; state: { datasourceStates: Record; visualization: unknown; query: ", { "pluginId": "@kbn/es-query", "scope": "common", @@ -21081,7 +21081,7 @@ "section": "def-public.ViewMode", "text": "ViewMode" }, - " | undefined; noPadding?: boolean | undefined; isNewPanel?: boolean | undefined; attributes: { title: string; description?: string | undefined; state: { datasourceStates: Record; visualization: unknown; query: ", + " | undefined; isNewPanel?: boolean | undefined; attributes: { title: string; description?: string | undefined; state: { datasourceStates: Record; visualization: unknown; query: ", { "pluginId": "@kbn/es-query", "scope": "common", @@ -21313,7 +21313,7 @@ "section": "def-public.ViewMode", "text": "ViewMode" }, - " | undefined; noPadding?: boolean | undefined; isNewPanel?: boolean | undefined; attributes: { title: string; description?: string | undefined; state: { datasourceStates: Record; visualization: unknown; query: ", + " | undefined; isNewPanel?: boolean | undefined; attributes: { title: string; description?: string | undefined; state: { datasourceStates: Record; visualization: unknown; query: ", { "pluginId": "@kbn/es-query", "scope": "common", @@ -21818,7 +21818,7 @@ "section": "def-public.ViewMode", "text": "ViewMode" }, - " | undefined; noPadding?: boolean | undefined; isNewPanel?: boolean | undefined; attributes: { title: string; description?: string | undefined; references: ", + " | undefined; isNewPanel?: boolean | undefined; attributes: { title: string; description?: string | undefined; references: ", { "pluginId": "@kbn/core-saved-objects-common", "scope": "common", @@ -22332,7 +22332,7 @@ }, " | undefined; textBased?: ", "TextBasedPersistedState", - " | undefined; }; visualization: unknown; }; }; abortController?: AbortController | undefined; withDefaultActions?: boolean | undefined; extraActions?: ", + " | undefined; }; visualization: unknown; }; }; abortController?: AbortController | undefined; noPadding?: boolean | undefined; withDefaultActions?: boolean | undefined; extraActions?: ", { "pluginId": "uiActions", "scope": "public", @@ -22611,7 +22611,7 @@ "section": "def-public.ViewMode", "text": "ViewMode" }, - " | undefined; noPadding?: boolean | undefined; isNewPanel?: boolean | undefined; attributes: { title: string; description?: string | undefined; state: { datasourceStates: Record; visualization: unknown; query: ", + " | undefined; isNewPanel?: boolean | undefined; attributes: { title: string; description?: string | undefined; state: { datasourceStates: Record; visualization: unknown; query: ", { "pluginId": "@kbn/es-query", "scope": "common", @@ -22955,15 +22955,7 @@ "section": "def-common.PaletteOutput", "text": "PaletteOutput" }, - "<{ [key: string]: unknown; }> | undefined; title?: string | undefined; description?: string | undefined; hidePanelTitles?: boolean | undefined; executionContext?: ", - { - "pluginId": "@kbn/core-execution-context-common", - "scope": "common", - "docId": "kibKbnCoreExecutionContextCommonPluginApi", - "section": "def-common.KibanaExecutionContext", - "text": "KibanaExecutionContext" - }, - " | undefined; style?: React.CSSProperties | undefined; className?: string | undefined; noPadding?: boolean | undefined; viewMode?: ", + "<{ [key: string]: unknown; }> | undefined; title?: string | undefined; description?: string | undefined; hidePanelTitles?: boolean | undefined; className?: string | undefined; style?: React.CSSProperties | undefined; viewMode?: ", { "pluginId": "@kbn/presentation-publishing", "scope": "public", @@ -22971,6 +22963,14 @@ "section": "def-public.ViewMode", "text": "ViewMode" }, + " | undefined; executionContext?: ", + { + "pluginId": "@kbn/core-execution-context-common", + "scope": "common", + "docId": "kibKbnCoreExecutionContextCommonPluginApi", + "section": "def-common.KibanaExecutionContext", + "text": "KibanaExecutionContext" + }, " | undefined; enhancements?: { dynamicActions: ", { "pluginId": "uiActionsEnhanced", diff --git a/api_docs/lens.mdx b/api_docs/lens.mdx index 1ba30e7d7aa34..2a0fa0fac8df9 100644 --- a/api_docs/lens.mdx +++ b/api_docs/lens.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/lens title: "lens" image: https://source.unsplash.com/400x175/?github description: API docs for the lens plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'lens'] --- import lensObj from './lens.devdocs.json'; diff --git a/api_docs/license_api_guard.mdx b/api_docs/license_api_guard.mdx index eaa76c823abfb..50c415af42cc7 100644 --- a/api_docs/license_api_guard.mdx +++ b/api_docs/license_api_guard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licenseApiGuard title: "licenseApiGuard" image: https://source.unsplash.com/400x175/?github description: API docs for the licenseApiGuard plugin -date: 2024-11-29 +date: 2024-12-03 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 a877c66525605..4bb9d046ea56c 100644 --- a/api_docs/license_management.mdx +++ b/api_docs/license_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licenseManagement title: "licenseManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the licenseManagement plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licenseManagement'] --- import licenseManagementObj from './license_management.devdocs.json'; diff --git a/api_docs/licensing.devdocs.json b/api_docs/licensing.devdocs.json index 57adc07f1a93b..954110ba3ede9 100644 --- a/api_docs/licensing.devdocs.json +++ b/api_docs/licensing.devdocs.json @@ -850,10 +850,6 @@ "plugin": "watcher", "path": "x-pack/plugins/watcher/public/plugin.ts" }, - { - "plugin": "profiling", - "path": "x-pack/plugins/observability_solution/profiling/public/components/contexts/license/license_context.tsx" - }, { "plugin": "slo", "path": "x-pack/plugins/observability_solution/slo/public/plugin.ts" diff --git a/api_docs/licensing.mdx b/api_docs/licensing.mdx index cb6625943b28f..8e4aa9179672c 100644 --- a/api_docs/licensing.mdx +++ b/api_docs/licensing.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licensing title: "licensing" image: https://source.unsplash.com/400x175/?github description: API docs for the licensing plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licensing'] --- import licensingObj from './licensing.devdocs.json'; diff --git a/api_docs/links.mdx b/api_docs/links.mdx index 92382e70bdb17..3666a3ae56f0b 100644 --- a/api_docs/links.mdx +++ b/api_docs/links.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/links title: "links" image: https://source.unsplash.com/400x175/?github description: API docs for the links plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'links'] --- import linksObj from './links.devdocs.json'; diff --git a/api_docs/lists.mdx b/api_docs/lists.mdx index c1932702a2421..03c4dff3ed058 100644 --- a/api_docs/lists.mdx +++ b/api_docs/lists.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/lists title: "lists" image: https://source.unsplash.com/400x175/?github description: API docs for the lists plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'lists'] --- import listsObj from './lists.devdocs.json'; diff --git a/api_docs/llm_tasks.mdx b/api_docs/llm_tasks.mdx index 592a7e7be260f..d8ce2477322ab 100644 --- a/api_docs/llm_tasks.mdx +++ b/api_docs/llm_tasks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/llmTasks title: "llmTasks" image: https://source.unsplash.com/400x175/?github description: API docs for the llmTasks plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'llmTasks'] --- import llmTasksObj from './llm_tasks.devdocs.json'; diff --git a/api_docs/logs_data_access.mdx b/api_docs/logs_data_access.mdx index 3b50f1d16ec39..583d6c438c7a4 100644 --- a/api_docs/logs_data_access.mdx +++ b/api_docs/logs_data_access.mdx @@ -8,14 +8,14 @@ slug: /kibana-dev-docs/api/logsDataAccess title: "logsDataAccess" image: https://source.unsplash.com/400x175/?github description: API docs for the logsDataAccess plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'logsDataAccess'] --- import logsDataAccessObj from './logs_data_access.devdocs.json'; -Contact [@elastic/obs-knowledge-team](https://github.com/orgs/elastic/teams/obs-knowledge-team) for questions regarding this plugin. +Contact [@elastic/obs-ux-logs-team](https://github.com/orgs/elastic/teams/obs-ux-logs-team) for questions regarding this plugin. **Code health stats** diff --git a/api_docs/logs_explorer.devdocs.json b/api_docs/logs_explorer.devdocs.json index fefcffd0f9174..d05a47b7590d0 100644 --- a/api_docs/logs_explorer.devdocs.json +++ b/api_docs/logs_explorer.devdocs.json @@ -311,7 +311,13 @@ "description": [], "signature": [ "Pick>, \"data\" | \"history\" | \"uiSettings\" | \"timefilter\" | \"filterManager\"> & { urlStateStorage: ", { "pluginId": "kibanaUtils", diff --git a/api_docs/logs_explorer.mdx b/api_docs/logs_explorer.mdx index af99f280f9542..baefde7680169 100644 --- a/api_docs/logs_explorer.mdx +++ b/api_docs/logs_explorer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/logsExplorer title: "logsExplorer" image: https://source.unsplash.com/400x175/?github description: API docs for the logsExplorer plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'logsExplorer'] --- import logsExplorerObj from './logs_explorer.devdocs.json'; diff --git a/api_docs/logs_shared.devdocs.json b/api_docs/logs_shared.devdocs.json index 70accf5e5f656..9f8ec3fc78fad 100644 --- a/api_docs/logs_shared.devdocs.json +++ b/api_docs/logs_shared.devdocs.json @@ -3164,6 +3164,46 @@ "path": "x-pack/plugins/observability_solution/logs_shared/public/types.ts", "deprecated": false, "trackAdoption": false + }, + { + "parentPluginId": "logsShared", + "id": "def-public.LogsSharedClientStartDeps.embeddable", + "type": "Object", + "tags": [], + "label": "embeddable", + "description": [], + "signature": [ + { + "pluginId": "embeddable", + "scope": "public", + "docId": "kibEmbeddablePluginApi", + "section": "def-public.EmbeddableStart", + "text": "EmbeddableStart" + } + ], + "path": "x-pack/plugins/observability_solution/logs_shared/public/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "logsShared", + "id": "def-public.LogsSharedClientStartDeps.savedSearch", + "type": "Object", + "tags": [], + "label": "savedSearch", + "description": [], + "signature": [ + { + "pluginId": "savedSearch", + "scope": "public", + "docId": "kibSavedSearchPluginApi", + "section": "def-public.SavedSearchPublicPluginStart", + "text": "SavedSearchPublicPluginStart" + } + ], + "path": "x-pack/plugins/observability_solution/logs_shared/public/types.ts", + "deprecated": false, + "trackAdoption": false } ], "initialIsOpen": false diff --git a/api_docs/logs_shared.mdx b/api_docs/logs_shared.mdx index b3f832946f7ad..86875b5059324 100644 --- a/api_docs/logs_shared.mdx +++ b/api_docs/logs_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/logsShared title: "logsShared" image: https://source.unsplash.com/400x175/?github description: API docs for the logsShared plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'logsShared'] --- import logsSharedObj from './logs_shared.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 | |-------------------|-----------|------------------------|-----------------| -| 314 | 0 | 285 | 34 | +| 316 | 0 | 287 | 34 | ## Client diff --git a/api_docs/management.mdx b/api_docs/management.mdx index ca5b64a7773ec..2a0acf38e95f9 100644 --- a/api_docs/management.mdx +++ b/api_docs/management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/management title: "management" image: https://source.unsplash.com/400x175/?github description: API docs for the management plugin -date: 2024-11-29 +date: 2024-12-03 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 19ba8606183d2..7b7896bf2a386 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: 2024-11-29 +date: 2024-12-03 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 3bdc6f47eb3f9..fa7e566583a8f 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: 2024-11-29 +date: 2024-12-03 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 dc2b37edae974..7d48db8921317 100644 --- a/api_docs/metrics_data_access.mdx +++ b/api_docs/metrics_data_access.mdx @@ -8,14 +8,14 @@ slug: /kibana-dev-docs/api/metricsDataAccess title: "metricsDataAccess" image: https://source.unsplash.com/400x175/?github description: API docs for the metricsDataAccess plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'metricsDataAccess'] --- import metricsDataAccessObj from './metrics_data_access.devdocs.json'; Exposes utilities for accessing metrics data -Contact [@elastic/obs-knowledge-team](https://github.com/orgs/elastic/teams/obs-knowledge-team) for questions regarding this plugin. +Contact [@elastic/obs-ux-infra_services-team](https://github.com/orgs/elastic/teams/obs-ux-infra_services-team) for questions regarding this plugin. **Code health stats** diff --git a/api_docs/ml.mdx b/api_docs/ml.mdx index 52a1e63524e2b..7f436ec133229 100644 --- a/api_docs/ml.mdx +++ b/api_docs/ml.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ml title: "ml" image: https://source.unsplash.com/400x175/?github description: API docs for the ml plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ml'] --- import mlObj from './ml.devdocs.json'; diff --git a/api_docs/mock_idp_plugin.mdx b/api_docs/mock_idp_plugin.mdx index 33530a3d2bb08..db1d4898b1296 100644 --- a/api_docs/mock_idp_plugin.mdx +++ b/api_docs/mock_idp_plugin.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/mockIdpPlugin title: "mockIdpPlugin" image: https://source.unsplash.com/400x175/?github description: API docs for the mockIdpPlugin plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'mockIdpPlugin'] --- import mockIdpPluginObj from './mock_idp_plugin.devdocs.json'; diff --git a/api_docs/monitoring.mdx b/api_docs/monitoring.mdx index 8e5e7c10c671c..23ecf827b250f 100644 --- a/api_docs/monitoring.mdx +++ b/api_docs/monitoring.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/monitoring title: "monitoring" image: https://source.unsplash.com/400x175/?github description: API docs for the monitoring plugin -date: 2024-11-29 +date: 2024-12-03 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 e2d91adfdd6d1..e761debc4aa24 100644 --- a/api_docs/monitoring_collection.mdx +++ b/api_docs/monitoring_collection.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/monitoringCollection title: "monitoringCollection" image: https://source.unsplash.com/400x175/?github description: API docs for the monitoringCollection plugin -date: 2024-11-29 +date: 2024-12-03 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 e3690b6d00b9c..699697eb251b3 100644 --- a/api_docs/navigation.mdx +++ b/api_docs/navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/navigation title: "navigation" image: https://source.unsplash.com/400x175/?github description: API docs for the navigation plugin -date: 2024-11-29 +date: 2024-12-03 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 273af10f6c484..245a48893309c 100644 --- a/api_docs/newsfeed.mdx +++ b/api_docs/newsfeed.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/newsfeed title: "newsfeed" image: https://source.unsplash.com/400x175/?github description: API docs for the newsfeed plugin -date: 2024-11-29 +date: 2024-12-03 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 5baccf6b94c46..cabc113dcef80 100644 --- a/api_docs/no_data_page.mdx +++ b/api_docs/no_data_page.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/noDataPage title: "noDataPage" image: https://source.unsplash.com/400x175/?github description: API docs for the noDataPage plugin -date: 2024-11-29 +date: 2024-12-03 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 fd4dd5b37dbc2..6fffbb0d80b3e 100644 --- a/api_docs/notifications.mdx +++ b/api_docs/notifications.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/notifications title: "notifications" image: https://source.unsplash.com/400x175/?github description: API docs for the notifications plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'notifications'] --- import notificationsObj from './notifications.devdocs.json'; diff --git a/api_docs/observability.devdocs.json b/api_docs/observability.devdocs.json index 6f2110a875d2a..89b649746b7af 100644 --- a/api_docs/observability.devdocs.json +++ b/api_docs/observability.devdocs.json @@ -1008,7 +1008,7 @@ "label": "useAnnotations", "description": [], "signature": [ - "({ domain, editAnnotation, slo, setEditAnnotation, }?: { slo?: ({ id: string; name: string; description: string; indicator: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.synthetics.availability\"; params: { monitorIds: { value: string; label: string; }[]; index: string; } & { tags?: { value: string; label: string; }[] | undefined; projects?: { value: string; label: string; }[] | undefined; filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; good: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; }; total: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.metric.custom\"; params: { index: string; good: { metrics: (({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; }; total: { metrics: (({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.metric.timeslice\"; params: { index: string; metric: { metrics: (({ name: string; aggregation: \"min\" | \"max\" | \"sum\" | \"avg\" | \"cardinality\" | \"last_value\" | \"std_deviation\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"percentile\"; field: string; percentile: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; threshold: number; comparator: \"GT\" | \"GTE\" | \"LT\" | \"LTE\"; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.histogram.custom\"; params: { index: string; timestampField: string; good: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }); total: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }); } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; }; timeWindow: { duration: string; type: \"rolling\"; } | { duration: string; type: \"calendarAligned\"; }; budgetingMethod: \"occurrences\" | \"timeslices\"; objective: { target: number; } & { timesliceTarget?: number | undefined; timesliceWindow?: string | undefined; }; settings: { syncDelay: string; frequency: string; preventInitialBackfill: boolean; }; revision: number; enabled: boolean; tags: string[]; createdAt: string; updatedAt: string; groupBy: string | string[]; version: number; } & { summary: { status: \"HEALTHY\" | \"NO_DATA\" | \"DEGRADING\" | \"VIOLATED\"; sliValue: number; errorBudget: { initial: number; consumed: number; remaining: number; isEstimated: boolean; }; fiveMinuteBurnRate: number; oneHourBurnRate: number; oneDayBurnRate: number; } & { summaryUpdatedAt?: string | null | undefined; }; groupings: { [x: string]: string | number; }; } & { instanceId?: string | undefined; meta?: { synthetics?: { monitorId: string; locationId: string; configId: string; } | undefined; } | undefined; remote?: { remoteName: string; kibanaUrl: string; } | undefined; }) | undefined; editAnnotation?: ({ id: string; } & { annotation: { title?: string | undefined; type?: string | undefined; style?: { icon?: string | undefined; color?: string | undefined; line?: { width?: number | undefined; style?: \"dashed\" | \"solid\" | \"dotted\" | undefined; iconPosition?: \"top\" | \"bottom\" | undefined; textDecoration?: \"none\" | \"name\" | undefined; } | undefined; rect?: { fill?: \"inside\" | \"outside\" | undefined; } | undefined; } | undefined; }; '@timestamp': string; message: string; } & { event?: ({ start: string; } & { end?: string | undefined; }) | undefined; tags?: string[] | undefined; service?: { name?: string | undefined; environment?: string | undefined; version?: string | undefined; } | undefined; monitor?: { id?: string | undefined; } | undefined; slo?: ({ id: string; } & { instanceId?: string | undefined; }) | undefined; host?: { name?: string | undefined; } | undefined; }) | null | undefined; setEditAnnotation?: ((annotation: ({ id: string; } & { annotation: { title?: string | undefined; type?: string | undefined; style?: { icon?: string | undefined; color?: string | undefined; line?: { width?: number | undefined; style?: \"dashed\" | \"solid\" | \"dotted\" | undefined; iconPosition?: \"top\" | \"bottom\" | undefined; textDecoration?: \"none\" | \"name\" | undefined; } | undefined; rect?: { fill?: \"inside\" | \"outside\" | undefined; } | undefined; } | undefined; }; '@timestamp': string; message: string; } & { event?: ({ start: string; } & { end?: string | undefined; }) | undefined; tags?: string[] | undefined; service?: { name?: string | undefined; environment?: string | undefined; version?: string | undefined; } | undefined; monitor?: { id?: string | undefined; } | undefined; slo?: ({ id: string; } & { instanceId?: string | undefined; }) | undefined; host?: { name?: string | undefined; } | undefined; }) | null) => void) | undefined; domain?: { min: string | number; max: string | number; } | undefined; }) => { annotations: ({ id: string; } & { annotation: { title?: string | undefined; type?: string | undefined; style?: { icon?: string | undefined; color?: string | undefined; line?: { width?: number | undefined; style?: \"dashed\" | \"solid\" | \"dotted\" | undefined; iconPosition?: \"top\" | \"bottom\" | undefined; textDecoration?: \"none\" | \"name\" | undefined; } | undefined; rect?: { fill?: \"inside\" | \"outside\" | undefined; } | undefined; } | undefined; }; '@timestamp': string; message: string; } & { event?: ({ start: string; } & { end?: string | undefined; }) | undefined; tags?: string[] | undefined; service?: { name?: string | undefined; environment?: string | undefined; version?: string | undefined; } | undefined; monitor?: { id?: string | undefined; } | undefined; slo?: ({ id: string; } & { instanceId?: string | undefined; }) | undefined; host?: { name?: string | undefined; } | undefined; })[]; onAnnotationClick: (annotations: { rects: ", + "({ domain, editAnnotation, slo, setEditAnnotation, }?: { slo?: ({ id: string; name: string; description: string; indicator: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.synthetics.availability\"; params: { monitorIds: { value: string; label: string; }[]; index: string; } & { tags?: { value: string; label: string; }[] | undefined; projects?: { value: string; label: string; }[] | undefined; filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; good: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; }; total: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.metric.custom\"; params: { index: string; good: { metrics: (({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; }; total: { metrics: (({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.metric.timeslice\"; params: { index: string; metric: { metrics: (({ name: string; aggregation: \"min\" | \"max\" | \"sum\" | \"avg\" | \"cardinality\" | \"last_value\" | \"std_deviation\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"percentile\"; field: string; percentile: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; threshold: number; comparator: \"GT\" | \"GTE\" | \"LT\" | \"LTE\"; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.histogram.custom\"; params: { index: string; timestampField: string; good: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }); total: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }); } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; }; timeWindow: { duration: string; type: \"rolling\"; } | { duration: string; type: \"calendarAligned\"; }; budgetingMethod: \"occurrences\" | \"timeslices\"; objective: { target: number; } & { timesliceTarget?: number | undefined; timesliceWindow?: string | undefined; }; settings: { syncDelay: string; frequency: string; preventInitialBackfill: boolean; } & { syncField?: string | null | undefined; }; revision: number; enabled: boolean; tags: string[]; createdAt: string; updatedAt: string; groupBy: string | string[]; version: number; } & { summary: { status: \"HEALTHY\" | \"NO_DATA\" | \"DEGRADING\" | \"VIOLATED\"; sliValue: number; errorBudget: { initial: number; consumed: number; remaining: number; isEstimated: boolean; }; fiveMinuteBurnRate: number; oneHourBurnRate: number; oneDayBurnRate: number; } & { summaryUpdatedAt?: string | null | undefined; }; groupings: { [x: string]: string | number; }; } & { instanceId?: string | undefined; meta?: { synthetics?: { monitorId: string; locationId: string; configId: string; } | undefined; } | undefined; remote?: { remoteName: string; kibanaUrl: string; } | undefined; }) | undefined; editAnnotation?: ({ id: string; } & { annotation: { title?: string | undefined; type?: string | undefined; style?: { icon?: string | undefined; color?: string | undefined; line?: { width?: number | undefined; style?: \"dashed\" | \"solid\" | \"dotted\" | undefined; iconPosition?: \"top\" | \"bottom\" | undefined; textDecoration?: \"none\" | \"name\" | undefined; } | undefined; rect?: { fill?: \"inside\" | \"outside\" | undefined; } | undefined; } | undefined; }; '@timestamp': string; message: string; } & { event?: ({ start: string; } & { end?: string | undefined; }) | undefined; tags?: string[] | undefined; service?: { name?: string | undefined; environment?: string | undefined; version?: string | undefined; } | undefined; monitor?: { id?: string | undefined; } | undefined; slo?: ({ id: string; } & { instanceId?: string | undefined; }) | undefined; host?: { name?: string | undefined; } | undefined; }) | null | undefined; setEditAnnotation?: ((annotation: ({ id: string; } & { annotation: { title?: string | undefined; type?: string | undefined; style?: { icon?: string | undefined; color?: string | undefined; line?: { width?: number | undefined; style?: \"dashed\" | \"solid\" | \"dotted\" | undefined; iconPosition?: \"top\" | \"bottom\" | undefined; textDecoration?: \"none\" | \"name\" | undefined; } | undefined; rect?: { fill?: \"inside\" | \"outside\" | undefined; } | undefined; } | undefined; }; '@timestamp': string; message: string; } & { event?: ({ start: string; } & { end?: string | undefined; }) | undefined; tags?: string[] | undefined; service?: { name?: string | undefined; environment?: string | undefined; version?: string | undefined; } | undefined; monitor?: { id?: string | undefined; } | undefined; slo?: ({ id: string; } & { instanceId?: string | undefined; }) | undefined; host?: { name?: string | undefined; } | undefined; }) | null) => void) | undefined; domain?: { min: string | number; max: string | number; } | undefined; }) => { annotations: ({ id: string; } & { annotation: { title?: string | undefined; type?: string | undefined; style?: { icon?: string | undefined; color?: string | undefined; line?: { width?: number | undefined; style?: \"dashed\" | \"solid\" | \"dotted\" | undefined; iconPosition?: \"top\" | \"bottom\" | undefined; textDecoration?: \"none\" | \"name\" | undefined; } | undefined; rect?: { fill?: \"inside\" | \"outside\" | undefined; } | undefined; } | undefined; }; '@timestamp': string; message: string; } & { event?: ({ start: string; } & { end?: string | undefined; }) | undefined; tags?: string[] | undefined; service?: { name?: string | undefined; environment?: string | undefined; version?: string | undefined; } | undefined; monitor?: { id?: string | undefined; } | undefined; slo?: ({ id: string; } & { instanceId?: string | undefined; }) | undefined; host?: { name?: string | undefined; } | undefined; })[]; onAnnotationClick: (annotations: { rects: ", "RectAnnotationEvent", "[]; lines: ", "LineAnnotationEvent", @@ -1045,7 +1045,7 @@ "label": "slo", "description": [], "signature": [ - "({ id: string; name: string; description: string; indicator: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.synthetics.availability\"; params: { monitorIds: { value: string; label: string; }[]; index: string; } & { tags?: { value: string; label: string; }[] | undefined; projects?: { value: string; label: string; }[] | undefined; filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; good: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; }; total: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.metric.custom\"; params: { index: string; good: { metrics: (({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; }; total: { metrics: (({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.metric.timeslice\"; params: { index: string; metric: { metrics: (({ name: string; aggregation: \"min\" | \"max\" | \"sum\" | \"avg\" | \"cardinality\" | \"last_value\" | \"std_deviation\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"percentile\"; field: string; percentile: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; threshold: number; comparator: \"GT\" | \"GTE\" | \"LT\" | \"LTE\"; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.histogram.custom\"; params: { index: string; timestampField: string; good: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }); total: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }); } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; }; timeWindow: { duration: string; type: \"rolling\"; } | { duration: string; type: \"calendarAligned\"; }; budgetingMethod: \"occurrences\" | \"timeslices\"; objective: { target: number; } & { timesliceTarget?: number | undefined; timesliceWindow?: string | undefined; }; settings: { syncDelay: string; frequency: string; preventInitialBackfill: boolean; }; revision: number; enabled: boolean; tags: string[]; createdAt: string; updatedAt: string; groupBy: string | string[]; version: number; } & { summary: { status: \"HEALTHY\" | \"NO_DATA\" | \"DEGRADING\" | \"VIOLATED\"; sliValue: number; errorBudget: { initial: number; consumed: number; remaining: number; isEstimated: boolean; }; fiveMinuteBurnRate: number; oneHourBurnRate: number; oneDayBurnRate: number; } & { summaryUpdatedAt?: string | null | undefined; }; groupings: { [x: string]: string | number; }; } & { instanceId?: string | undefined; meta?: { synthetics?: { monitorId: string; locationId: string; configId: string; } | undefined; } | undefined; remote?: { remoteName: string; kibanaUrl: string; } | undefined; }) | undefined" + "({ id: string; name: string; description: string; indicator: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.synthetics.availability\"; params: { monitorIds: { value: string; label: string; }[]; index: string; } & { tags?: { value: string; label: string; }[] | undefined; projects?: { value: string; label: string; }[] | undefined; filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; good: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; }; total: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.metric.custom\"; params: { index: string; good: { metrics: (({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; }; total: { metrics: (({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.metric.timeslice\"; params: { index: string; metric: { metrics: (({ name: string; aggregation: \"min\" | \"max\" | \"sum\" | \"avg\" | \"cardinality\" | \"last_value\" | \"std_deviation\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"percentile\"; field: string; percentile: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; threshold: number; comparator: \"GT\" | \"GTE\" | \"LT\" | \"LTE\"; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.histogram.custom\"; params: { index: string; timestampField: string; good: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }); total: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }); } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; }; timeWindow: { duration: string; type: \"rolling\"; } | { duration: string; type: \"calendarAligned\"; }; budgetingMethod: \"occurrences\" | \"timeslices\"; objective: { target: number; } & { timesliceTarget?: number | undefined; timesliceWindow?: string | undefined; }; settings: { syncDelay: string; frequency: string; preventInitialBackfill: boolean; } & { syncField?: string | null | undefined; }; revision: number; enabled: boolean; tags: string[]; createdAt: string; updatedAt: string; groupBy: string | string[]; version: number; } & { summary: { status: \"HEALTHY\" | \"NO_DATA\" | \"DEGRADING\" | \"VIOLATED\"; sliValue: number; errorBudget: { initial: number; consumed: number; remaining: number; isEstimated: boolean; }; fiveMinuteBurnRate: number; oneHourBurnRate: number; oneDayBurnRate: number; } & { summaryUpdatedAt?: string | null | undefined; }; groupings: { [x: string]: string | number; }; } & { instanceId?: string | undefined; meta?: { synthetics?: { monitorId: string; locationId: string; configId: string; } | undefined; } | undefined; remote?: { remoteName: string; kibanaUrl: string; } | undefined; }) | undefined" ], "path": "x-pack/plugins/observability_solution/observability/public/components/annotations/use_annotations.tsx", "deprecated": false, diff --git a/api_docs/observability.mdx b/api_docs/observability.mdx index 741bbc5bbd819..e41db59251190 100644 --- a/api_docs/observability.mdx +++ b/api_docs/observability.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observability title: "observability" image: https://source.unsplash.com/400x175/?github description: API docs for the observability plugin -date: 2024-11-29 +date: 2024-12-03 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 a11aa4c4548bd..322e88d27cdf3 100644 --- a/api_docs/observability_a_i_assistant.devdocs.json +++ b/api_docs/observability_a_i_assistant.devdocs.json @@ -2418,18 +2418,8 @@ "<{ id: ", "StringC", "; text: ", - "BrandC", - "<", "StringC", - ", ", - { - "pluginId": "@kbn/io-ts-utils", - "scope": "common", - "docId": "kibKbnIoTsUtilsPluginApi", - "section": "def-common.NonEmptyStringBrand", - "text": "NonEmptyStringBrand" - }, - ">; public: ", + "; public: ", "Type", "; }>; }>, ", "ObservabilityAIAssistantRouteHandlerResources", @@ -3398,18 +3388,8 @@ "<{ id: ", "StringC", "; text: ", - "BrandC", - "<", "StringC", - ", ", - { - "pluginId": "@kbn/io-ts-utils", - "scope": "common", - "docId": "kibKbnIoTsUtilsPluginApi", - "section": "def-common.NonEmptyStringBrand", - "text": "NonEmptyStringBrand" - }, - ">; public: ", + "; public: ", "Type", "; }>; }>, ", "ObservabilityAIAssistantRouteHandlerResources", @@ -5115,18 +5095,8 @@ "<{ id: ", "StringC", "; text: ", - "BrandC", - "<", "StringC", - ", ", - { - "pluginId": "@kbn/io-ts-utils", - "scope": "common", - "docId": "kibKbnIoTsUtilsPluginApi", - "section": "def-common.NonEmptyStringBrand", - "text": "NonEmptyStringBrand" - }, - ">; public: ", + "; public: ", "Type", "; }>; }>, ", "ObservabilityAIAssistantRouteHandlerResources", @@ -6322,18 +6292,8 @@ "<{ id: ", "StringC", "; text: ", - "BrandC", - "<", "StringC", - ", ", - { - "pluginId": "@kbn/io-ts-utils", - "scope": "common", - "docId": "kibKbnIoTsUtilsPluginApi", - "section": "def-common.NonEmptyStringBrand", - "text": "NonEmptyStringBrand" - }, - ">; public: ", + "; public: ", "Type", "; }>; }>, ", "ObservabilityAIAssistantRouteHandlerResources", @@ -7301,7 +7261,17 @@ "section": "def-common.AssistantScope", "text": "AssistantScope" }, - "[]; }; }" + "[]; }; } | { type: ", + { + "pluginId": "observabilityAIAssistant", + "scope": "public", + "docId": "kibObservabilityAIAssistantPluginApi", + "section": "def-public.ObservabilityAIAssistantTelemetryEventType", + "text": "ObservabilityAIAssistantTelemetryEventType" + }, + ".InsightResponse; payload: ", + "InsightResponse", + "; }" ], "path": "x-pack/plugins/observability_solution/observability_ai_assistant/public/analytics/index.ts", "deprecated": false, @@ -8062,18 +8032,8 @@ "<{ id: ", "StringC", "; text: ", - "BrandC", - "<", "StringC", - ", ", - { - "pluginId": "@kbn/io-ts-utils", - "scope": "common", - "docId": "kibKbnIoTsUtilsPluginApi", - "section": "def-common.NonEmptyStringBrand", - "text": "NonEmptyStringBrand" - }, - ">; public: ", + "; public: ", "Type", "; }>; }>, ", "ObservabilityAIAssistantRouteHandlerResources", diff --git a/api_docs/observability_a_i_assistant.mdx b/api_docs/observability_a_i_assistant.mdx index 7128e8b5899cf..70d5cc9a5c0be 100644 --- a/api_docs/observability_a_i_assistant.mdx +++ b/api_docs/observability_a_i_assistant.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observabilityAIAssistant title: "observabilityAIAssistant" image: https://source.unsplash.com/400x175/?github description: API docs for the observabilityAIAssistant plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observabilityAIAssistant'] --- import observabilityAIAssistantObj from './observability_a_i_assistant.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/obs-ai-assistant](https://github.com/orgs/elastic/teams/obs-ai | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 296 | 1 | 294 | 27 | +| 296 | 1 | 294 | 28 | ## Client diff --git a/api_docs/observability_a_i_assistant_app.mdx b/api_docs/observability_a_i_assistant_app.mdx index 46a6981382a52..41bb15ce4fe02 100644 --- a/api_docs/observability_a_i_assistant_app.mdx +++ b/api_docs/observability_a_i_assistant_app.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observabilityAIAssistantApp title: "observabilityAIAssistantApp" image: https://source.unsplash.com/400x175/?github description: API docs for the observabilityAIAssistantApp plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observabilityAIAssistantApp'] --- import observabilityAIAssistantAppObj from './observability_a_i_assistant_app.devdocs.json'; diff --git a/api_docs/observability_ai_assistant_management.mdx b/api_docs/observability_ai_assistant_management.mdx index 2142db4c0cbd3..39d707158fee5 100644 --- a/api_docs/observability_ai_assistant_management.mdx +++ b/api_docs/observability_ai_assistant_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observabilityAiAssistantManagement title: "observabilityAiAssistantManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the observabilityAiAssistantManagement plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observabilityAiAssistantManagement'] --- import observabilityAiAssistantManagementObj from './observability_ai_assistant_management.devdocs.json'; diff --git a/api_docs/observability_logs_explorer.mdx b/api_docs/observability_logs_explorer.mdx index bbb72a97a05a5..9a8534c58aea4 100644 --- a/api_docs/observability_logs_explorer.mdx +++ b/api_docs/observability_logs_explorer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observabilityLogsExplorer title: "observabilityLogsExplorer" image: https://source.unsplash.com/400x175/?github description: API docs for the observabilityLogsExplorer plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observabilityLogsExplorer'] --- import observabilityLogsExplorerObj from './observability_logs_explorer.devdocs.json'; diff --git a/api_docs/observability_onboarding.mdx b/api_docs/observability_onboarding.mdx index ccf84c01ca186..0446c0eb1c386 100644 --- a/api_docs/observability_onboarding.mdx +++ b/api_docs/observability_onboarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observabilityOnboarding title: "observabilityOnboarding" image: https://source.unsplash.com/400x175/?github description: API docs for the observabilityOnboarding plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observabilityOnboarding'] --- import observabilityOnboardingObj from './observability_onboarding.devdocs.json'; diff --git a/api_docs/observability_shared.mdx b/api_docs/observability_shared.mdx index 15499b3cfe199..3784f6203d55b 100644 --- a/api_docs/observability_shared.mdx +++ b/api_docs/observability_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observabilityShared title: "observabilityShared" image: https://source.unsplash.com/400x175/?github description: API docs for the observabilityShared plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observabilityShared'] --- import observabilitySharedObj from './observability_shared.devdocs.json'; diff --git a/api_docs/osquery.mdx b/api_docs/osquery.mdx index 0d8970aad5b94..bf64f7fd4fd91 100644 --- a/api_docs/osquery.mdx +++ b/api_docs/osquery.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/osquery title: "osquery" image: https://source.unsplash.com/400x175/?github description: API docs for the osquery plugin -date: 2024-11-29 +date: 2024-12-03 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 7d990e843b234..3916ebb5cb959 100644 --- a/api_docs/painless_lab.mdx +++ b/api_docs/painless_lab.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/painlessLab title: "painlessLab" image: https://source.unsplash.com/400x175/?github description: API docs for the painlessLab plugin -date: 2024-11-29 +date: 2024-12-03 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 d42df1853578b..d321ce8d8ca21 100644 --- a/api_docs/plugin_directory.mdx +++ b/api_docs/plugin_directory.mdx @@ -7,7 +7,7 @@ id: kibDevDocsPluginDirectory slug: /kibana-dev-docs/api-meta/plugin-api-directory title: Directory description: Directory of public APIs available through plugins or packages. -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- @@ -15,25 +15,25 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | Count | Plugins or Packages with a
public API | Number of teams | |--------------|----------|------------------------| -| 893 | 761 | 43 | +| 895 | 762 | 43 | ### Public API health stats | API Count | Any Count | Missing comments | Missing exports | |--------------|----------|-----------------|--------| -| 54592 | 240 | 41008 | 2024 | +| 54810 | 240 | 41195 | 2033 | ## Plugin Directory | Plugin name           | Maintaining team | Description | API Cnt | Any Cnt | Missing
comments | Missing
exports | |--------------|----------------|-----------|--------------|----------|---------------|--------| -| | [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-ops) | - | 322 | 0 | 316 | 37 | +| | [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-ops) | - | 321 | 0 | 315 | 37 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 2 | 0 | 2 | 0 | -| | [@elastic/obs-knowledge-team](https://github.com/orgs/elastic/teams/obs-knowledge-team) | - | 4 | 0 | 4 | 1 | +| | [@elastic/obs-ai-assistant](https://github.com/orgs/elastic/teams/obs-ai-assistant) | - | 4 | 0 | 4 | 1 | | | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | AIOps plugin maintained by ML team. | 72 | 0 | 8 | 2 | -| | [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-ops) | - | 881 | 1 | 849 | 50 | +| | [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-ops) | - | 880 | 1 | 848 | 50 | | | [@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 | 119 | -| | [@elastic/obs-knowledge-team](https://github.com/orgs/elastic/teams/obs-knowledge-team) | - | 86 | 0 | 86 | 3 | +| | [@elastic/obs-ux-infra_services-team](https://github.com/orgs/elastic/teams/obs-ux-infra_services-team) | - | 93 | 0 | 93 | 3 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 9 | 0 | 9 | 0 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | Considering using bfetch capabilities when fetching large amounts of data. This services supports batching HTTP requests and streaming responses back. | 60 | 1 | 59 | 2 | | | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds Canvas application to Kibana | 9 | 0 | 8 | 3 | @@ -65,9 +65,9 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@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 | 4 | | | [@elastic/obs-ux-logs-team](https://github.com/orgs/elastic/teams/obs-ux-logs-team) | This plugin introduces the concept of data set quality, where users can easily get an overview on the data sets they have. | 14 | 0 | 14 | 8 | | | [@elastic/kibana-management](https://github.com/orgs/elastic/teams/kibana-management) | - | 15 | 0 | 9 | 2 | -| | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | This plugin contains the Discover application and the saved search embeddable. | 148 | 0 | 100 | 24 | +| | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | This plugin contains the Discover application and the saved search embeddable. | 214 | 0 | 166 | 30 | | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | - | 35 | 0 | 33 | 2 | -| | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | A stateful layer to register shared features and provide an access point to discover without a direct dependency | 16 | 0 | 15 | 3 | +| | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | A stateful layer to register shared features and provide an access point to discover without a direct dependency | 26 | 0 | 23 | 2 | | | [@elastic/security-threat-hunting-explore](https://github.com/orgs/elastic/teams/security-threat-hunting-explore) | APIs used to assess the quality of data in Elasticsearch indexes | 2 | 0 | 0 | 0 | | | [@elastic/security-generative-ai](https://github.com/orgs/elastic/teams/security-generative-ai) | Server APIs for the Elastic AI Assistant | 53 | 0 | 38 | 2 | | | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds embeddables service to Kibana | 578 | 1 | 468 | 9 | @@ -104,7 +104,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | The file upload plugin contains components and services for uploading a file, analyzing its data, and then importing the data into an Elasticsearch index. Supported file types include CSV, TSV, newline-delimited JSON and GeoJSON. | 89 | 0 | 89 | 8 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | File upload, download, sharing, and serving over HTTP implementation in Kibana. | 240 | 0 | 24 | 9 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | Simple UI for managing files in Kibana | 3 | 0 | 3 | 0 | -| | [@elastic/fleet](https://github.com/orgs/elastic/teams/fleet) | - | 1432 | 5 | 1306 | 82 | +| | [@elastic/fleet](https://github.com/orgs/elastic/teams/fleet) | - | 1435 | 5 | 1309 | 82 | | ftrApis | [@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) | - | 72 | 0 | 14 | 5 | | globalSearchBar | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 0 | 0 | 0 | 0 | @@ -116,7 +116,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | Image embeddable | 1 | 0 | 1 | 0 | | | [@elastic/kibana-management](https://github.com/orgs/elastic/teams/kibana-management) | - | 4 | 0 | 4 | 0 | | | [@elastic/kibana-management](https://github.com/orgs/elastic/teams/kibana-management) | - | 244 | 0 | 239 | 1 | -| | [@elastic/appex-ai-infra](https://github.com/orgs/elastic/teams/appex-ai-infra) | - | 40 | 0 | 29 | 6 | +| | [@elastic/appex-ai-infra](https://github.com/orgs/elastic/teams/appex-ai-infra) | - | 40 | 0 | 28 | 6 | | | [@elastic/obs-ux-logs-team](https://github.com/orgs/elastic/teams/obs-ux-logs-team) | This plugin visualizes data from Filebeat and Metricbeat, and integrates with other Observability solutions | 24 | 0 | 24 | 5 | | | [@elastic/kibana-management](https://github.com/orgs/elastic/teams/kibana-management) | - | 4 | 0 | 4 | 0 | | inputControlVis | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds Input Control visualization to Kibana | 0 | 0 | 0 | 0 | @@ -138,14 +138,14 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | A dashboard panel for creating links to dashboards or external links. | 5 | 0 | 5 | 0 | | | [@elastic/security-detection-engine](https://github.com/orgs/elastic/teams/security-detection-engine) | - | 227 | 0 | 98 | 52 | | | [@elastic/appex-ai-infra](https://github.com/orgs/elastic/teams/appex-ai-infra) | - | 5 | 0 | 1 | 2 | -| | [@elastic/obs-knowledge-team](https://github.com/orgs/elastic/teams/obs-knowledge-team) | - | 15 | 0 | 13 | 7 | +| | [@elastic/obs-ux-logs-team](https://github.com/orgs/elastic/teams/obs-ux-logs-team) | - | 15 | 0 | 13 | 7 | | | [@elastic/obs-ux-logs-team](https://github.com/orgs/elastic/teams/obs-ux-logs-team) | This plugin provides a LogsExplorer component using the Discover customization framework, offering several affordances specifically designed for log consumption. | 120 | 4 | 120 | 23 | -| | [@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. | 314 | 0 | 285 | 34 | +| | [@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. | 316 | 0 | 287 | 34 | | logstash | [@elastic/logstash](https://github.com/orgs/elastic/teams/logstash) | - | 0 | 0 | 0 | 0 | | | [@elastic/kibana-management](https://github.com/orgs/elastic/teams/kibana-management) | - | 44 | 0 | 44 | 7 | | | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | - | 213 | 0 | 207 | 28 | | | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | - | 60 | 0 | 60 | 0 | -| | [@elastic/obs-knowledge-team](https://github.com/orgs/elastic/teams/obs-knowledge-team) | Exposes utilities for accessing metrics data | 135 | 6 | 135 | 5 | +| | [@elastic/obs-ux-infra_services-team](https://github.com/orgs/elastic/teams/obs-ux-infra_services-team) | Exposes utilities for accessing metrics data | 135 | 6 | 135 | 5 | | | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | This plugin provides access to the machine learning features provided by Elastic. | 148 | 3 | 63 | 104 | | | [@elastic/kibana-security](https://github.com/orgs/elastic/teams/kibana-security) | - | 2 | 0 | 2 | 0 | | | [@elastic/stack-monitoring](https://github.com/orgs/elastic/teams/stack-monitoring) | - | 15 | 3 | 13 | 1 | @@ -155,7 +155,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 3 | 0 | 3 | 0 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 2 | 0 | 2 | 1 | | | [@elastic/obs-ux-management-team](https://github.com/orgs/elastic/teams/obs-ux-management-team) | - | 697 | 2 | 689 | 23 | -| | [@elastic/obs-ai-assistant](https://github.com/orgs/elastic/teams/obs-ai-assistant) | - | 296 | 1 | 294 | 27 | +| | [@elastic/obs-ai-assistant](https://github.com/orgs/elastic/teams/obs-ai-assistant) | - | 296 | 1 | 294 | 28 | | | [@elastic/obs-ai-assistant](https://github.com/orgs/elastic/teams/obs-ai-assistant) | - | 4 | 0 | 4 | 0 | | | [@elastic/obs-ai-assistant](https://github.com/orgs/elastic/teams/obs-ai-assistant) | - | 2 | 0 | 2 | 0 | | | [@elastic/obs-ux-logs-team](https://github.com/orgs/elastic/teams/obs-ux-logs-team) | This plugin exposes and registers observability log consumption features. | 19 | 0 | 19 | 1 | @@ -191,7 +191,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/search-kibana](https://github.com/orgs/elastic/teams/search-kibana) | - | 22 | 0 | 16 | 1 | | searchprofiler | [@elastic/kibana-management](https://github.com/orgs/elastic/teams/kibana-management) | - | 0 | 0 | 0 | 0 | | | [@elastic/kibana-security](https://github.com/orgs/elastic/teams/kibana-security) | This plugin provides authentication and authorization features, and exposes functionality to understand the capabilities of the currently authenticated user. | 455 | 0 | 238 | 0 | -| | [@elastic/security-solution](https://github.com/orgs/elastic/teams/security-solution) | - | 187 | 0 | 119 | 33 | +| | [@elastic/security-solution](https://github.com/orgs/elastic/teams/security-solution) | - | 191 | 0 | 123 | 34 | | | [@elastic/security-solution](https://github.com/orgs/elastic/teams/security-solution) | ESS customizations for Security Solution. | 6 | 0 | 6 | 0 | | | [@elastic/security-solution](https://github.com/orgs/elastic/teams/security-solution) | Serverless customizations for security. | 7 | 0 | 7 | 0 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | The core Serverless plugin, providing APIs to Serverless Project plugins. | 25 | 0 | 24 | 0 | @@ -199,7 +199,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/search-kibana](https://github.com/orgs/elastic/teams/search-kibana) | Serverless customizations for search. | 7 | 0 | 7 | 0 | | | [@elastic/kibana-cloud-security-posture](https://github.com/orgs/elastic/teams/kibana-cloud-security-posture) | - | 134 | 0 | 134 | 8 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | Adds URL Service and sharing capabilities to Kibana | 136 | 0 | 73 | 15 | -| | [@elastic/obs-ux-management-team](https://github.com/orgs/elastic/teams/obs-ux-management-team) | - | 47 | 0 | 47 | 4 | +| | [@elastic/obs-ux-management-team](https://github.com/orgs/elastic/teams/obs-ux-management-team) | - | 47 | 0 | 47 | 2 | | | [@elastic/kibana-management](https://github.com/orgs/elastic/teams/kibana-management) | - | 22 | 1 | 22 | 1 | | | [@elastic/kibana-security](https://github.com/orgs/elastic/teams/kibana-security) | This plugin provides the Spaces feature, which allows saved objects to be organized into meaningful categories. | 269 | 0 | 73 | 1 | | | [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-ops) | - | 25 | 0 | 25 | 3 | @@ -251,7 +251,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-ops) | - | 14 | 0 | 14 | 0 | | | [@elastic/search-kibana](https://github.com/orgs/elastic/teams/search-kibana) | - | 64 | 0 | 64 | 1 | | | [@elastic/search-kibana](https://github.com/orgs/elastic/teams/search-kibana) | - | 3 | 0 | 3 | 0 | -| | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | - | 36 | 0 | 0 | 0 | +| | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | - | 37 | 0 | 0 | 0 | | | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | - | 2 | 0 | 0 | 0 | | | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | - | 66 | 0 | 0 | 0 | | | [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-ops) | - | 27 | 3 | 27 | 0 | @@ -283,8 +283,8 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 3 | 0 | 3 | 0 | | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 62 | 0 | 17 | 1 | | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 2 | 0 | 2 | 0 | -| | [@elastic/kibana-cloud-security-posture](https://github.com/orgs/elastic/teams/kibana-cloud-security-posture) | - | 89 | 1 | 89 | 0 | -| | [@elastic/kibana-cloud-security-posture](https://github.com/orgs/elastic/teams/kibana-cloud-security-posture) | - | 109 | 0 | 107 | 1 | +| | [@elastic/kibana-cloud-security-posture](https://github.com/orgs/elastic/teams/kibana-cloud-security-posture) | - | 93 | 1 | 93 | 0 | +| | [@elastic/kibana-cloud-security-posture](https://github.com/orgs/elastic/teams/kibana-cloud-security-posture) | - | 122 | 0 | 120 | 1 | | | [@elastic/kibana-cloud-security-posture](https://github.com/orgs/elastic/teams/kibana-cloud-security-posture) | - | 20 | 0 | 15 | 4 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 41 | 0 | 17 | 0 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 2 | 0 | 2 | 0 | @@ -521,7 +521,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/obs-ux-logs-team](https://github.com/orgs/elastic/teams/obs-ux-logs-team) | - | 42 | 0 | 41 | 0 | | | [@elastic/security-generative-ai](https://github.com/orgs/elastic/teams/security-generative-ai) | - | 170 | 0 | 141 | 10 | | | [@elastic/security-generative-ai](https://github.com/orgs/elastic/teams/security-generative-ai) | - | 442 | 0 | 405 | 0 | -| | [@elastic/obs-entities](https://github.com/orgs/elastic/teams/obs-entities) | - | 50 | 0 | 50 | 0 | +| | [@elastic/obs-entities](https://github.com/orgs/elastic/teams/obs-entities) | - | 51 | 0 | 51 | 0 | | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 55 | 0 | 40 | 7 | | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 32 | 0 | 19 | 1 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 11 | 0 | 6 | 0 | @@ -630,7 +630,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/obs-ux-management-team](https://github.com/orgs/elastic/teams/obs-ux-management-team) | - | 5 | 0 | 5 | 0 | | | [@elastic/obs-ux-management-team](https://github.com/orgs/elastic/teams/obs-ux-management-team) | - | 99 | 1 | 99 | 0 | | | [@elastic/obs-ux-management-team](https://github.com/orgs/elastic/teams/obs-ux-management-team) | - | 6 | 0 | 6 | 1 | -| | [@elastic/obs-ux-logs-team](https://github.com/orgs/elastic/teams/obs-ux-logs-team) | - | 29 | 0 | 27 | 4 | +| | [@elastic/obs-ux-logs-team](https://github.com/orgs/elastic/teams/obs-ux-logs-team) | - | 29 | 0 | 27 | 5 | | | [@elastic/obs-ux-management-team](https://github.com/orgs/elastic/teams/obs-ux-management-team) | - | 4 | 0 | 4 | 1 | | | [@elastic/security-detection-rule-management](https://github.com/orgs/elastic/teams/security-detection-rule-management) | - | 12 | 0 | 12 | 0 | | | [@elastic/security-detection-rule-management](https://github.com/orgs/elastic/teams/security-detection-rule-management) | - | 15 | 0 | 15 | 0 | @@ -643,7 +643,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@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/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | - | 92 | 0 | 80 | 0 | -| | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | - | 228 | 0 | 192 | 6 | +| | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | - | 229 | 0 | 193 | 6 | | | [@elastic/appex-ai-infra](https://github.com/orgs/elastic/teams/appex-ai-infra) | - | 1 | 0 | 1 | 0 | | | [@elastic/appex-ai-infra](https://github.com/orgs/elastic/teams/appex-ai-infra) | - | 31 | 0 | 31 | 0 | | | [@elastic/obs-ux-infra_services-team](https://github.com/orgs/elastic/teams/obs-ux-infra_services-team) | - | 168 | 0 | 55 | 0 | @@ -682,12 +682,13 @@ 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) | - | 138 | 0 | 135 | 0 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 2 | 0 | 2 | 0 | -| | [@elastic/appex-qa](https://github.com/orgs/elastic/teams/appex-qa) | - | 34 | 0 | 26 | 5 | +| | [@elastic/obs-ux-logs-team](https://github.com/orgs/elastic/teams/obs-ux-logs-team) | - | 15 | 0 | 14 | 0 | +| | [@elastic/appex-qa](https://github.com/orgs/elastic/teams/appex-qa) | - | 119 | 0 | 86 | 8 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 35 | 0 | 34 | 0 | | | [@elastic/search-kibana](https://github.com/orgs/elastic/teams/search-kibana) | - | 8 | 0 | 8 | 1 | | | [@elastic/search-kibana](https://github.com/orgs/elastic/teams/search-kibana) | - | 3 | 0 | 3 | 0 | | | [@elastic/search-kibana](https://github.com/orgs/elastic/teams/search-kibana) | - | 76 | 0 | 76 | 0 | -| | [@elastic/search-kibana](https://github.com/orgs/elastic/teams/search-kibana) | - | 3948 | 0 | 3948 | 0 | +| | [@elastic/search-kibana](https://github.com/orgs/elastic/teams/search-kibana) | - | 3954 | 0 | 3954 | 0 | | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | - | 18 | 1 | 17 | 1 | | | [@elastic/search-kibana](https://github.com/orgs/elastic/teams/search-kibana) | - | 36 | 0 | 34 | 3 | | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | - | 20 | 0 | 18 | 1 | @@ -802,7 +803,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 42 | 0 | 28 | 0 | | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 61 | 0 | 52 | 0 | | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 9 | 0 | 8 | 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 | 184 | 0 | 108 | 1 | +| | [@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 | 186 | 0 | 109 | 1 | | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | - | 18 | 0 | 17 | 5 | | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | Contains functionality for the field list and field stats which can be integrated into apps | 317 | 0 | 288 | 8 | | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | - | 13 | 0 | 9 | 0 | diff --git a/api_docs/presentation_panel.mdx b/api_docs/presentation_panel.mdx index 882add710e8ad..ba7ad19e35c1a 100644 --- a/api_docs/presentation_panel.mdx +++ b/api_docs/presentation_panel.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/presentationPanel title: "presentationPanel" image: https://source.unsplash.com/400x175/?github description: API docs for the presentationPanel plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'presentationPanel'] --- import presentationPanelObj from './presentation_panel.devdocs.json'; diff --git a/api_docs/presentation_util.mdx b/api_docs/presentation_util.mdx index 0ef6cbff858b8..608ee8ec6052a 100644 --- a/api_docs/presentation_util.mdx +++ b/api_docs/presentation_util.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/presentationUtil title: "presentationUtil" image: https://source.unsplash.com/400x175/?github description: API docs for the presentationUtil plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'presentationUtil'] --- import presentationUtilObj from './presentation_util.devdocs.json'; diff --git a/api_docs/product_doc_base.mdx b/api_docs/product_doc_base.mdx index 3e7df57ef6bfc..b4d5a3abd7bbd 100644 --- a/api_docs/product_doc_base.mdx +++ b/api_docs/product_doc_base.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/productDocBase title: "productDocBase" image: https://source.unsplash.com/400x175/?github description: API docs for the productDocBase plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'productDocBase'] --- import productDocBaseObj from './product_doc_base.devdocs.json'; diff --git a/api_docs/profiling.mdx b/api_docs/profiling.mdx index 166e13a70b590..e483cfd96c659 100644 --- a/api_docs/profiling.mdx +++ b/api_docs/profiling.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/profiling title: "profiling" image: https://source.unsplash.com/400x175/?github description: API docs for the profiling plugin -date: 2024-11-29 +date: 2024-12-03 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 50e70505b1a44..acc71b8508e7f 100644 --- a/api_docs/profiling_data_access.mdx +++ b/api_docs/profiling_data_access.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/profilingDataAccess title: "profilingDataAccess" image: https://source.unsplash.com/400x175/?github description: API docs for the profilingDataAccess plugin -date: 2024-11-29 +date: 2024-12-03 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 71188941a22bf..0c8f1c61f827d 100644 --- a/api_docs/remote_clusters.mdx +++ b/api_docs/remote_clusters.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/remoteClusters title: "remoteClusters" image: https://source.unsplash.com/400x175/?github description: API docs for the remoteClusters plugin -date: 2024-11-29 +date: 2024-12-03 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 b08e763e0d44e..35957e03e59f3 100644 --- a/api_docs/reporting.mdx +++ b/api_docs/reporting.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/reporting title: "reporting" image: https://source.unsplash.com/400x175/?github description: API docs for the reporting plugin -date: 2024-11-29 +date: 2024-12-03 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 73c4962eaeff8..774258153466e 100644 --- a/api_docs/rollup.mdx +++ b/api_docs/rollup.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/rollup title: "rollup" image: https://source.unsplash.com/400x175/?github description: API docs for the rollup plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'rollup'] --- import rollupObj from './rollup.devdocs.json'; diff --git a/api_docs/rule_registry.mdx b/api_docs/rule_registry.mdx index 642f6711c2b70..a2312f45d5df3 100644 --- a/api_docs/rule_registry.mdx +++ b/api_docs/rule_registry.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ruleRegistry title: "ruleRegistry" image: https://source.unsplash.com/400x175/?github description: API docs for the ruleRegistry plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ruleRegistry'] --- import ruleRegistryObj from './rule_registry.devdocs.json'; diff --git a/api_docs/runtime_fields.mdx b/api_docs/runtime_fields.mdx index cc40c729a1604..4e8cb4f0a32f2 100644 --- a/api_docs/runtime_fields.mdx +++ b/api_docs/runtime_fields.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/runtimeFields title: "runtimeFields" image: https://source.unsplash.com/400x175/?github description: API docs for the runtimeFields plugin -date: 2024-11-29 +date: 2024-12-03 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 84962348849ec..bb90830dba62f 100644 --- a/api_docs/saved_objects.mdx +++ b/api_docs/saved_objects.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjects title: "savedObjects" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjects plugin -date: 2024-11-29 +date: 2024-12-03 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 e032a6982edd2..0d9cdee95f93a 100644 --- a/api_docs/saved_objects_finder.mdx +++ b/api_docs/saved_objects_finder.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsFinder title: "savedObjectsFinder" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsFinder plugin -date: 2024-11-29 +date: 2024-12-03 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 ad297f87a92d2..15bd21d5b6d18 100644 --- a/api_docs/saved_objects_management.mdx +++ b/api_docs/saved_objects_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsManagement title: "savedObjectsManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsManagement plugin -date: 2024-11-29 +date: 2024-12-03 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 47d7887ad3193..ec1638958e02a 100644 --- a/api_docs/saved_objects_tagging.mdx +++ b/api_docs/saved_objects_tagging.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsTagging title: "savedObjectsTagging" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsTagging plugin -date: 2024-11-29 +date: 2024-12-03 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 d38aebf634489..a613566c60776 100644 --- a/api_docs/saved_objects_tagging_oss.mdx +++ b/api_docs/saved_objects_tagging_oss.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsTaggingOss title: "savedObjectsTaggingOss" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsTaggingOss plugin -date: 2024-11-29 +date: 2024-12-03 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 4978f452e351e..56a59050b9058 100644 --- a/api_docs/saved_search.mdx +++ b/api_docs/saved_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedSearch title: "savedSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the savedSearch plugin -date: 2024-11-29 +date: 2024-12-03 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 b2b5d18e578ef..0086b8cb10a91 100644 --- a/api_docs/screenshot_mode.mdx +++ b/api_docs/screenshot_mode.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/screenshotMode title: "screenshotMode" image: https://source.unsplash.com/400x175/?github description: API docs for the screenshotMode plugin -date: 2024-11-29 +date: 2024-12-03 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 9d2c3b5d52c09..c06d70c38dd90 100644 --- a/api_docs/screenshotting.mdx +++ b/api_docs/screenshotting.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/screenshotting title: "screenshotting" image: https://source.unsplash.com/400x175/?github description: API docs for the screenshotting plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'screenshotting'] --- import screenshottingObj from './screenshotting.devdocs.json'; diff --git a/api_docs/search_assistant.mdx b/api_docs/search_assistant.mdx index e67a589774652..30858fc27f43b 100644 --- a/api_docs/search_assistant.mdx +++ b/api_docs/search_assistant.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/searchAssistant title: "searchAssistant" image: https://source.unsplash.com/400x175/?github description: API docs for the searchAssistant plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'searchAssistant'] --- import searchAssistantObj from './search_assistant.devdocs.json'; diff --git a/api_docs/search_connectors.mdx b/api_docs/search_connectors.mdx index cd5ace0afd6ac..72f4f46714b77 100644 --- a/api_docs/search_connectors.mdx +++ b/api_docs/search_connectors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/searchConnectors title: "searchConnectors" image: https://source.unsplash.com/400x175/?github description: API docs for the searchConnectors plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'searchConnectors'] --- import searchConnectorsObj from './search_connectors.devdocs.json'; diff --git a/api_docs/search_homepage.mdx b/api_docs/search_homepage.mdx index b8e6366e175dd..c90944ba62182 100644 --- a/api_docs/search_homepage.mdx +++ b/api_docs/search_homepage.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/searchHomepage title: "searchHomepage" image: https://source.unsplash.com/400x175/?github description: API docs for the searchHomepage plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'searchHomepage'] --- import searchHomepageObj from './search_homepage.devdocs.json'; diff --git a/api_docs/search_indices.mdx b/api_docs/search_indices.mdx index 686cb92be2243..fd27a066f0051 100644 --- a/api_docs/search_indices.mdx +++ b/api_docs/search_indices.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/searchIndices title: "searchIndices" image: https://source.unsplash.com/400x175/?github description: API docs for the searchIndices plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'searchIndices'] --- import searchIndicesObj from './search_indices.devdocs.json'; diff --git a/api_docs/search_inference_endpoints.mdx b/api_docs/search_inference_endpoints.mdx index 2e42872e131f9..56b3db801e11a 100644 --- a/api_docs/search_inference_endpoints.mdx +++ b/api_docs/search_inference_endpoints.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/searchInferenceEndpoints title: "searchInferenceEndpoints" image: https://source.unsplash.com/400x175/?github description: API docs for the searchInferenceEndpoints plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'searchInferenceEndpoints'] --- import searchInferenceEndpointsObj from './search_inference_endpoints.devdocs.json'; diff --git a/api_docs/search_navigation.mdx b/api_docs/search_navigation.mdx index 8993d0365df1d..13ec3c71cb616 100644 --- a/api_docs/search_navigation.mdx +++ b/api_docs/search_navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/searchNavigation title: "searchNavigation" image: https://source.unsplash.com/400x175/?github description: API docs for the searchNavigation plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'searchNavigation'] --- import searchNavigationObj from './search_navigation.devdocs.json'; diff --git a/api_docs/search_notebooks.mdx b/api_docs/search_notebooks.mdx index 5ddec569c71c8..87e79557b6d02 100644 --- a/api_docs/search_notebooks.mdx +++ b/api_docs/search_notebooks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/searchNotebooks title: "searchNotebooks" image: https://source.unsplash.com/400x175/?github description: API docs for the searchNotebooks plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'searchNotebooks'] --- import searchNotebooksObj from './search_notebooks.devdocs.json'; diff --git a/api_docs/search_playground.mdx b/api_docs/search_playground.mdx index ec2159d180851..25725925c071e 100644 --- a/api_docs/search_playground.mdx +++ b/api_docs/search_playground.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/searchPlayground title: "searchPlayground" image: https://source.unsplash.com/400x175/?github description: API docs for the searchPlayground plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'searchPlayground'] --- import searchPlaygroundObj from './search_playground.devdocs.json'; diff --git a/api_docs/security.mdx b/api_docs/security.mdx index b20c500c1165d..202af84020403 100644 --- a/api_docs/security.mdx +++ b/api_docs/security.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/security title: "security" image: https://source.unsplash.com/400x175/?github description: API docs for the security plugin -date: 2024-11-29 +date: 2024-12-03 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 f537e0449301d..8320b9f633933 100644 --- a/api_docs/security_solution.devdocs.json +++ b/api_docs/security_solution.devdocs.json @@ -266,6 +266,108 @@ "trackAdoption": false, "children": [], "returnComment": [] + }, + { + "parentPluginId": "securitySolution", + "id": "def-public.Plugin.registerDiscoverSharedFeatures", + "type": "Function", + "tags": [], + "label": "registerDiscoverSharedFeatures", + "description": [], + "signature": [ + "(core: ", + { + "pluginId": "@kbn/core-lifecycle-browser", + "scope": "public", + "docId": "kibKbnCoreLifecycleBrowserPluginApi", + "section": "def-public.CoreSetup", + "text": "CoreSetup" + }, + "<", + "StartPluginsDependencies", + ", ", + { + "pluginId": "securitySolution", + "scope": "public", + "docId": "kibSecuritySolutionPluginApi", + "section": "def-public.PluginStart", + "text": "PluginStart" + }, + ">, plugins: ", + "SetupPlugins", + ") => Promise" + ], + "path": "x-pack/plugins/security_solution/public/plugin.tsx", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "securitySolution", + "id": "def-public.Plugin.registerDiscoverSharedFeatures.$1", + "type": "Object", + "tags": [], + "label": "core", + "description": [], + "signature": [ + { + "pluginId": "@kbn/core-lifecycle-browser", + "scope": "public", + "docId": "kibKbnCoreLifecycleBrowserPluginApi", + "section": "def-public.CoreSetup", + "text": "CoreSetup" + }, + "<", + "StartPluginsDependencies", + ", ", + { + "pluginId": "securitySolution", + "scope": "public", + "docId": "kibSecuritySolutionPluginApi", + "section": "def-public.PluginStart", + "text": "PluginStart" + }, + ">" + ], + "path": "x-pack/plugins/security_solution/public/plugin.tsx", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "securitySolution", + "id": "def-public.Plugin.registerDiscoverSharedFeatures.$2", + "type": "Object", + "tags": [], + "label": "plugins", + "description": [], + "signature": [ + "SetupPlugins" + ], + "path": "x-pack/plugins/security_solution/public/plugin.tsx", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "securitySolution", + "id": "def-public.Plugin.getLazyDiscoverSharedDeps", + "type": "Function", + "tags": [], + "label": "getLazyDiscoverSharedDeps", + "description": [], + "signature": [ + "() => Promise" + ], + "path": "x-pack/plugins/security_solution/public/plugin.tsx", + "deprecated": false, + "trackAdoption": false, + "children": [], + "returnComment": [] } ], "initialIsOpen": false diff --git a/api_docs/security_solution.mdx b/api_docs/security_solution.mdx index b3fc1652450ee..1568e2234ad23 100644 --- a/api_docs/security_solution.mdx +++ b/api_docs/security_solution.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/securitySolution title: "securitySolution" image: https://source.unsplash.com/400x175/?github description: API docs for the securitySolution plugin -date: 2024-11-29 +date: 2024-12-03 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 | |-------------------|-----------|------------------------|-----------------| -| 187 | 0 | 119 | 33 | +| 191 | 0 | 123 | 34 | ## Client diff --git a/api_docs/security_solution_ess.mdx b/api_docs/security_solution_ess.mdx index c151a747e14ef..37360609c9b10 100644 --- a/api_docs/security_solution_ess.mdx +++ b/api_docs/security_solution_ess.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/securitySolutionEss title: "securitySolutionEss" image: https://source.unsplash.com/400x175/?github description: API docs for the securitySolutionEss plugin -date: 2024-11-29 +date: 2024-12-03 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 3cbf4d3066b7b..21ecd0fdc8eec 100644 --- a/api_docs/security_solution_serverless.mdx +++ b/api_docs/security_solution_serverless.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/securitySolutionServerless title: "securitySolutionServerless" image: https://source.unsplash.com/400x175/?github description: API docs for the securitySolutionServerless plugin -date: 2024-11-29 +date: 2024-12-03 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 272341237cdd7..6d3ac863fa09d 100644 --- a/api_docs/serverless.mdx +++ b/api_docs/serverless.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/serverless title: "serverless" image: https://source.unsplash.com/400x175/?github description: API docs for the serverless plugin -date: 2024-11-29 +date: 2024-12-03 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 dc190bd57433f..868a24e2392bb 100644 --- a/api_docs/serverless_observability.mdx +++ b/api_docs/serverless_observability.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/serverlessObservability title: "serverlessObservability" image: https://source.unsplash.com/400x175/?github description: API docs for the serverlessObservability plugin -date: 2024-11-29 +date: 2024-12-03 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 82fea68d82034..9ff4dc7b3e9e1 100644 --- a/api_docs/serverless_search.mdx +++ b/api_docs/serverless_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/serverlessSearch title: "serverlessSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the serverlessSearch plugin -date: 2024-11-29 +date: 2024-12-03 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 ac85784e5af27..4065f8ed52a9c 100644 --- a/api_docs/session_view.mdx +++ b/api_docs/session_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/sessionView title: "sessionView" image: https://source.unsplash.com/400x175/?github description: API docs for the sessionView plugin -date: 2024-11-29 +date: 2024-12-03 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 d688640eff984..922d5c624d3a0 100644 --- a/api_docs/share.mdx +++ b/api_docs/share.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/share title: "share" image: https://source.unsplash.com/400x175/?github description: API docs for the share plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'share'] --- import shareObj from './share.devdocs.json'; diff --git a/api_docs/slo.devdocs.json b/api_docs/slo.devdocs.json index 0485730fce148..9c7a930086fa6 100644 --- a/api_docs/slo.devdocs.json +++ b/api_docs/slo.devdocs.json @@ -1142,9 +1142,7 @@ "section": "def-common.RecursivePartial", "text": "RecursivePartial" }, - "<", - "CreateSLOForm", - "<{ type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.synthetics.availability\"; params: { monitorIds: { value: string; label: string; }[]; index: string; } & { tags?: { value: string; label: string; }[] | undefined; projects?: { value: string; label: string; }[] | undefined; filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; good: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; }; total: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.metric.custom\"; params: { index: string; good: { metrics: (({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; }; total: { metrics: (({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.metric.timeslice\"; params: { index: string; metric: { metrics: (({ name: string; aggregation: \"min\" | \"max\" | \"sum\" | \"avg\" | \"cardinality\" | \"last_value\" | \"std_deviation\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"percentile\"; field: string; percentile: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; threshold: number; comparator: \"GT\" | \"GTE\" | \"LT\" | \"LTE\"; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.histogram.custom\"; params: { index: string; timestampField: string; good: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }); total: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }); } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; }>> | undefined; }>; }" + "<{ name: string; description: string; indicator: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.synthetics.availability\"; params: { monitorIds: { value: string; label: string; }[]; index: string; } & { tags?: { value: string; label: string; }[] | undefined; projects?: { value: string; label: string; }[] | undefined; filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; good: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; }; total: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.metric.custom\"; params: { index: string; good: { metrics: (({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; }; total: { metrics: (({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.metric.timeslice\"; params: { index: string; metric: { metrics: (({ name: string; aggregation: \"min\" | \"max\" | \"sum\" | \"avg\" | \"cardinality\" | \"last_value\" | \"std_deviation\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"percentile\"; field: string; percentile: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; threshold: number; comparator: \"GT\" | \"GTE\" | \"LT\" | \"LTE\"; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.histogram.custom\"; params: { index: string; timestampField: string; good: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }); total: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }); } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; }; timeWindow: { duration: string; type: \"rolling\"; } | { duration: string; type: \"calendarAligned\"; }; budgetingMethod: \"occurrences\" | \"timeslices\"; objective: { target: number; } & { timesliceTarget?: number | undefined; timesliceWindow?: string | undefined; }; } & { id?: string | undefined; settings?: { syncDelay?: string | undefined; frequency?: string | undefined; preventInitialBackfill?: boolean | undefined; syncField?: string | null | undefined; } | undefined; tags?: string[] | undefined; groupBy?: string | string[] | undefined; revision?: number | undefined; }> | undefined; }>; }" ], "path": "x-pack/plugins/observability_solution/slo/public/types.ts", "deprecated": false, @@ -1179,8 +1177,8 @@ "text": "LocatorPublic" }, "<", - "SloEditLocatorParams", - ">; sloListLocator: ", + "RecursivePartial", + "<{ name: string; description: string; indicator: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.synthetics.availability\"; params: { monitorIds: { value: string; label: string; }[]; index: string; } & { tags?: { value: string; label: string; }[] | undefined; projects?: { value: string; label: string; }[] | undefined; filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; good: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; }; total: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.metric.custom\"; params: { index: string; good: { metrics: (({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; }; total: { metrics: (({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.metric.timeslice\"; params: { index: string; metric: { metrics: (({ name: string; aggregation: \"min\" | \"max\" | \"sum\" | \"avg\" | \"cardinality\" | \"last_value\" | \"std_deviation\"; field: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"doc_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ name: string; aggregation: \"percentile\"; field: string; percentile: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }))[]; equation: string; threshold: number; comparator: \"GT\" | \"GTE\" | \"LT\" | \"LTE\"; }; timestampField: string; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; } | { type: \"sli.histogram.custom\"; params: { index: string; timestampField: string; good: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }); total: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; }); } & { filter?: string | { kqlQuery: string; filters: { meta: { alias?: string | null | undefined; disabled?: boolean | undefined; negate?: boolean | undefined; controlledBy?: string | undefined; group?: string | undefined; index?: string | undefined; isMultiIndex?: boolean | undefined; type?: string | undefined; key?: string | undefined; field?: string | undefined; params?: any; value?: string | undefined; }; query: { [x: string]: any; }; }[]; } | undefined; dataViewId?: string | undefined; }; }; timeWindow: { duration: string; type: \"rolling\"; } | { duration: string; type: \"calendarAligned\"; }; budgetingMethod: \"occurrences\" | \"timeslices\"; objective: { target: number; } & { timesliceTarget?: number | undefined; timesliceWindow?: string | undefined; }; } & { id?: string | undefined; settings?: { syncDelay?: string | undefined; frequency?: string | undefined; preventInitialBackfill?: boolean | undefined; syncField?: string | null | undefined; } | undefined; tags?: string[] | undefined; groupBy?: string | string[] | undefined; revision?: number | undefined; }>>; sloListLocator: ", { "pluginId": "share", "scope": "common", diff --git a/api_docs/slo.mdx b/api_docs/slo.mdx index fa2dece926006..dd266c0213c99 100644 --- a/api_docs/slo.mdx +++ b/api_docs/slo.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/slo title: "slo" image: https://source.unsplash.com/400x175/?github description: API docs for the slo plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'slo'] --- import sloObj from './slo.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/obs-ux-management-team](https://github.com/orgs/elastic/teams/ | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 47 | 0 | 47 | 4 | +| 47 | 0 | 47 | 2 | ## Client diff --git a/api_docs/snapshot_restore.mdx b/api_docs/snapshot_restore.mdx index 2d8a0f0d1c92e..a7b3818f4a82d 100644 --- a/api_docs/snapshot_restore.mdx +++ b/api_docs/snapshot_restore.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/snapshotRestore title: "snapshotRestore" image: https://source.unsplash.com/400x175/?github description: API docs for the snapshotRestore plugin -date: 2024-11-29 +date: 2024-12-03 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 f16c8b426596d..635c21d795899 100644 --- a/api_docs/spaces.mdx +++ b/api_docs/spaces.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/spaces title: "spaces" image: https://source.unsplash.com/400x175/?github description: API docs for the spaces plugin -date: 2024-11-29 +date: 2024-12-03 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 4f02b44d4f92f..c787e7566524d 100644 --- a/api_docs/stack_alerts.mdx +++ b/api_docs/stack_alerts.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/stackAlerts title: "stackAlerts" image: https://source.unsplash.com/400x175/?github description: API docs for the stackAlerts plugin -date: 2024-11-29 +date: 2024-12-03 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 009dde0a2b47e..abd4c2df3a8da 100644 --- a/api_docs/stack_connectors.mdx +++ b/api_docs/stack_connectors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/stackConnectors title: "stackConnectors" image: https://source.unsplash.com/400x175/?github description: API docs for the stackConnectors plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'stackConnectors'] --- import stackConnectorsObj from './stack_connectors.devdocs.json'; diff --git a/api_docs/streams.devdocs.json b/api_docs/streams.devdocs.json index 1d744b0580b2f..bf552dc47d88d 100644 --- a/api_docs/streams.devdocs.json +++ b/api_docs/streams.devdocs.json @@ -107,9 +107,9 @@ "StreamsRouteHandlerResources", ", { definitions: { id: string; children: { id: string; condition?: ", "Condition", - "; }[]; fields: { type: \"boolean\" | \"ip\" | \"keyword\" | \"date\" | \"long\" | \"double\" | \"match_only_text\"; name: string; }[]; processing: { config: { type: \"grok\"; field: string; patterns: string[]; pattern_definitions?: Record | undefined; } | { type: \"dissect\"; field: string; pattern: string; }; condition?: ", + "; }[]; fields: { type: \"boolean\" | \"ip\" | \"keyword\" | \"date\" | \"long\" | \"double\" | \"match_only_text\"; name: string; }[]; managed: boolean; processing: { config: { type: \"grok\"; field: string; patterns: string[]; pattern_definitions?: Record | undefined; } | { type: \"dissect\"; field: string; pattern: string; }; condition?: ", "Condition", - "; }[]; }[]; trees: ", + "; }[]; unmanaged_elasticsearch_assets?: { id: string; type: \"ingest_pipeline\" | \"data_stream\" | \"index_template\" | \"component_template\"; }[] | undefined; }[]; trees: ", "StreamTree", "[]; }, undefined>; \"DELETE /api/streams/{id}\": ", { @@ -175,9 +175,9 @@ "StreamsRouteHandlerResources", ", { id: string; children: { id: string; condition?: ", "Condition", - "; }[]; fields: { type: \"boolean\" | \"ip\" | \"keyword\" | \"date\" | \"long\" | \"double\" | \"match_only_text\"; name: string; }[]; processing: { config: { type: \"grok\"; field: string; patterns: string[]; pattern_definitions?: Record | undefined; } | { type: \"dissect\"; field: string; pattern: string; }; condition?: ", + "; }[]; fields: { type: \"boolean\" | \"ip\" | \"keyword\" | \"date\" | \"long\" | \"double\" | \"match_only_text\"; name: string; }[]; managed: boolean; processing: { config: { type: \"grok\"; field: string; patterns: string[]; pattern_definitions?: Record | undefined; } | { type: \"dissect\"; field: string; pattern: string; }; condition?: ", "Condition", - "; }[]; } & { inheritedFields: ({ type: \"boolean\" | \"ip\" | \"keyword\" | \"date\" | \"long\" | \"double\" | \"match_only_text\"; name: string; } & { from: string; })[]; }, undefined>; \"POST /api/streams/{id}/_fork\": ", + "; }[]; unmanaged_elasticsearch_assets?: { id: string; type: \"ingest_pipeline\" | \"data_stream\" | \"index_template\" | \"component_template\"; }[] | undefined; } & { inheritedFields: ({ type: \"boolean\" | \"ip\" | \"keyword\" | \"date\" | \"long\" | \"double\" | \"match_only_text\"; name: string; } & { from: string; })[]; }, undefined>; \"POST /api/streams/{id}/_fork\": ", { "pluginId": "@kbn/server-route-repository-utils", "scope": "common", @@ -201,29 +201,29 @@ "Condition", "; }, { id: string; condition?: ", "Condition", - "; }>, \"many\">>; }, { id: Zod.ZodString; }>, \"children\">, \"strip\", Zod.ZodTypeAny, { id: string; fields: { type: \"boolean\" | \"ip\" | \"keyword\" | \"date\" | \"long\" | \"double\" | \"match_only_text\"; name: string; }[]; processing: { config: { type: \"grok\"; field: string; patterns: string[]; pattern_definitions?: Record | undefined; } | { type: \"dissect\"; field: string; pattern: string; }; condition?: ", + "; }>, \"many\">>; }, { id: Zod.ZodString; managed: Zod.ZodDefault; unmanaged_elasticsearch_assets: Zod.ZodOptional; id: Zod.ZodString; }, \"strip\", Zod.ZodTypeAny, { id: string; type: \"ingest_pipeline\" | \"data_stream\" | \"index_template\" | \"component_template\"; }, { id: string; type: \"ingest_pipeline\" | \"data_stream\" | \"index_template\" | \"component_template\"; }>, \"many\">>; }>, \"children\">, \"strip\", Zod.ZodTypeAny, { id: string; fields: { type: \"boolean\" | \"ip\" | \"keyword\" | \"date\" | \"long\" | \"double\" | \"match_only_text\"; name: string; }[]; managed: boolean; processing: { config: { type: \"grok\"; field: string; patterns: string[]; pattern_definitions?: Record | undefined; } | { type: \"dissect\"; field: string; pattern: string; }; condition?: ", "Condition", - "; }[]; }, { id: string; fields?: { type: \"boolean\" | \"ip\" | \"keyword\" | \"date\" | \"long\" | \"double\" | \"match_only_text\"; name: string; }[] | undefined; processing?: { config: { type: \"grok\"; field: string; patterns: string[]; pattern_definitions?: Record | undefined; } | { type: \"dissect\"; field: string; pattern: string; }; condition?: ", + "; }[]; unmanaged_elasticsearch_assets?: { id: string; type: \"ingest_pipeline\" | \"data_stream\" | \"index_template\" | \"component_template\"; }[] | undefined; }, { id: string; fields?: { type: \"boolean\" | \"ip\" | \"keyword\" | \"date\" | \"long\" | \"double\" | \"match_only_text\"; name: string; }[] | undefined; managed?: boolean | undefined; processing?: { config: { type: \"grok\"; field: string; patterns: string[]; pattern_definitions?: Record | undefined; } | { type: \"dissect\"; field: string; pattern: string; }; condition?: ", "Condition", - "; }[] | undefined; }>; condition: Zod.ZodType<", + "; }[] | undefined; unmanaged_elasticsearch_assets?: { id: string; type: \"ingest_pipeline\" | \"data_stream\" | \"index_template\" | \"component_template\"; }[] | undefined; }>; condition: Zod.ZodType<", "Condition", ", Zod.ZodTypeDef, ", "Condition", - ">; }, \"strip\", Zod.ZodTypeAny, { stream: { id: string; fields: { type: \"boolean\" | \"ip\" | \"keyword\" | \"date\" | \"long\" | \"double\" | \"match_only_text\"; name: string; }[]; processing: { config: { type: \"grok\"; field: string; patterns: string[]; pattern_definitions?: Record | undefined; } | { type: \"dissect\"; field: string; pattern: string; }; condition?: ", + ">; }, \"strip\", Zod.ZodTypeAny, { stream: { id: string; fields: { type: \"boolean\" | \"ip\" | \"keyword\" | \"date\" | \"long\" | \"double\" | \"match_only_text\"; name: string; }[]; managed: boolean; processing: { config: { type: \"grok\"; field: string; patterns: string[]; pattern_definitions?: Record | undefined; } | { type: \"dissect\"; field: string; pattern: string; }; condition?: ", "Condition", - "; }[]; }; condition?: ", + "; }[]; unmanaged_elasticsearch_assets?: { id: string; type: \"ingest_pipeline\" | \"data_stream\" | \"index_template\" | \"component_template\"; }[] | undefined; }; condition?: ", "Condition", - "; }, { stream: { id: string; fields?: { type: \"boolean\" | \"ip\" | \"keyword\" | \"date\" | \"long\" | \"double\" | \"match_only_text\"; name: string; }[] | undefined; processing?: { config: { type: \"grok\"; field: string; patterns: string[]; pattern_definitions?: Record | undefined; } | { type: \"dissect\"; field: string; pattern: string; }; condition?: ", + "; }, { stream: { id: string; fields?: { type: \"boolean\" | \"ip\" | \"keyword\" | \"date\" | \"long\" | \"double\" | \"match_only_text\"; name: string; }[] | undefined; managed?: boolean | undefined; processing?: { config: { type: \"grok\"; field: string; patterns: string[]; pattern_definitions?: Record | undefined; } | { type: \"dissect\"; field: string; pattern: string; }; condition?: ", "Condition", - "; }[] | undefined; }; condition?: ", + "; }[] | undefined; unmanaged_elasticsearch_assets?: { id: string; type: \"ingest_pipeline\" | \"data_stream\" | \"index_template\" | \"component_template\"; }[] | undefined; }; condition?: ", "Condition", - "; }>; }, \"strip\", Zod.ZodTypeAny, { path: { id: string; }; body: { stream: { id: string; fields: { type: \"boolean\" | \"ip\" | \"keyword\" | \"date\" | \"long\" | \"double\" | \"match_only_text\"; name: string; }[]; processing: { config: { type: \"grok\"; field: string; patterns: string[]; pattern_definitions?: Record | undefined; } | { type: \"dissect\"; field: string; pattern: string; }; condition?: ", + "; }>; }, \"strip\", Zod.ZodTypeAny, { path: { id: string; }; body: { stream: { id: string; fields: { type: \"boolean\" | \"ip\" | \"keyword\" | \"date\" | \"long\" | \"double\" | \"match_only_text\"; name: string; }[]; managed: boolean; processing: { config: { type: \"grok\"; field: string; patterns: string[]; pattern_definitions?: Record | undefined; } | { type: \"dissect\"; field: string; pattern: string; }; condition?: ", "Condition", - "; }[]; }; condition?: ", + "; }[]; unmanaged_elasticsearch_assets?: { id: string; type: \"ingest_pipeline\" | \"data_stream\" | \"index_template\" | \"component_template\"; }[] | undefined; }; condition?: ", "Condition", - "; }; }, { path: { id: string; }; body: { stream: { id: string; fields?: { type: \"boolean\" | \"ip\" | \"keyword\" | \"date\" | \"long\" | \"double\" | \"match_only_text\"; name: string; }[] | undefined; processing?: { config: { type: \"grok\"; field: string; patterns: string[]; pattern_definitions?: Record | undefined; } | { type: \"dissect\"; field: string; pattern: string; }; condition?: ", + "; }; }, { path: { id: string; }; body: { stream: { id: string; fields?: { type: \"boolean\" | \"ip\" | \"keyword\" | \"date\" | \"long\" | \"double\" | \"match_only_text\"; name: string; }[] | undefined; managed?: boolean | undefined; processing?: { config: { type: \"grok\"; field: string; patterns: string[]; pattern_definitions?: Record | undefined; } | { type: \"dissect\"; field: string; pattern: string; }; condition?: ", "Condition", - "; }[] | undefined; }; condition?: ", + "; }[] | undefined; unmanaged_elasticsearch_assets?: { id: string; type: \"ingest_pipeline\" | \"data_stream\" | \"index_template\" | \"component_template\"; }[] | undefined; }; condition?: ", "Condition", "; }; }>, ", "StreamsRouteHandlerResources", @@ -311,9 +311,9 @@ "signature": [ "{ id: string; children: { id: string; condition?: ", "Condition", - "; }[]; fields: { type: \"boolean\" | \"ip\" | \"keyword\" | \"date\" | \"long\" | \"double\" | \"match_only_text\"; name: string; }[]; processing: { config: { type: \"grok\"; field: string; patterns: string[]; pattern_definitions?: Record | undefined; } | { type: \"dissect\"; field: string; pattern: string; }; condition?: ", + "; }[]; fields: { type: \"boolean\" | \"ip\" | \"keyword\" | \"date\" | \"long\" | \"double\" | \"match_only_text\"; name: string; }[]; managed: boolean; processing: { config: { type: \"grok\"; field: string; patterns: string[]; pattern_definitions?: Record | undefined; } | { type: \"dissect\"; field: string; pattern: string; }; condition?: ", "Condition", - "; }[]; }[]" + "; }[]; unmanaged_elasticsearch_assets?: { id: string; type: \"ingest_pipeline\" | \"data_stream\" | \"index_template\" | \"component_template\"; }[] | undefined; }[]" ], "path": "x-pack/plugins/streams/server/lib/streams/stream_crud.ts", "deprecated": false, @@ -392,9 +392,9 @@ "StreamsRouteHandlerResources", ", { definitions: { id: string; children: { id: string; condition?: ", "Condition", - "; }[]; fields: { type: \"boolean\" | \"ip\" | \"keyword\" | \"date\" | \"long\" | \"double\" | \"match_only_text\"; name: string; }[]; processing: { config: { type: \"grok\"; field: string; patterns: string[]; pattern_definitions?: Record | undefined; } | { type: \"dissect\"; field: string; pattern: string; }; condition?: ", + "; }[]; fields: { type: \"boolean\" | \"ip\" | \"keyword\" | \"date\" | \"long\" | \"double\" | \"match_only_text\"; name: string; }[]; managed: boolean; processing: { config: { type: \"grok\"; field: string; patterns: string[]; pattern_definitions?: Record | undefined; } | { type: \"dissect\"; field: string; pattern: string; }; condition?: ", "Condition", - "; }[]; }[]; trees: ", + "; }[]; unmanaged_elasticsearch_assets?: { id: string; type: \"ingest_pipeline\" | \"data_stream\" | \"index_template\" | \"component_template\"; }[] | undefined; }[]; trees: ", "StreamTree", "[]; }, undefined>; \"DELETE /api/streams/{id}\": ", { @@ -460,9 +460,9 @@ "StreamsRouteHandlerResources", ", { id: string; children: { id: string; condition?: ", "Condition", - "; }[]; fields: { type: \"boolean\" | \"ip\" | \"keyword\" | \"date\" | \"long\" | \"double\" | \"match_only_text\"; name: string; }[]; processing: { config: { type: \"grok\"; field: string; patterns: string[]; pattern_definitions?: Record | undefined; } | { type: \"dissect\"; field: string; pattern: string; }; condition?: ", + "; }[]; fields: { type: \"boolean\" | \"ip\" | \"keyword\" | \"date\" | \"long\" | \"double\" | \"match_only_text\"; name: string; }[]; managed: boolean; processing: { config: { type: \"grok\"; field: string; patterns: string[]; pattern_definitions?: Record | undefined; } | { type: \"dissect\"; field: string; pattern: string; }; condition?: ", "Condition", - "; }[]; } & { inheritedFields: ({ type: \"boolean\" | \"ip\" | \"keyword\" | \"date\" | \"long\" | \"double\" | \"match_only_text\"; name: string; } & { from: string; })[]; }, undefined>; \"POST /api/streams/{id}/_fork\": ", + "; }[]; unmanaged_elasticsearch_assets?: { id: string; type: \"ingest_pipeline\" | \"data_stream\" | \"index_template\" | \"component_template\"; }[] | undefined; } & { inheritedFields: ({ type: \"boolean\" | \"ip\" | \"keyword\" | \"date\" | \"long\" | \"double\" | \"match_only_text\"; name: string; } & { from: string; })[]; }, undefined>; \"POST /api/streams/{id}/_fork\": ", { "pluginId": "@kbn/server-route-repository-utils", "scope": "common", @@ -486,29 +486,29 @@ "Condition", "; }, { id: string; condition?: ", "Condition", - "; }>, \"many\">>; }, { id: Zod.ZodString; }>, \"children\">, \"strip\", Zod.ZodTypeAny, { id: string; fields: { type: \"boolean\" | \"ip\" | \"keyword\" | \"date\" | \"long\" | \"double\" | \"match_only_text\"; name: string; }[]; processing: { config: { type: \"grok\"; field: string; patterns: string[]; pattern_definitions?: Record | undefined; } | { type: \"dissect\"; field: string; pattern: string; }; condition?: ", + "; }>, \"many\">>; }, { id: Zod.ZodString; managed: Zod.ZodDefault; unmanaged_elasticsearch_assets: Zod.ZodOptional; id: Zod.ZodString; }, \"strip\", Zod.ZodTypeAny, { id: string; type: \"ingest_pipeline\" | \"data_stream\" | \"index_template\" | \"component_template\"; }, { id: string; type: \"ingest_pipeline\" | \"data_stream\" | \"index_template\" | \"component_template\"; }>, \"many\">>; }>, \"children\">, \"strip\", Zod.ZodTypeAny, { id: string; fields: { type: \"boolean\" | \"ip\" | \"keyword\" | \"date\" | \"long\" | \"double\" | \"match_only_text\"; name: string; }[]; managed: boolean; processing: { config: { type: \"grok\"; field: string; patterns: string[]; pattern_definitions?: Record | undefined; } | { type: \"dissect\"; field: string; pattern: string; }; condition?: ", "Condition", - "; }[]; }, { id: string; fields?: { type: \"boolean\" | \"ip\" | \"keyword\" | \"date\" | \"long\" | \"double\" | \"match_only_text\"; name: string; }[] | undefined; processing?: { config: { type: \"grok\"; field: string; patterns: string[]; pattern_definitions?: Record | undefined; } | { type: \"dissect\"; field: string; pattern: string; }; condition?: ", + "; }[]; unmanaged_elasticsearch_assets?: { id: string; type: \"ingest_pipeline\" | \"data_stream\" | \"index_template\" | \"component_template\"; }[] | undefined; }, { id: string; fields?: { type: \"boolean\" | \"ip\" | \"keyword\" | \"date\" | \"long\" | \"double\" | \"match_only_text\"; name: string; }[] | undefined; managed?: boolean | undefined; processing?: { config: { type: \"grok\"; field: string; patterns: string[]; pattern_definitions?: Record | undefined; } | { type: \"dissect\"; field: string; pattern: string; }; condition?: ", "Condition", - "; }[] | undefined; }>; condition: Zod.ZodType<", + "; }[] | undefined; unmanaged_elasticsearch_assets?: { id: string; type: \"ingest_pipeline\" | \"data_stream\" | \"index_template\" | \"component_template\"; }[] | undefined; }>; condition: Zod.ZodType<", "Condition", ", Zod.ZodTypeDef, ", "Condition", - ">; }, \"strip\", Zod.ZodTypeAny, { stream: { id: string; fields: { type: \"boolean\" | \"ip\" | \"keyword\" | \"date\" | \"long\" | \"double\" | \"match_only_text\"; name: string; }[]; processing: { config: { type: \"grok\"; field: string; patterns: string[]; pattern_definitions?: Record | undefined; } | { type: \"dissect\"; field: string; pattern: string; }; condition?: ", + ">; }, \"strip\", Zod.ZodTypeAny, { stream: { id: string; fields: { type: \"boolean\" | \"ip\" | \"keyword\" | \"date\" | \"long\" | \"double\" | \"match_only_text\"; name: string; }[]; managed: boolean; processing: { config: { type: \"grok\"; field: string; patterns: string[]; pattern_definitions?: Record | undefined; } | { type: \"dissect\"; field: string; pattern: string; }; condition?: ", "Condition", - "; }[]; }; condition?: ", + "; }[]; unmanaged_elasticsearch_assets?: { id: string; type: \"ingest_pipeline\" | \"data_stream\" | \"index_template\" | \"component_template\"; }[] | undefined; }; condition?: ", "Condition", - "; }, { stream: { id: string; fields?: { type: \"boolean\" | \"ip\" | \"keyword\" | \"date\" | \"long\" | \"double\" | \"match_only_text\"; name: string; }[] | undefined; processing?: { config: { type: \"grok\"; field: string; patterns: string[]; pattern_definitions?: Record | undefined; } | { type: \"dissect\"; field: string; pattern: string; }; condition?: ", + "; }, { stream: { id: string; fields?: { type: \"boolean\" | \"ip\" | \"keyword\" | \"date\" | \"long\" | \"double\" | \"match_only_text\"; name: string; }[] | undefined; managed?: boolean | undefined; processing?: { config: { type: \"grok\"; field: string; patterns: string[]; pattern_definitions?: Record | undefined; } | { type: \"dissect\"; field: string; pattern: string; }; condition?: ", "Condition", - "; }[] | undefined; }; condition?: ", + "; }[] | undefined; unmanaged_elasticsearch_assets?: { id: string; type: \"ingest_pipeline\" | \"data_stream\" | \"index_template\" | \"component_template\"; }[] | undefined; }; condition?: ", "Condition", - "; }>; }, \"strip\", Zod.ZodTypeAny, { path: { id: string; }; body: { stream: { id: string; fields: { type: \"boolean\" | \"ip\" | \"keyword\" | \"date\" | \"long\" | \"double\" | \"match_only_text\"; name: string; }[]; processing: { config: { type: \"grok\"; field: string; patterns: string[]; pattern_definitions?: Record | undefined; } | { type: \"dissect\"; field: string; pattern: string; }; condition?: ", + "; }>; }, \"strip\", Zod.ZodTypeAny, { path: { id: string; }; body: { stream: { id: string; fields: { type: \"boolean\" | \"ip\" | \"keyword\" | \"date\" | \"long\" | \"double\" | \"match_only_text\"; name: string; }[]; managed: boolean; processing: { config: { type: \"grok\"; field: string; patterns: string[]; pattern_definitions?: Record | undefined; } | { type: \"dissect\"; field: string; pattern: string; }; condition?: ", "Condition", - "; }[]; }; condition?: ", + "; }[]; unmanaged_elasticsearch_assets?: { id: string; type: \"ingest_pipeline\" | \"data_stream\" | \"index_template\" | \"component_template\"; }[] | undefined; }; condition?: ", "Condition", - "; }; }, { path: { id: string; }; body: { stream: { id: string; fields?: { type: \"boolean\" | \"ip\" | \"keyword\" | \"date\" | \"long\" | \"double\" | \"match_only_text\"; name: string; }[] | undefined; processing?: { config: { type: \"grok\"; field: string; patterns: string[]; pattern_definitions?: Record | undefined; } | { type: \"dissect\"; field: string; pattern: string; }; condition?: ", + "; }; }, { path: { id: string; }; body: { stream: { id: string; fields?: { type: \"boolean\" | \"ip\" | \"keyword\" | \"date\" | \"long\" | \"double\" | \"match_only_text\"; name: string; }[] | undefined; managed?: boolean | undefined; processing?: { config: { type: \"grok\"; field: string; patterns: string[]; pattern_definitions?: Record | undefined; } | { type: \"dissect\"; field: string; pattern: string; }; condition?: ", "Condition", - "; }[] | undefined; }; condition?: ", + "; }[] | undefined; unmanaged_elasticsearch_assets?: { id: string; type: \"ingest_pipeline\" | \"data_stream\" | \"index_template\" | \"component_template\"; }[] | undefined; }; condition?: ", "Condition", "; }; }>, ", "StreamsRouteHandlerResources", @@ -586,9 +586,9 @@ "signature": [ "{ id: string; children: { id: string; condition?: ", "Condition", - "; }[]; fields: { type: \"boolean\" | \"ip\" | \"keyword\" | \"date\" | \"long\" | \"double\" | \"match_only_text\"; name: string; }[]; processing: { config: { type: \"grok\"; field: string; patterns: string[]; pattern_definitions?: Record | undefined; } | { type: \"dissect\"; field: string; pattern: string; }; condition?: ", + "; }[]; fields: { type: \"boolean\" | \"ip\" | \"keyword\" | \"date\" | \"long\" | \"double\" | \"match_only_text\"; name: string; }[]; managed: boolean; processing: { config: { type: \"grok\"; field: string; patterns: string[]; pattern_definitions?: Record | undefined; } | { type: \"dissect\"; field: string; pattern: string; }; condition?: ", "Condition", - "; }[]; }" + "; }[]; unmanaged_elasticsearch_assets?: { id: string; type: \"ingest_pipeline\" | \"data_stream\" | \"index_template\" | \"component_template\"; }[] | undefined; }" ], "path": "x-pack/plugins/streams/common/types.ts", "deprecated": false, diff --git a/api_docs/streams.mdx b/api_docs/streams.mdx index 56884c0a4ebc6..9c4865f7f286f 100644 --- a/api_docs/streams.mdx +++ b/api_docs/streams.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/streams title: "streams" image: https://source.unsplash.com/400x175/?github description: API docs for the streams plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'streams'] --- import streamsObj from './streams.devdocs.json'; diff --git a/api_docs/streams_app.devdocs.json b/api_docs/streams_app.devdocs.json index 2bb7bd48fb0cb..12a4d9b1b7d5a 100644 --- a/api_docs/streams_app.devdocs.json +++ b/api_docs/streams_app.devdocs.json @@ -114,9 +114,9 @@ "signature": [ "EntityBase & { type: \"stream\"; properties: { id: string; children: { id: string; condition?: ", "Condition", - "; }[]; fields: { type: \"boolean\" | \"ip\" | \"keyword\" | \"date\" | \"long\" | \"double\" | \"match_only_text\"; name: string; }[]; processing: { config: { type: \"grok\"; field: string; patterns: string[]; pattern_definitions?: Record | undefined; } | { type: \"dissect\"; field: string; pattern: string; }; condition?: ", + "; }[]; fields: { type: \"boolean\" | \"ip\" | \"keyword\" | \"date\" | \"long\" | \"double\" | \"match_only_text\"; name: string; }[]; managed: boolean; processing: { config: { type: \"grok\"; field: string; patterns: string[]; pattern_definitions?: Record | undefined; } | { type: \"dissect\"; field: string; pattern: string; }; condition?: ", "Condition", - "; }[]; }; }" + "; }[]; unmanaged_elasticsearch_assets?: { id: string; type: \"ingest_pipeline\" | \"data_stream\" | \"index_template\" | \"component_template\"; }[] | undefined; }; }" ], "path": "x-pack/plugins/streams_app/common/index.ts", "deprecated": false, @@ -133,9 +133,9 @@ "signature": [ "EntityBase & { type: \"stream\"; properties: { id: string; children: { id: string; condition?: ", "Condition", - "; }[]; fields: { type: \"boolean\" | \"ip\" | \"keyword\" | \"date\" | \"long\" | \"double\" | \"match_only_text\"; name: string; }[]; processing: { config: { type: \"grok\"; field: string; patterns: string[]; pattern_definitions?: Record | undefined; } | { type: \"dissect\"; field: string; pattern: string; }; condition?: ", + "; }[]; fields: { type: \"boolean\" | \"ip\" | \"keyword\" | \"date\" | \"long\" | \"double\" | \"match_only_text\"; name: string; }[]; managed: boolean; processing: { config: { type: \"grok\"; field: string; patterns: string[]; pattern_definitions?: Record | undefined; } | { type: \"dissect\"; field: string; pattern: string; }; condition?: ", "Condition", - "; }[]; }; }" + "; }[]; unmanaged_elasticsearch_assets?: { id: string; type: \"ingest_pipeline\" | \"data_stream\" | \"index_template\" | \"component_template\"; }[] | undefined; }; }" ], "path": "x-pack/plugins/streams_app/common/index.ts", "deprecated": false, diff --git a/api_docs/streams_app.mdx b/api_docs/streams_app.mdx index 8cd9607e67b46..629a0ca065115 100644 --- a/api_docs/streams_app.mdx +++ b/api_docs/streams_app.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/streamsApp title: "streamsApp" image: https://source.unsplash.com/400x175/?github description: API docs for the streamsApp plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'streamsApp'] --- import streamsAppObj from './streams_app.devdocs.json'; diff --git a/api_docs/task_manager.mdx b/api_docs/task_manager.mdx index 235a55f749823..3a338e11eac2a 100644 --- a/api_docs/task_manager.mdx +++ b/api_docs/task_manager.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/taskManager title: "taskManager" image: https://source.unsplash.com/400x175/?github description: API docs for the taskManager plugin -date: 2024-11-29 +date: 2024-12-03 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 f0d1244c7a7e1..ed12ad96ade80 100644 --- a/api_docs/telemetry.mdx +++ b/api_docs/telemetry.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetry title: "telemetry" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetry plugin -date: 2024-11-29 +date: 2024-12-03 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 6be2b6ea70835..ade6bf4aa32f0 100644 --- a/api_docs/telemetry_collection_manager.mdx +++ b/api_docs/telemetry_collection_manager.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryCollectionManager title: "telemetryCollectionManager" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryCollectionManager plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryCollectionManager'] --- import telemetryCollectionManagerObj from './telemetry_collection_manager.devdocs.json'; diff --git a/api_docs/telemetry_management_section.mdx b/api_docs/telemetry_management_section.mdx index 405166c18b4e7..cb5728a3d59f2 100644 --- a/api_docs/telemetry_management_section.mdx +++ b/api_docs/telemetry_management_section.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryManagementSection title: "telemetryManagementSection" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryManagementSection plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryManagementSection'] --- import telemetryManagementSectionObj from './telemetry_management_section.devdocs.json'; diff --git a/api_docs/threat_intelligence.mdx b/api_docs/threat_intelligence.mdx index 9c1fb4f0a8f05..3a2034cece75a 100644 --- a/api_docs/threat_intelligence.mdx +++ b/api_docs/threat_intelligence.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/threatIntelligence title: "threatIntelligence" image: https://source.unsplash.com/400x175/?github description: API docs for the threatIntelligence plugin -date: 2024-11-29 +date: 2024-12-03 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 47dc47ee41c77..8b41d13110bf2 100644 --- a/api_docs/timelines.mdx +++ b/api_docs/timelines.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/timelines title: "timelines" image: https://source.unsplash.com/400x175/?github description: API docs for the timelines plugin -date: 2024-11-29 +date: 2024-12-03 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 c0f9e71e24bc3..fe7f7d34d99c8 100644 --- a/api_docs/transform.mdx +++ b/api_docs/transform.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/transform title: "transform" image: https://source.unsplash.com/400x175/?github description: API docs for the transform plugin -date: 2024-11-29 +date: 2024-12-03 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 89baf2aad16c6..9585065993bd3 100644 --- a/api_docs/triggers_actions_ui.mdx +++ b/api_docs/triggers_actions_ui.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/triggersActionsUi title: "triggersActionsUi" image: https://source.unsplash.com/400x175/?github description: API docs for the triggersActionsUi plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'triggersActionsUi'] --- import triggersActionsUiObj from './triggers_actions_ui.devdocs.json'; diff --git a/api_docs/ui_actions.mdx b/api_docs/ui_actions.mdx index 671949fa14646..923384e4c2600 100644 --- a/api_docs/ui_actions.mdx +++ b/api_docs/ui_actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/uiActions title: "uiActions" image: https://source.unsplash.com/400x175/?github description: API docs for the uiActions plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'uiActions'] --- import uiActionsObj from './ui_actions.devdocs.json'; diff --git a/api_docs/ui_actions_enhanced.mdx b/api_docs/ui_actions_enhanced.mdx index f98ff3405923e..76c339e7a7e3a 100644 --- a/api_docs/ui_actions_enhanced.mdx +++ b/api_docs/ui_actions_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/uiActionsEnhanced title: "uiActionsEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the uiActionsEnhanced plugin -date: 2024-11-29 +date: 2024-12-03 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 ad068e26636c4..3327549edae03 100644 --- a/api_docs/unified_doc_viewer.mdx +++ b/api_docs/unified_doc_viewer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedDocViewer title: "unifiedDocViewer" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedDocViewer plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedDocViewer'] --- import unifiedDocViewerObj from './unified_doc_viewer.devdocs.json'; diff --git a/api_docs/unified_histogram.mdx b/api_docs/unified_histogram.mdx index b0e7db937ceb2..cb762669e1fe6 100644 --- a/api_docs/unified_histogram.mdx +++ b/api_docs/unified_histogram.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedHistogram title: "unifiedHistogram" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedHistogram plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedHistogram'] --- import unifiedHistogramObj from './unified_histogram.devdocs.json'; diff --git a/api_docs/unified_search.mdx b/api_docs/unified_search.mdx index 8d3242a850157..4a7b6b6a93256 100644 --- a/api_docs/unified_search.mdx +++ b/api_docs/unified_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedSearch title: "unifiedSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedSearch plugin -date: 2024-11-29 +date: 2024-12-03 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 b7164bce8510b..e390173873794 100644 --- a/api_docs/unified_search_autocomplete.mdx +++ b/api_docs/unified_search_autocomplete.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedSearch-autocomplete title: "unifiedSearch.autocomplete" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedSearch.autocomplete plugin -date: 2024-11-29 +date: 2024-12-03 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 f4e09fa306ac1..67b588c31ea63 100644 --- a/api_docs/uptime.mdx +++ b/api_docs/uptime.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/uptime title: "uptime" image: https://source.unsplash.com/400x175/?github description: API docs for the uptime plugin -date: 2024-11-29 +date: 2024-12-03 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 f641c130c598c..9918c9f120844 100644 --- a/api_docs/url_forwarding.mdx +++ b/api_docs/url_forwarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/urlForwarding title: "urlForwarding" image: https://source.unsplash.com/400x175/?github description: API docs for the urlForwarding plugin -date: 2024-11-29 +date: 2024-12-03 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 a72904a74490b..f9b10099d1e72 100644 --- a/api_docs/usage_collection.mdx +++ b/api_docs/usage_collection.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/usageCollection title: "usageCollection" image: https://source.unsplash.com/400x175/?github description: API docs for the usageCollection plugin -date: 2024-11-29 +date: 2024-12-03 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 7d98879577b77..40dfc1020e700 100644 --- a/api_docs/ux.mdx +++ b/api_docs/ux.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ux title: "ux" image: https://source.unsplash.com/400x175/?github description: API docs for the ux plugin -date: 2024-11-29 +date: 2024-12-03 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 04f9675dc944b..1c52c77a9c374 100644 --- a/api_docs/vis_default_editor.mdx +++ b/api_docs/vis_default_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visDefaultEditor title: "visDefaultEditor" image: https://source.unsplash.com/400x175/?github description: API docs for the visDefaultEditor plugin -date: 2024-11-29 +date: 2024-12-03 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 ebb3189ed08f0..e6d4660542074 100644 --- a/api_docs/vis_type_gauge.mdx +++ b/api_docs/vis_type_gauge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeGauge title: "visTypeGauge" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeGauge plugin -date: 2024-11-29 +date: 2024-12-03 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 319826c61b21f..d582a5d36f3b7 100644 --- a/api_docs/vis_type_heatmap.mdx +++ b/api_docs/vis_type_heatmap.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeHeatmap title: "visTypeHeatmap" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeHeatmap plugin -date: 2024-11-29 +date: 2024-12-03 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 51d2fe9e367d8..58bf93a187797 100644 --- a/api_docs/vis_type_pie.mdx +++ b/api_docs/vis_type_pie.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypePie title: "visTypePie" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypePie plugin -date: 2024-11-29 +date: 2024-12-03 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 09f53fb4734a6..868a64d7ea529 100644 --- a/api_docs/vis_type_table.mdx +++ b/api_docs/vis_type_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeTable title: "visTypeTable" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeTable plugin -date: 2024-11-29 +date: 2024-12-03 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 94c76b9ec74e4..46f5b63e4c4ca 100644 --- a/api_docs/vis_type_timelion.mdx +++ b/api_docs/vis_type_timelion.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeTimelion title: "visTypeTimelion" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeTimelion plugin -date: 2024-11-29 +date: 2024-12-03 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 96a94b8ac4757..0b7d0f0020d77 100644 --- a/api_docs/vis_type_timeseries.mdx +++ b/api_docs/vis_type_timeseries.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeTimeseries title: "visTypeTimeseries" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeTimeseries plugin -date: 2024-11-29 +date: 2024-12-03 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 ff50b026393cf..edbc75b2fa1a3 100644 --- a/api_docs/vis_type_vega.mdx +++ b/api_docs/vis_type_vega.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeVega title: "visTypeVega" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeVega plugin -date: 2024-11-29 +date: 2024-12-03 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 eb2fcb6a085cd..f0e417c66112d 100644 --- a/api_docs/vis_type_vislib.mdx +++ b/api_docs/vis_type_vislib.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeVislib title: "visTypeVislib" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeVislib plugin -date: 2024-11-29 +date: 2024-12-03 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 f388debf62ab4..61634c53a811a 100644 --- a/api_docs/vis_type_xy.mdx +++ b/api_docs/vis_type_xy.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeXy title: "visTypeXy" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeXy plugin -date: 2024-11-29 +date: 2024-12-03 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 26842c773bde4..234558c6457ac 100644 --- a/api_docs/visualizations.devdocs.json +++ b/api_docs/visualizations.devdocs.json @@ -7050,7 +7050,7 @@ "section": "def-common.AggregateQuery", "text": "AggregateQuery" }, - " | undefined; getFilters: () => ", + " | undefined; canLinkToLibrary: (() => Promise) | undefined; canUnlinkFromLibrary: (() => Promise) | undefined; onEdit: () => Promise; isEditingEnabled: () => boolean; getEditHref: () => Promise; getTypeDisplayName: () => string; getFilters: () => ", { "pluginId": "@kbn/es-query", "scope": "common", @@ -7058,7 +7058,7 @@ "section": "def-common.Filter", "text": "Filter" }, - "[]; canLinkToLibrary: (() => Promise) | undefined; canUnlinkFromLibrary: (() => Promise) | undefined; setTimeRange: (timeRange: ", + "[]; setTimeRange: (timeRange: ", { "pluginId": "@kbn/es-query", "scope": "common", @@ -7074,7 +7074,7 @@ "section": "def-public.VisualizeInput", "text": "VisualizeInput" }, - "; getDescription: () => string; onEdit: () => Promise; phase$: ", + "; getDescription: () => string; phase$: ", { "pluginId": "@kbn/presentation-publishing", "scope": "public", @@ -7090,7 +7090,7 @@ "section": "def-public.PhaseEvent", "text": "PhaseEvent" }, - " | undefined>; setPanelTitle: (newTitle: string | undefined) => void; isEditingEnabled: () => boolean; setHidePanelTitle: (hide: boolean | undefined) => void; getTypeDisplayName: () => string; setPanelDescription: (newTitle: string | undefined) => void; render: (domNode: HTMLElement) => Promise; getEditHref: () => Promise; supportedTriggers: () => string[]; getInspectorAdapters: () => ", + " | undefined>; setPanelTitle: (newTitle: string | undefined) => void; setHidePanelTitle: (hide: boolean | undefined) => void; setPanelDescription: (newTitle: string | undefined) => void; render: (domNode: HTMLElement) => Promise; supportedTriggers: () => string[]; getInspectorAdapters: () => ", { "pluginId": "inspector", "scope": "common", diff --git a/api_docs/visualizations.mdx b/api_docs/visualizations.mdx index 392f0b7990d18..ac0e737f773a2 100644 --- a/api_docs/visualizations.mdx +++ b/api_docs/visualizations.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visualizations title: "visualizations" image: https://source.unsplash.com/400x175/?github description: API docs for the visualizations plugin -date: 2024-11-29 +date: 2024-12-03 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visualizations'] --- import visualizationsObj from './visualizations.devdocs.json'; diff --git a/config/serverless.es.yml b/config/serverless.es.yml index 4b0d416bacdfc..3132125bfecde 100644 --- a/config/serverless.es.yml +++ b/config/serverless.es.yml @@ -59,6 +59,13 @@ xpack.features.overrides: stackAlerts: name: "Alerts" category: "enterpriseSearch" + ### Observability AI Assistant feature is moved to Search and renamed + observabilityAIAssistant: + name: "AI Assistant" + category: "enterpriseSearch" + ### AI Assistant enables the Inventory feature, moving to Search + inventory: + category: "enterpriseSearch" ## Cloud settings xpack.cloud.serverless.project_type: search @@ -127,7 +134,6 @@ xpack.observabilityAIAssistant.enabled: true xpack.searchAssistant.enabled: true xpack.searchAssistant.ui.enabled: true xpack.observabilityAIAssistant.scope: "search" -xpack.observabilityAIAssistant.enableKnowledgeBase: false aiAssistantManagementSelection.preferredAIAssistantType: "observability" xpack.observabilityAiAssistantManagement.logSourcesEnabled: false xpack.observabilityAiAssistantManagement.spacesEnabled: false diff --git a/docs/developer/plugin-list.asciidoc b/docs/developer/plugin-list.asciidoc index 8e8ee80ff81be..00841c869ef4f 100644 --- a/docs/developer/plugin-list.asciidoc +++ b/docs/developer/plugin-list.asciidoc @@ -470,6 +470,10 @@ The plugin exposes the static DefaultEditorController class to consume. |WARNING: Missing README. +|{kib-repo}blob/{branch}/x-pack/plugins/asset_inventory/README.md[assetInventory] +|Centralized asset inventory experience within the Elastic Security solution. A central place for users to view and manage all their assets from different environments. + + |{kib-repo}blob/{branch}/x-pack/plugins/banners/README.md[banners] |Allow to add a header banner that will be displayed on every page of the Kibana application diff --git a/docs/management/advanced-options.asciidoc b/docs/management/advanced-options.asciidoc index f6b8e6844ce04..fde70b5ffca0e 100644 --- a/docs/management/advanced-options.asciidoc +++ b/docs/management/advanced-options.asciidoc @@ -208,10 +208,6 @@ The default refresh interval for the time filter. Example: [[timepicker-timedefaults]]`timepicker:timeDefaults`:: The default selection in the time filter. -[[truncate-maxheight]]`truncate:maxHeight`:: -deprecated:[8.16.0]The maximum height that a cell occupies in a table. Set to 0 to disable -truncation. - [[enableESQL]]`enableESQL`:: This setting enables ES|QL in Kibana. @@ -340,14 +336,6 @@ Hides the "Time" column in *Discover* and in all saved searches on dashboards. Highlights results in *Discover* and saved searches on dashboards. Highlighting slows requests when working on big documents. -[[doctable-legacy]]`doc_table:legacy`:: -deprecated:[8.15.0] Controls the way the document table looks and works. -To use the new *Document Explorer* instead of the classic view, turn off this option. -The *Document Explorer* offers better data sorting, resizable columns, and a full screen view. - -[[truncate-max-height]]`truncate:maxHeight`:: -The maximum height that a cell in a table can occupy. To disable truncation, set to 0. - [float] [[kibana-ml-settings]] diff --git a/docs/settings/alert-action-settings.asciidoc b/docs/settings/alert-action-settings.asciidoc index 0f4987822dc32..6bd7eb1e76345 100644 --- a/docs/settings/alert-action-settings.asciidoc +++ b/docs/settings/alert-action-settings.asciidoc @@ -577,12 +577,6 @@ For a <>, <> - `xpack.alerting.cancelAlertsOnRuleTimeout` {ess-icon}:: Specifies whether to skip writing alerts and scheduling actions if rule processing was cancelled due to a timeout. Default: `true`. This setting can be diff --git a/oas_docs/kibana.info.yaml b/oas_docs/kibana.info.yaml index cb478f300214e..693f4db5981e4 100644 --- a/oas_docs/kibana.info.yaml +++ b/oas_docs/kibana.info.yaml @@ -42,11 +42,6 @@ info: x-feedbackLink: label: Feedback url: https://github.com/elastic/docs-content/issues/new?assignees=&labels=feedback%2Ccommunity&projects=&template=api-feedback.yaml&title=%5BFeedback%5D%3A+ -servers: - - url: https://{kibana_url} - variables: - kibana_url: - default: localhost:5601 security: - apiKeyAuth: [] - basicAuth: [] diff --git a/oas_docs/output/kibana.serverless.yaml b/oas_docs/output/kibana.serverless.yaml index 68a5ccaff2e10..b605ab09de62f 100644 --- a/oas_docs/output/kibana.serverless.yaml +++ b/oas_docs/output/kibana.serverless.yaml @@ -40,7 +40,7 @@ servers: - url: https://{kibana_url} variables: kibana_url: - default: localhost:5601 + default: security: - apiKeyAuth: [] tags: @@ -7560,42 +7560,6 @@ paths: tags: - Security Entity Analytics API x-beta: true - /api/entity_store/engines/{entityType}/stats: - post: - operationId: GetEntityEngineStats - parameters: - - description: The entity type of the engine (either 'user' or 'host'). - in: path - name: entityType - required: true - schema: - $ref: '#/components/schemas/Security_Entity_Analytics_API_EntityType' - responses: - '200': - content: - application/json; Elastic-Api-Version=2023-10-31: - schema: - type: object - properties: - indexPattern: - $ref: '#/components/schemas/Security_Entity_Analytics_API_IndexPattern' - indices: - items: - type: object - type: array - status: - $ref: '#/components/schemas/Security_Entity_Analytics_API_EngineStatus' - transforms: - items: - type: object - type: array - type: - $ref: '#/components/schemas/Security_Entity_Analytics_API_EntityType' - description: Successful response - summary: Get Entity Engine stats - tags: - - Security Entity Analytics API - x-beta: true /api/entity_store/engines/{entityType}/stop: post: operationId: StopEntityEngine @@ -7749,6 +7713,12 @@ paths: /api/entity_store/status: get: operationId: GetEntityStoreStatus + parameters: + - description: If true returns a detailed status of the engine including all it's components + in: query + name: include_components + schema: + type: boolean responses: '200': content: @@ -7758,10 +7728,20 @@ paths: properties: engines: items: - $ref: '#/components/schemas/Security_Entity_Analytics_API_EngineDescriptor' + allOf: + - $ref: '#/components/schemas/Security_Entity_Analytics_API_EngineDescriptor' + - type: object + properties: + components: + items: + $ref: '#/components/schemas/Security_Entity_Analytics_API_EngineComponentStatus' + type: array type: array status: $ref: '#/components/schemas/Security_Entity_Analytics_API_StoreStatus' + required: + - status + - engines description: Successful response summary: Get the status of the Entity Store tags: @@ -32247,8 +32227,6 @@ paths: Exported saved objects are not backwards compatible and cannot be imported into an older version of Kibana. NOTE: The `savedObjects.maxImportExportSize` configuration setting limits the number of saved objects which may be exported. - - This 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. operationId: exportSavedObjectsDefault parameters: - $ref: '#/components/parameters/Serverless_saved_objects_kbn_xsrf' @@ -32307,8 +32285,6 @@ paths: description: | Create sets of Kibana saved objects from a file created by the export API. Saved objects can be imported only into the same version, a newer minor on the same major, or the next major. Exported saved objects are not backwards compatible and cannot be imported into an older version of Kibana. - - This 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. operationId: importSavedObjectsDefault parameters: - $ref: '#/components/parameters/Serverless_saved_objects_kbn_xsrf' @@ -34512,8 +34488,6 @@ paths: schema: $ref: '#/components/schemas/SLOs_409_response' description: Conflict - The SLO id already exists - servers: - - url: https://localhost:5601 summary: Create an SLO tags: - slo @@ -34553,8 +34527,6 @@ paths: schema: $ref: '#/components/schemas/SLOs_403_response' description: Unauthorized response - servers: - - url: https://localhost:5601 summary: Batch delete rollup and summary data tags: - slo @@ -45755,6 +45727,47 @@ components: $ref: '#/components/schemas/Security_Entity_Analytics_API_AssetCriticalityLevel' required: - criticality_level + Security_Entity_Analytics_API_EngineComponentResource: + enum: + - entity_engine + - entity_definition + - index + - component_template + - index_template + - ingest_pipeline + - enrich_policy + - task + - transform + type: string + Security_Entity_Analytics_API_EngineComponentStatus: + type: object + properties: + errors: + items: + type: object + properties: + message: + type: string + title: + type: string + type: array + health: + enum: + - green + - yellow + - red + - unknown + type: string + id: + type: string + installed: + type: boolean + resource: + $ref: '#/components/schemas/Security_Entity_Analytics_API_EngineComponentResource' + required: + - id + - installed + - resource Security_Entity_Analytics_API_EngineDataviewUpdateResult: type: object properties: @@ -48650,19 +48663,23 @@ components: properties: frequency: default: 1m - description: Configure how often the transform runs, default 1m + description: The interval between checks for changes in the source data. The minimum value is 1m and the maximum is 59m. The default value is 1 minute. example: 5m type: string preventInitialBackfill: default: false - description: Prevents the transform from backfilling data when it starts. + description: Start aggregating data from the time the SLO is created, instead of backfilling data from the beginning of the time window. example: true type: boolean syncDelay: default: 1m - description: The synch delay to apply to the transform. Default 1m + description: The time delay in minutes between the current time and the latest source data time. Increasing the value will delay any alerting. The default value is 1 minute. The minimum value is 1m and the maximum is 359m. It should always be greater then source index refresh interval. example: 5m type: string + syncField: + description: The date field that is used to identify new documents in the source. It is strongly recommended to use a field that contains the ingest timestamp. If you use a different field, you might need to set the delay such that it accounts for data transmission delays. When unspecified, we use the indicator timestamp field. + example: event.ingested + type: string title: Settings type: object SLOs_slo_definition_response: diff --git a/oas_docs/output/kibana.yaml b/oas_docs/output/kibana.yaml index 208bced5d70f6..b1f2186262365 100644 --- a/oas_docs/output/kibana.yaml +++ b/oas_docs/output/kibana.yaml @@ -10445,41 +10445,6 @@ paths: summary: Start an Entity Engine tags: - Security Entity Analytics API - /api/entity_store/engines/{entityType}/stats: - post: - operationId: GetEntityEngineStats - parameters: - - description: The entity type of the engine (either 'user' or 'host'). - in: path - name: entityType - required: true - schema: - $ref: '#/components/schemas/Security_Entity_Analytics_API_EntityType' - responses: - '200': - content: - application/json; Elastic-Api-Version=2023-10-31: - schema: - type: object - properties: - indexPattern: - $ref: '#/components/schemas/Security_Entity_Analytics_API_IndexPattern' - indices: - items: - type: object - type: array - status: - $ref: '#/components/schemas/Security_Entity_Analytics_API_EngineStatus' - transforms: - items: - type: object - type: array - type: - $ref: '#/components/schemas/Security_Entity_Analytics_API_EntityType' - description: Successful response - summary: Get Entity Engine stats - tags: - - Security Entity Analytics API /api/entity_store/engines/{entityType}/stop: post: operationId: StopEntityEngine @@ -10630,6 +10595,12 @@ paths: /api/entity_store/status: get: operationId: GetEntityStoreStatus + parameters: + - description: If true returns a detailed status of the engine including all it's components + in: query + name: include_components + schema: + type: boolean responses: '200': content: @@ -10639,10 +10610,20 @@ paths: properties: engines: items: - $ref: '#/components/schemas/Security_Entity_Analytics_API_EngineDescriptor' + allOf: + - $ref: '#/components/schemas/Security_Entity_Analytics_API_EngineDescriptor' + - type: object + properties: + components: + items: + $ref: '#/components/schemas/Security_Entity_Analytics_API_EngineComponentStatus' + type: array type: array status: $ref: '#/components/schemas/Security_Entity_Analytics_API_StoreStatus' + required: + - status + - engines description: Successful response summary: Get the status of the Entity Store tags: @@ -35089,7 +35070,7 @@ paths: schema: type: object 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. '400': content: application/json; Elastic-Api-Version=2023-10-31: @@ -35121,7 +35102,7 @@ paths: schema: type: object 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. '400': content: application/json; Elastic-Api-Version=2023-10-31: @@ -35140,8 +35121,6 @@ paths: Exported saved objects are not backwards compatible and cannot be imported into an older version of Kibana. NOTE: The `savedObjects.maxImportExportSize` configuration setting limits the number of saved objects which may be exported. - - This 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. operationId: exportSavedObjectsDefault parameters: - $ref: '#/components/parameters/Saved_objects_kbn_xsrf' @@ -35301,8 +35280,6 @@ paths: description: | Create sets of Kibana saved objects from a file created by the export API. Saved objects can be imported only into the same version, a newer minor on the same major, or the next major. Exported saved objects are not backwards compatible and cannot be imported into an older version of Kibana. - - This 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. operationId: importSavedObjectsDefault parameters: - $ref: '#/components/parameters/Saved_objects_kbn_xsrf' @@ -35399,8 +35376,6 @@ paths: * Retry certain saved objects * Overwrite specific saved objects * Change references to different saved objects - - This 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. operationId: resolveImportErrors parameters: - $ref: '#/components/parameters/Saved_objects_kbn_xsrf' @@ -53478,6 +53453,47 @@ components: $ref: '#/components/schemas/Security_Entity_Analytics_API_AssetCriticalityLevel' required: - criticality_level + Security_Entity_Analytics_API_EngineComponentResource: + enum: + - entity_engine + - entity_definition + - index + - component_template + - index_template + - ingest_pipeline + - enrich_policy + - task + - transform + type: string + Security_Entity_Analytics_API_EngineComponentStatus: + type: object + properties: + errors: + items: + type: object + properties: + message: + type: string + title: + type: string + type: array + health: + enum: + - green + - yellow + - red + - unknown + type: string + id: + type: string + installed: + type: boolean + resource: + $ref: '#/components/schemas/Security_Entity_Analytics_API_EngineComponentResource' + required: + - id + - installed + - resource Security_Entity_Analytics_API_EngineDataviewUpdateResult: type: object properties: @@ -56355,19 +56371,23 @@ components: properties: frequency: default: 1m - description: Configure how often the transform runs, default 1m + description: The interval between checks for changes in the source data. The minimum value is 1m and the maximum is 59m. The default value is 1 minute. example: 5m type: string preventInitialBackfill: default: false - description: Prevents the transform from backfilling data when it starts. + description: Start aggregating data from the time the SLO is created, instead of backfilling data from the beginning of the time window. example: true type: boolean syncDelay: default: 1m - description: The synch delay to apply to the transform. Default 1m + description: The time delay in minutes between the current time and the latest source data time. Increasing the value will delay any alerting. The default value is 1 minute. The minimum value is 1m and the maximum is 359m. It should always be greater then source index refresh interval. example: 5m type: string + syncField: + description: The date field that is used to identify new documents in the source. It is strongly recommended to use a field that contains the ingest timestamp. If you use a different field, you might need to set the delay such that it accounts for data transmission delays. When unspecified, we use the indicator timestamp field. + example: event.ingested + type: string title: Settings type: object SLOs_slo_definition_response: diff --git a/oas_docs/overlays/kibana.overlays.serverless.yaml b/oas_docs/overlays/kibana.overlays.serverless.yaml index 1054f774fe11e..36efbe18e9403 100644 --- a/oas_docs/overlays/kibana.overlays.serverless.yaml +++ b/oas_docs/overlays/kibana.overlays.serverless.yaml @@ -14,7 +14,7 @@ actions: - url: https://{kibana_url} variables: kibana_url: - default: localhost:5601 + default: # Mark all operations as beta - target: "$.paths[*]['get','put','post','delete','options','head','patch','trace']" description: Add x-beta diff --git a/oas_docs/overlays/kibana.overlays.yaml b/oas_docs/overlays/kibana.overlays.yaml index ed41f56088bf8..666cba540a658 100644 --- a/oas_docs/overlays/kibana.overlays.yaml +++ b/oas_docs/overlays/kibana.overlays.yaml @@ -4,6 +4,17 @@ info: title: Overlays for the Kibana API document version: 0.0.1 actions: +# Clean up server definitions + - target: '$.servers.*' + description: Remove all servers so we can add our own. + remove: true + - target: '$.servers' + description: Add server into the now empty server array. + update: + - url: https://{kibana_url} + variables: + kibana_url: + default: localhost:5601 # Add an introduction to spaces - target: '$' description: Add an extra page about spaces diff --git a/oas_docs/package-lock.json b/oas_docs/package-lock.json index c3edcf9a017af..ab921922f0d15 100644 --- a/oas_docs/package-lock.json +++ b/oas_docs/package-lock.json @@ -9,7 +9,7 @@ "version": "1.0.0", "license": "ISC", "dependencies": { - "@redocly/cli": "^1.25.12", + "@redocly/cli": "^1.25.14", "bump-cli": "^2.8.4" } }, @@ -515,12 +515,12 @@ } }, "node_modules/@redocly/cli": { - "version": "1.25.14", - "resolved": "https://registry.npmjs.org/@redocly/cli/-/cli-1.25.14.tgz", - "integrity": "sha512-HRDOoN3YpFe4+2rWrL/uTqRUDqqyrRtj1MVHFJ0heKTfBLOFEEfXXUYExw7R6yoiY3+GnptR96wePeFpH1gheg==", + "version": "1.25.15", + "resolved": "https://registry.npmjs.org/@redocly/cli/-/cli-1.25.15.tgz", + "integrity": "sha512-ZD743CJX4FpMJvGNE9Cm3gNn8LNRzRjyrYNVPi1C4iIEtrFkr5Zq791qv6gUFehWns71svbVyzWD9ftVTdfqYg==", "license": "MIT", "dependencies": { - "@redocly/openapi-core": "1.25.14", + "@redocly/openapi-core": "1.25.15", "abort-controller": "^3.0.0", "chokidar": "^3.5.1", "colorette": "^1.2.0", @@ -550,18 +550,19 @@ } }, "node_modules/@redocly/config": { - "version": "0.16.0", - "resolved": "https://registry.npmjs.org/@redocly/config/-/config-0.16.0.tgz", - "integrity": "sha512-t9jnODbUcuANRSl/K4L9nb12V+U5acIHnVSl26NWrtSdDZVtoqUXk2yGFPZzohYf62cCfEQUT8ouJ3bhPfpnJg==" + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/@redocly/config/-/config-0.17.1.tgz", + "integrity": "sha512-CEmvaJuG7pm2ylQg53emPmtgm4nW2nxBgwXzbVEHpGas/lGnMyN8Zlkgiz6rPw0unASg6VW3wlz27SOL5XFHYQ==", + "license": "MIT" }, "node_modules/@redocly/openapi-core": { - "version": "1.25.14", - "resolved": "https://registry.npmjs.org/@redocly/openapi-core/-/openapi-core-1.25.14.tgz", - "integrity": "sha512-B9ewI0KVC1yqyeoQzErVnV4kdnxaYfwRMctxk/YwJxZZc/nVZ3VOVE+r2kXIFaGbUgc4ZHFn+aE2qvzCRXTXHw==", + "version": "1.25.15", + "resolved": "https://registry.npmjs.org/@redocly/openapi-core/-/openapi-core-1.25.15.tgz", + "integrity": "sha512-/dpr5zpGj2t1Bf7EIXEboRZm1hsJZBQfv3Q1pkivtdAEg3if2khv+b9gY68aquC6cM/2aQY2kMLy8LlY2tn+Og==", "license": "MIT", "dependencies": { "@redocly/ajv": "^8.11.2", - "@redocly/config": "^0.16.0", + "@redocly/config": "^0.17.0", "colorette": "^1.2.0", "https-proxy-agent": "^7.0.4", "js-levenshtein": "^1.1.6", diff --git a/oas_docs/package.json b/oas_docs/package.json index 88d55030405b5..9510dc4d31dc7 100644 --- a/oas_docs/package.json +++ b/oas_docs/package.json @@ -8,7 +8,7 @@ }, "dependencies": { "bump-cli": "^2.8.4", - "@redocly/cli": "^1.25.12" + "@redocly/cli": "^1.25.14" }, "scripts": { "test": "echo \"Error: no test specified\" && exit 1" diff --git a/package.json b/package.json index 99e47203f8c43..f6c3330adad25 100644 --- a/package.json +++ b/package.json @@ -111,7 +111,7 @@ "@elastic/apm-rum": "^5.16.1", "@elastic/apm-rum-core": "^5.21.1", "@elastic/apm-rum-react": "^2.0.3", - "@elastic/charts": "68.0.2", + "@elastic/charts": "68.0.3", "@elastic/datemath": "5.0.3", "@elastic/ebt": "^1.1.1", "@elastic/ecs": "^8.11.1", @@ -191,6 +191,7 @@ "@kbn/apm-utils": "link:packages/kbn-apm-utils", "@kbn/app-link-test-plugin": "link:test/plugin_functional/plugins/app_link_test", "@kbn/application-usage-test-plugin": "link:x-pack/test/usage_collection/plugins/application_usage_test", + "@kbn/asset-inventory-plugin": "link:x-pack/plugins/asset_inventory", "@kbn/audit-log-plugin": "link:x-pack/test/security_api_integration/plugins/audit_log", "@kbn/avc-banner": "link:packages/kbn-avc-banner", "@kbn/banners-plugin": "link:x-pack/plugins/banners", @@ -785,6 +786,7 @@ "@kbn/saved-objects-settings": "link:packages/kbn-saved-objects-settings", "@kbn/saved-objects-tagging-oss-plugin": "link:src/plugins/saved_objects_tagging_oss", "@kbn/saved-objects-tagging-plugin": "link:x-pack/plugins/saved_objects_tagging", + "@kbn/saved-search-component": "link:packages/kbn-saved-search-component", "@kbn/saved-search-plugin": "link:src/plugins/saved_search", "@kbn/screenshot-mode-example-plugin": "link:examples/screenshot_mode_example", "@kbn/screenshot-mode-plugin": "link:src/plugins/screenshot_mode", @@ -1430,6 +1432,7 @@ "@kbn/core-ui-settings-server-mocks": "link:packages/core/ui-settings/core-ui-settings-server-mocks", "@kbn/core-usage-data-server-mocks": "link:packages/core/usage-data/core-usage-data-server-mocks", "@kbn/cypress-config": "link:packages/kbn-cypress-config", + "@kbn/dependency-ownership": "link:packages/kbn-dependency-ownership", "@kbn/dependency-usage": "link:packages/kbn-dependency-usage", "@kbn/dev-cli-errors": "link:packages/kbn-dev-cli-errors", "@kbn/dev-cli-runner": "link:packages/kbn-dev-cli-runner", @@ -1513,7 +1516,7 @@ "@octokit/rest": "^17.11.2", "@parcel/watcher": "^2.1.0", "@playwright/test": "=1.46.0", - "@redocly/cli": "^1.25.12", + "@redocly/cli": "^1.25.14", "@statoscope/webpack-plugin": "^5.28.2", "@storybook/addon-a11y": "^6.5.16", "@storybook/addon-actions": "^6.5.16", @@ -1624,7 +1627,7 @@ "@types/picomatch": "^2.3.0", "@types/pidusage": "^2.0.2", "@types/pixelmatch": "^5.2.4", - "@types/pngjs": "^3.4.0", + "@types/pngjs": "^6.0.5", "@types/prop-types": "^15.7.5", "@types/rbush": "^3.0.0", "@types/react": "~18.2.0", @@ -1691,7 +1694,7 @@ "buildkite-test-collector": "^1.7.0", "callsites": "^3.1.0", "chance": "1.0.18", - "chromedriver": "^131.0.0", + "chromedriver": "^131.0.1", "clarify": "^2.2.0", "clean-webpack-plugin": "^3.0.0", "cli-progress": "^3.12.0", @@ -1790,8 +1793,8 @@ "native-hdr-histogram": "^1.0.0", "nock": "12.0.3", "null-loader": "^3.0.0", - "nyc": "^15.1.0", - "oboe": "^2.1.4", + "nyc": "^17.1.0", + "oboe": "^2.1.7", "openapi-types": "^12.1.3", "p-reflect": "2.1.0", "peggy": "^1.2.0", @@ -1802,7 +1805,7 @@ "pixelmatch": "^5.3.0", "playwright": "=1.46.0", "playwright-chromium": "=1.46.0", - "pngjs": "^3.4.0", + "pngjs": "^7.0.0", "postcss": "^8.4.31", "postcss-loader": "^4.2.0", "postcss-prefix-selector": "^1.16.0", @@ -1818,7 +1821,7 @@ "rxjs-marbles": "^7.0.1", "sass-embedded": "^1.78.0", "sass-loader": "^10.5.1", - "selenium-webdriver": "^4.26.0", + "selenium-webdriver": "^4.27.0", "sharp": "0.32.6", "simple-git": "^3.16.0", "sinon": "^7.4.2", @@ -1828,7 +1831,7 @@ "style-loader": "^1.1.3", "stylelint": "^14.9.1", "stylelint-scss": "^4.3.0", - "superagent": "^9.0.2", + "superagent": "^10.1.1", "supertest": "^7.0.0", "svgo": "^2.8.0", "swagger-jsdoc": "^6.2.8", @@ -1856,7 +1859,7 @@ "webpack-sources": "^1.4.1", "webpack-visualizer-plugin2": "^1.1.0", "xml-crypto": "^6.0.0", - "xmlbuilder": "13.0.2", + "xmlbuilder": "15.1.1", "yargs": "^15.4.1", "yarn-deduplicate": "^6.0.2", "zod-to-json-schema": "^3.23.0" diff --git a/packages/core/saved-objects/docs/openapi/bundled.json b/packages/core/saved-objects/docs/openapi/bundled.json index 45cfdd7fa5055..c445332816661 100644 --- a/packages/core/saved-objects/docs/openapi/bundled.json +++ b/packages/core/saved-objects/docs/openapi/bundled.json @@ -380,7 +380,7 @@ "post": { "summary": "Export saved objects", "operationId": "exportSavedObjectsDefault", - "description": "Retrieve sets of saved objects that you want to import into Kibana.\nYou must include `type` or `objects` in the request body.\n\nExported saved objects are not backwards compatible and cannot be imported into an older version of Kibana.\n\nNOTE: The `savedObjects.maxImportExportSize` configuration setting limits the number of saved objects which may be exported.\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": "Retrieve sets of saved objects that you want to import into Kibana.\nYou must include `type` or `objects` in the request body.\n\nExported saved objects are not backwards compatible and cannot be imported into an older version of Kibana.\n\nNOTE: The `savedObjects.maxImportExportSize` configuration setting limits the number of saved objects which may be exported.\n", "tags": [ "saved objects" ], @@ -639,7 +639,7 @@ "post": { "summary": "Import saved objects", "operationId": "importSavedObjectsDefault", - "description": "Create sets of Kibana saved objects from a file created by the export API.\nSaved objects can be imported only into the same version, a newer minor on the same major, or the next major. Exported saved objects are not backwards compatible and cannot be imported into an older version of Kibana.\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": "Create sets of Kibana saved objects from a file created by the export API.\nSaved objects can be imported only into the same version, a newer minor on the same major, or the next major. Exported saved objects are not backwards compatible and cannot be imported into an older version of Kibana.\n", "tags": [ "saved objects" ], @@ -759,7 +759,7 @@ "post": { "summary": "Resolve import errors", "operationId": "resolveImportErrors", - "description": "To resolve errors from the Import objects API, 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 from the Import objects API, you can:\n\n* Retry certain saved objects\n* Overwrite specific saved objects\n* Change references to different saved objects\n", "tags": [ "saved objects" ], @@ -1423,4 +1423,4 @@ } } } -} +} \ No newline at end of file diff --git a/packages/core/saved-objects/docs/openapi/bundled.yaml b/packages/core/saved-objects/docs/openapi/bundled.yaml index 9b5aad6e54958..b62424c10a7fe 100644 --- a/packages/core/saved-objects/docs/openapi/bundled.yaml +++ b/packages/core/saved-objects/docs/openapi/bundled.yaml @@ -216,7 +216,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: @@ -248,7 +248,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: @@ -270,8 +270,6 @@ paths: Exported saved objects are not backwards compatible and cannot be imported into an older version of Kibana. NOTE: The `savedObjects.maxImportExportSize` configuration setting limits the number of saved objects which may be exported. - - This 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. tags: - saved objects parameters: @@ -431,8 +429,6 @@ paths: description: | Create sets of Kibana saved objects from a file created by the export API. Saved objects can be imported only into the same version, a newer minor on the same major, or the next major. Exported saved objects are not backwards compatible and cannot be imported into an older version of Kibana. - - This 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. tags: - saved objects parameters: @@ -529,8 +525,6 @@ paths: * Retry certain saved objects * Overwrite specific saved objects * Change references to different saved objects - - This 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. tags: - saved objects parameters: diff --git a/packages/core/saved-objects/docs/openapi/bundled_serverless.json b/packages/core/saved-objects/docs/openapi/bundled_serverless.json index 67b8a710b5bcd..b225e95b14739 100644 --- a/packages/core/saved-objects/docs/openapi/bundled_serverless.json +++ b/packages/core/saved-objects/docs/openapi/bundled_serverless.json @@ -34,7 +34,7 @@ "post": { "summary": "Export saved objects", "operationId": "exportSavedObjectsDefault", - "description": "Retrieve sets of saved objects that you want to import into Kibana.\nYou must include `type` or `objects` in the request body.\n\nExported saved objects are not backwards compatible and cannot be imported into an older version of Kibana.\n\nNOTE: The `savedObjects.maxImportExportSize` configuration setting limits the number of saved objects which may be exported.\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": "Retrieve sets of saved objects that you want to import into Kibana.\nYou must include `type` or `objects` in the request body.\n\nExported saved objects are not backwards compatible and cannot be imported into an older version of Kibana.\n\nNOTE: The `savedObjects.maxImportExportSize` configuration setting limits the number of saved objects which may be exported.\n", "tags": [ "saved objects" ], @@ -124,7 +124,7 @@ "post": { "summary": "Import saved objects", "operationId": "importSavedObjectsDefault", - "description": "Create sets of Kibana saved objects from a file created by the export API.\nSaved objects can be imported only into the same version, a newer minor on the same major, or the next major. Exported saved objects are not backwards compatible and cannot be imported into an older version of Kibana.\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": "Create sets of Kibana saved objects from a file created by the export API.\nSaved objects can be imported only into the same version, a newer minor on the same major, or the next major. Exported saved objects are not backwards compatible and cannot be imported into an older version of Kibana.\n", "tags": [ "saved objects" ], @@ -358,4 +358,4 @@ } } } -} +} \ No newline at end of file diff --git a/packages/core/saved-objects/docs/openapi/bundled_serverless.yaml b/packages/core/saved-objects/docs/openapi/bundled_serverless.yaml index b874f0e32361b..d6775921a3080 100644 --- a/packages/core/saved-objects/docs/openapi/bundled_serverless.yaml +++ b/packages/core/saved-objects/docs/openapi/bundled_serverless.yaml @@ -37,8 +37,6 @@ paths: Exported saved objects are not backwards compatible and cannot be imported into an older version of Kibana. NOTE: The `savedObjects.maxImportExportSize` configuration setting limits the number of saved objects which may be exported. - - This 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. tags: - saved objects parameters: @@ -96,8 +94,6 @@ paths: description: | Create sets of Kibana saved objects from a file created by the export API. Saved objects can be imported only into the same version, a newer minor on the same major, or the next major. Exported saved objects are not backwards compatible and cannot be imported into an older version of Kibana. - - This 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. tags: - saved objects parameters: diff --git a/packages/core/saved-objects/docs/openapi/paths/api@saved_objects@_export.yaml b/packages/core/saved-objects/docs/openapi/paths/api@saved_objects@_export.yaml index 93224e4d243b3..fd9c248056164 100644 --- a/packages/core/saved-objects/docs/openapi/paths/api@saved_objects@_export.yaml +++ b/packages/core/saved-objects/docs/openapi/paths/api@saved_objects@_export.yaml @@ -8,8 +8,6 @@ post: Exported saved objects are not backwards compatible and cannot be imported into an older version of Kibana. NOTE: The `savedObjects.maxImportExportSize` configuration setting limits the number of saved objects which may be exported. - - This 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. tags: - saved objects parameters: diff --git a/packages/core/saved-objects/docs/openapi/paths/api@saved_objects@_import.yaml b/packages/core/saved-objects/docs/openapi/paths/api@saved_objects@_import.yaml index 3f27987f779f7..7bd9b6f801c49 100644 --- a/packages/core/saved-objects/docs/openapi/paths/api@saved_objects@_import.yaml +++ b/packages/core/saved-objects/docs/openapi/paths/api@saved_objects@_import.yaml @@ -4,8 +4,6 @@ post: description: | Create sets of Kibana saved objects from a file created by the export API. Saved objects can be imported only into the same version, a newer minor on the same major, or the next major. Exported saved objects are not backwards compatible and cannot be imported into an older version of Kibana. - - This 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. tags: - saved objects parameters: diff --git a/packages/core/saved-objects/docs/openapi/paths/api@saved_objects@_resolve_import_errors.yaml b/packages/core/saved-objects/docs/openapi/paths/api@saved_objects@_resolve_import_errors.yaml index bfca82dbe7274..c6d2b23ce012d 100644 --- a/packages/core/saved-objects/docs/openapi/paths/api@saved_objects@_resolve_import_errors.yaml +++ b/packages/core/saved-objects/docs/openapi/paths/api@saved_objects@_resolve_import_errors.yaml @@ -7,8 +7,6 @@ post: * Retry certain saved objects * Overwrite specific saved objects * Change references to different saved objects - - This 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. tags: - saved objects parameters: diff --git a/packages/kbn-alerting-types/search_strategy_types.ts b/packages/kbn-alerting-types/search_strategy_types.ts index 797ca82294b8a..9df72e4fa7886 100644 --- a/packages/kbn-alerting-types/search_strategy_types.ts +++ b/packages/kbn-alerting-types/search_strategy_types.ts @@ -8,7 +8,6 @@ */ import type { IEsSearchRequest, IEsSearchResponse } from '@kbn/search-types'; -import type { ValidFeatureId } from '@kbn/rule-data-utils'; import type { MappingRuntimeFields, QueryDslFieldAndFormat, @@ -18,7 +17,8 @@ import type { import type { Alert } from './alert_type'; export type RuleRegistrySearchRequest = IEsSearchRequest & { - featureIds: ValidFeatureId[]; + ruleTypeIds: string[]; + consumers?: string[]; fields?: QueryDslFieldAndFormat[]; query?: Pick; sort?: SortCombinations[]; diff --git a/packages/kbn-alerts-as-data-utils/src/schemas/generated/observability_threshold_schema.ts b/packages/kbn-alerts-as-data-utils/src/schemas/generated/observability_threshold_schema.ts new file mode 100644 index 0000000000000..2f08e082aebea --- /dev/null +++ b/packages/kbn-alerts-as-data-utils/src/schemas/generated/observability_threshold_schema.ts @@ -0,0 +1,90 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the "Elastic License + * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side + * Public License v 1"; you may not use this file except in compliance with, at + * your election, the "Elastic License 2.0", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ +// ---------------------------------- WARNING ---------------------------------- +// this file was generated, and should not be edited by hand +// ---------------------------------- WARNING ---------------------------------- +import * as rt from 'io-ts'; +import { Either } from 'fp-ts/lib/Either'; +import { AlertSchema } from './alert_schema'; +import { EcsSchema } from './ecs_schema'; +const ISO_DATE_PATTERN = /^d{4}-d{2}-d{2}Td{2}:d{2}:d{2}.d{3}Z$/; +export const IsoDateString = new rt.Type( + 'IsoDateString', + rt.string.is, + (input, context): Either => { + if (typeof input === 'string' && ISO_DATE_PATTERN.test(input)) { + return rt.success(input); + } else { + return rt.failure(input, context); + } + }, + rt.identity +); +export type IsoDateStringC = typeof IsoDateString; +export const schemaUnknown = rt.unknown; +export const schemaUnknownArray = rt.array(rt.unknown); +export const schemaString = rt.string; +export const schemaStringArray = rt.array(schemaString); +export const schemaNumber = rt.number; +export const schemaNumberArray = rt.array(schemaNumber); +export const schemaDate = rt.union([IsoDateString, schemaNumber]); +export const schemaDateArray = rt.array(schemaDate); +export const schemaDateRange = rt.partial({ + gte: schemaDate, + lte: schemaDate, +}); +export const schemaDateRangeArray = rt.array(schemaDateRange); +export const schemaStringOrNumber = rt.union([schemaString, schemaNumber]); +export const schemaStringOrNumberArray = rt.array(schemaStringOrNumber); +export const schemaBoolean = rt.boolean; +export const schemaBooleanArray = rt.array(schemaBoolean); +const schemaGeoPointCoords = rt.type({ + type: schemaString, + coordinates: schemaNumberArray, +}); +const schemaGeoPointString = schemaString; +const schemaGeoPointLatLon = rt.type({ + lat: schemaNumber, + lon: schemaNumber, +}); +const schemaGeoPointLocation = rt.type({ + location: schemaNumberArray, +}); +const schemaGeoPointLocationString = rt.type({ + location: schemaString, +}); +export const schemaGeoPoint = rt.union([ + schemaGeoPointCoords, + schemaGeoPointString, + schemaGeoPointLatLon, + schemaGeoPointLocation, + schemaGeoPointLocationString, +]); +export const schemaGeoPointArray = rt.array(schemaGeoPoint); +// prettier-ignore +const ObservabilityThresholdAlertRequired = rt.type({ +}); +// prettier-ignore +const ObservabilityThresholdAlertOptional = rt.partial({ + 'kibana.alert.context': schemaUnknown, + 'kibana.alert.evaluation.threshold': schemaStringOrNumber, + 'kibana.alert.evaluation.value': schemaStringOrNumber, + 'kibana.alert.evaluation.values': schemaStringOrNumberArray, + 'kibana.alert.group': rt.array( + rt.partial({ + field: schemaStringArray, + value: schemaStringArray, + }) + ), +}); + +// prettier-ignore +export const ObservabilityThresholdAlertSchema = rt.intersection([ObservabilityThresholdAlertRequired, ObservabilityThresholdAlertOptional, AlertSchema, EcsSchema]); +// prettier-ignore +export type ObservabilityThresholdAlert = rt.TypeOf; diff --git a/packages/kbn-alerts-grouping/src/components/alerts_grouping.test.tsx b/packages/kbn-alerts-grouping/src/components/alerts_grouping.test.tsx index 86ae0a54f9224..0137953b2313c 100644 --- a/packages/kbn-alerts-grouping/src/components/alerts_grouping.test.tsx +++ b/packages/kbn-alerts-grouping/src/components/alerts_grouping.test.tsx @@ -23,7 +23,8 @@ import { groupingSearchResponse } from '../mocks/grouping_query.mock'; import { useAlertsGroupingState } from '../contexts/alerts_grouping_context'; import { I18nProvider } from '@kbn/i18n-react'; import { - mockFeatureIds, + mockRuleTypeIds, + mockConsumers, mockDate, mockGroupingProps, mockGroupingId, @@ -146,7 +147,8 @@ describe('AlertsGrouping', () => { expect.objectContaining({ params: { aggregations: {}, - featureIds: mockFeatureIds, + ruleTypeIds: mockRuleTypeIds, + consumers: mockConsumers, groupByField: 'kibana.alert.rule.name', filters: [ { diff --git a/packages/kbn-alerts-grouping/src/components/alerts_grouping.tsx b/packages/kbn-alerts-grouping/src/components/alerts_grouping.tsx index d814d70903a5c..5ea010d442145 100644 --- a/packages/kbn-alerts-grouping/src/components/alerts_grouping.tsx +++ b/packages/kbn-alerts-grouping/src/components/alerts_grouping.tsx @@ -66,7 +66,7 @@ const AlertsGroupingInternal = ( const { groupingId, services, - featureIds, + ruleTypeIds, defaultGroupingOptions, defaultFilters, globalFilters, @@ -79,7 +79,7 @@ const AlertsGroupingInternal = ( const { grouping, updateGrouping } = useAlertsGroupingState(groupingId); const { dataView } = useAlertsDataView({ - featureIds, + ruleTypeIds, dataViewsService: dataViews, http, toasts: notifications.toasts, @@ -252,7 +252,7 @@ const typedMemo: (c: T) => T = memo; * * return ( * - * featureIds={[...]} + * ruleTypeIds={[...]} * globalQuery={{ query: ..., language: 'kql' }} * globalFilters={...} * from={...} diff --git a/packages/kbn-alerts-grouping/src/components/alerts_grouping_level.test.tsx b/packages/kbn-alerts-grouping/src/components/alerts_grouping_level.test.tsx index 5548c14fcf26f..b908b07caf7a1 100644 --- a/packages/kbn-alerts-grouping/src/components/alerts_grouping_level.test.tsx +++ b/packages/kbn-alerts-grouping/src/components/alerts_grouping_level.test.tsx @@ -55,6 +55,10 @@ const mockGroupingLevelProps: Omit = { describe('AlertsGroupingLevel', () => { let buildEsQuerySpy: jest.SpyInstance; + beforeEach(() => { + jest.clearAllMocks(); + }); + beforeAll(() => { buildEsQuerySpy = jest.spyOn(buildEsQueryModule, 'buildEsQuery'); }); @@ -119,4 +123,58 @@ describe('AlertsGroupingLevel', () => { Object.keys(groupingSearchResponse.aggregations) ); }); + + it('should calls useGetAlertsGroupAggregationsQuery with correct props', () => { + render( + + {() => } + + ); + + expect(mockUseGetAlertsGroupAggregationsQuery.mock.calls).toMatchInlineSnapshot(` + Array [ + Array [ + Object { + "enabled": true, + "http": Object { + "get": [MockFunction], + }, + "params": Object { + "aggregations": Object {}, + "consumers": Array [ + "stackAlerts", + ], + "filters": Array [ + Object { + "bool": Object { + "filter": Array [], + "must": Array [], + "must_not": Array [], + "should": Array [], + }, + }, + Object { + "range": Object { + "kibana.alert.time_range": Object { + "gte": "2020-07-07T08:20:18.966Z", + "lte": "2020-07-08T08:20:18.966Z", + }, + }, + }, + ], + "groupByField": "selectedGroup", + "pageIndex": 0, + "pageSize": 10, + "ruleTypeIds": Array [ + ".es-query", + ], + }, + "toasts": Object { + "addDanger": [MockFunction], + }, + }, + ], + ] + `); + }); }); diff --git a/packages/kbn-alerts-grouping/src/components/alerts_grouping_level.tsx b/packages/kbn-alerts-grouping/src/components/alerts_grouping_level.tsx index 7e620276d2e4d..02fd5d33e2379 100644 --- a/packages/kbn-alerts-grouping/src/components/alerts_grouping_level.tsx +++ b/packages/kbn-alerts-grouping/src/components/alerts_grouping_level.tsx @@ -46,7 +46,8 @@ const DEFAULT_FILTERS: Filter[] = []; const typedMemo: (c: T) => T = memo; export const AlertsGroupingLevel = typedMemo( ({ - featureIds, + ruleTypeIds, + consumers, defaultFilters = DEFAULT_FILTERS, from, getGrouping, @@ -86,7 +87,8 @@ export const AlertsGroupingLevel = typedMemo( const aggregationsQuery = useMemo(() => { return { - featureIds, + ruleTypeIds, + consumers, groupByField: selectedGroup, aggregations: getAggregationsByGroupingField(selectedGroup)?.reduce( (acc, val) => Object.assign(acc, val), @@ -107,12 +109,13 @@ export const AlertsGroupingLevel = typedMemo( pageSize, }; }, [ - featureIds, + consumers, filters, from, getAggregationsByGroupingField, pageIndex, pageSize, + ruleTypeIds, selectedGroup, to, ]); diff --git a/packages/kbn-alerts-grouping/src/mocks/grouping_props.mock.tsx b/packages/kbn-alerts-grouping/src/mocks/grouping_props.mock.tsx index 925a32fbd9de6..510c7c8fdb896 100644 --- a/packages/kbn-alerts-grouping/src/mocks/grouping_props.mock.tsx +++ b/packages/kbn-alerts-grouping/src/mocks/grouping_props.mock.tsx @@ -8,12 +8,12 @@ */ import React from 'react'; -import { AlertConsumers } from '@kbn/rule-data-utils'; import { AlertsGroupingProps } from '../types'; export const mockGroupingId = 'test'; -export const mockFeatureIds = [AlertConsumers.STACK_ALERTS]; +export const mockRuleTypeIds = ['.es-query']; +export const mockConsumers = ['stackAlerts']; export const mockDate = { from: '2020-07-07T08:20:18.966Z', @@ -30,7 +30,8 @@ export const mockOptions = [ export const mockGroupingProps: Omit = { ...mockDate, groupingId: mockGroupingId, - featureIds: mockFeatureIds, + ruleTypeIds: mockRuleTypeIds, + consumers: mockConsumers, defaultGroupingOptions: mockOptions, getAggregationsByGroupingField: () => [], getGroupStats: () => [{ title: 'Stat', component: }], diff --git a/packages/kbn-alerts-grouping/src/mocks/grouping_query.mock.ts b/packages/kbn-alerts-grouping/src/mocks/grouping_query.mock.ts index 8820f884928b7..486771e70a140 100644 --- a/packages/kbn-alerts-grouping/src/mocks/grouping_query.mock.ts +++ b/packages/kbn-alerts-grouping/src/mocks/grouping_query.mock.ts @@ -11,12 +11,12 @@ export const getQuery = ({ selectedGroup, uniqueValue, timeRange, - featureIds, + ruleTypeIds, }: { selectedGroup: string; uniqueValue: string; timeRange: { from: string; to: string }; - featureIds: string[]; + ruleTypeIds: string[]; }) => ({ _source: false, aggs: { @@ -52,7 +52,7 @@ export const getQuery = ({ }, }, }, - feature_ids: featureIds, + rule_type_ids: ruleTypeIds, query: { bool: { filter: [ diff --git a/packages/kbn-alerts-grouping/src/types.ts b/packages/kbn-alerts-grouping/src/types.ts index c6132e94e8729..f1eb9ef00fee8 100644 --- a/packages/kbn-alerts-grouping/src/types.ts +++ b/packages/kbn-alerts-grouping/src/types.ts @@ -8,7 +8,6 @@ */ import type { Filter, Query } from '@kbn/es-query'; -import { ValidFeatureId } from '@kbn/rule-data-utils'; import type { NotificationsStart } from '@kbn/core-notifications-browser'; import type { DataViewsServicePublic } from '@kbn/data-views-plugin/public/types'; import type { HttpSetup } from '@kbn/core-http-browser'; @@ -63,9 +62,13 @@ export interface AlertsGroupingProps< */ defaultGroupingOptions: GroupOption[]; /** - * The alerting feature ids this grouping covers + * The alerting rule type ids this grouping covers */ - featureIds: ValidFeatureId[]; + ruleTypeIds: string[]; + /** + * The alerting consumers this grouping covers + */ + consumers?: string[]; /** * Time filter start */ diff --git a/packages/kbn-alerts-ui-shared/src/action_variables/transforms.test.ts b/packages/kbn-alerts-ui-shared/src/action_variables/transforms.test.ts index d574aaf9592a9..6f362fd34710b 100644 --- a/packages/kbn-alerts-ui-shared/src/action_variables/transforms.test.ts +++ b/packages/kbn-alerts-ui-shared/src/action_variables/transforms.test.ts @@ -289,5 +289,6 @@ function getAlertType(actionVariables: ActionVariables): RuleType { producer: ALERTING_FEATURE_ID, minimumLicenseRequired: 'basic', enabledInLicense: true, + category: 'my-category', }; } diff --git a/packages/kbn-alerts-ui-shared/src/alert_filter_controls/alert_filter_controls.test.tsx b/packages/kbn-alerts-ui-shared/src/alert_filter_controls/alert_filter_controls.test.tsx index 3c314c62fc28c..6c35234b54006 100644 --- a/packages/kbn-alerts-ui-shared/src/alert_filter_controls/alert_filter_controls.test.tsx +++ b/packages/kbn-alerts-ui-shared/src/alert_filter_controls/alert_filter_controls.test.tsx @@ -10,7 +10,6 @@ import React from 'react'; import { render, screen } from '@testing-library/react'; import { AlertFilterControls, AlertFilterControlsProps } from './alert_filter_controls'; -import { AlertConsumers } from '@kbn/rule-data-utils'; import { DEFAULT_CONTROLS } from './constants'; import { useAlertsDataView } from '../common/hooks/use_alerts_data_view'; import { FilterGroup } from './filter_group'; @@ -56,7 +55,7 @@ const ControlGroupRenderer = (() => ( describe('AlertFilterControls', () => { const props: AlertFilterControlsProps = { - featureIds: [AlertConsumers.STACK_ALERTS], + ruleTypeIds: ['.es-query'], defaultControls: DEFAULT_CONTROLS, dataViewSpec: { id: 'alerts-filters-dv', diff --git a/packages/kbn-alerts-ui-shared/src/alert_filter_controls/alert_filter_controls.tsx b/packages/kbn-alerts-ui-shared/src/alert_filter_controls/alert_filter_controls.tsx index e8e7e63859250..f64b02e2ee350 100644 --- a/packages/kbn-alerts-ui-shared/src/alert_filter_controls/alert_filter_controls.tsx +++ b/packages/kbn-alerts-ui-shared/src/alert_filter_controls/alert_filter_controls.tsx @@ -12,7 +12,6 @@ import React, { useCallback, useEffect, useState } from 'react'; import type { Filter } from '@kbn/es-query'; import { EuiFlexItem } from '@elastic/eui'; import type { DataViewSpec, DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public'; -import { AlertConsumers } from '@kbn/rule-data-utils'; import { HttpStart } from '@kbn/core-http-browser'; import { NotificationsStart } from '@kbn/core-notifications-browser'; import type { Storage } from '@kbn/kibana-utils-plugin/public'; @@ -24,12 +23,12 @@ import { FilterControlConfig } from './types'; export type AlertFilterControlsProps = Omit< ComponentProps, - 'dataViewId' | 'defaultControls' | 'featureIds' | 'Storage' + 'dataViewId' | 'defaultControls' | 'ruleTypeIds' | 'Storage' > & { /** - * The feature ids used to get the correct alert data view(s) + * The rule type ids used to get the correct alert data view(s) */ - featureIds?: AlertConsumers[]; + ruleTypeIds?: string[]; /** * An array of default control configurations */ @@ -57,7 +56,7 @@ export type AlertFilterControlsProps = Omit< * * { const { - featureIds = [AlertConsumers.STACK_ALERTS], + ruleTypeIds = [], defaultControls = DEFAULT_CONTROLS, dataViewSpec, onFiltersChange, @@ -96,7 +95,7 @@ export const AlertFilterControls = (props: AlertFilterControlsProps) => { } = props; const [loadingPageFilters, setLoadingPageFilters] = useState(true); const { dataView, isLoading: isLoadingDataView } = useAlertsDataView({ - featureIds, + ruleTypeIds, dataViewsService: dataViews, http, toasts, @@ -156,7 +155,7 @@ export const AlertFilterControls = (props: AlertFilterControlsProps) => { > = (props) => { ) => { const { - featureIds, dataViewId, onFiltersChange, timeRange, @@ -59,6 +58,7 @@ export const FilterGroup = (props: PropsWithChildren) => { maxControls = Infinity, ControlGroupRenderer, Storage, + ruleTypeIds, storageKey, } = props; @@ -80,8 +80,8 @@ export const FilterGroup = (props: PropsWithChildren) => { const [controlGroup, setControlGroup] = useState(); const localStoragePageFilterKey = useMemo( - () => storageKey ?? `${featureIds.join(',')}.${spaceId}.${URL_PARAM_KEY}`, - [featureIds, spaceId, storageKey] + () => storageKey ?? `${ruleTypeIds.join(',')}.${spaceId}.${URL_PARAM_KEY}`, + [ruleTypeIds, spaceId, storageKey] ); const currentFiltersRef = useRef(); diff --git a/packages/kbn-alerts-ui-shared/src/alert_filter_controls/types.ts b/packages/kbn-alerts-ui-shared/src/alert_filter_controls/types.ts index 19a76c76ff6f8..ed625897a418e 100644 --- a/packages/kbn-alerts-ui-shared/src/alert_filter_controls/types.ts +++ b/packages/kbn-alerts-ui-shared/src/alert_filter_controls/types.ts @@ -15,7 +15,6 @@ import type { ControlGroupRendererApi, } from '@kbn/controls-plugin/public'; import type { Storage } from '@kbn/kibana-utils-plugin/public'; -import { AlertConsumers } from '@kbn/rule-data-utils'; export type FilterUrlFormat = Record< string, @@ -46,7 +45,7 @@ export interface FilterGroupProps extends Pick ( - - - - - - first - - - - - - - - - - - middle - - - - - - - - - - - - - - last - - - - - - - - - -`; - -exports[`TableHeader without time column renders correctly 1`] = ` - - - - - first - - - - - - - - - - - middle - - - - - - - - - - - - - - last - - - - - - - - - -`; diff --git a/src/plugins/discover/public/components/doc_table/components/table_header/helpers.tsx b/src/plugins/discover/public/components/doc_table/components/table_header/helpers.tsx deleted file mode 100644 index 6640164d76d50..0000000000000 --- a/src/plugins/discover/public/components/doc_table/components/table_header/helpers.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", the "GNU Affero General Public License v3.0 only", and the "Server Side - * Public License v 1"; you may not use this file except in compliance with, at - * your election, the "Elastic License 2.0", the "GNU Affero General Public - * License v3.0 only", or the "Server Side Public License, v 1". - */ - -import { i18n } from '@kbn/i18n'; -import type { DataView } from '@kbn/data-views-plugin/public'; - -export interface ColumnProps { - name: string; - displayName: string; - isSortable: boolean; - isRemoveable: boolean; - colLeftIdx: number; - colRightIdx: number; -} - -/** - * Returns properties necessary to display the time column - * If it's an DataView with timefield, the time column is - * prepended, not moveable and removeable - * @param timeFieldName - */ -export function getTimeColumn(timeFieldName: string): ColumnProps { - return { - name: timeFieldName, - displayName: timeFieldName, - isSortable: true, - isRemoveable: false, - colLeftIdx: -1, - colRightIdx: -1, - }; -} -/** - * A given array of column names returns an array of properties - * necessary to display the columns. If the given dataView - * has a timefield, a time column is prepended - * @param columns - * @param dataView - * @param hideTimeField - * @param isShortDots - */ -export function getDisplayedColumns( - columns: string[], - dataView: DataView, - hideTimeField: boolean, - isShortDots: boolean -) { - if (!Array.isArray(columns) || typeof dataView !== 'object' || !dataView.getFieldByName) { - return []; - } - - const columnProps = - columns.length === 0 - ? [ - { - name: '__document__', - displayName: i18n.translate('discover.docTable.tableHeader.documentHeader', { - defaultMessage: 'Document', - }), - isSortable: false, - isRemoveable: false, - colLeftIdx: -1, - colRightIdx: -1, - }, - ] - : columns.map((column, idx) => { - const field = dataView.getFieldByName(column); - return { - name: column, - displayName: field?.displayName ?? column, - isSortable: !!(field && field.sortable), - isRemoveable: column !== '_source' || columns.length > 1, - colLeftIdx: idx - 1 < 0 ? -1 : idx - 1, - colRightIdx: idx + 1 >= columns.length ? -1 : idx + 1, - }; - }); - - return !hideTimeField && dataView.timeFieldName - ? [getTimeColumn(dataView.timeFieldName), ...columnProps] - : columnProps; -} diff --git a/src/plugins/discover/public/components/doc_table/components/table_header/score_sort_warning.tsx b/src/plugins/discover/public/components/doc_table/components/table_header/score_sort_warning.tsx deleted file mode 100644 index 188a92ea98579..0000000000000 --- a/src/plugins/discover/public/components/doc_table/components/table_header/score_sort_warning.tsx +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the "Elastic License - * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side - * Public License v 1"; you may not use this file except in compliance with, at - * your election, the "Elastic License 2.0", the "GNU Affero General Public - * License v3.0 only", or the "Server Side Public License, v 1". - */ - -import React from 'react'; -import { EuiIconTip } from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; - -export function DocViewTableScoreSortWarning() { - const tooltipContent = i18n.translate('discover.docViews.table.scoreSortWarningTooltip', { - defaultMessage: 'In order to retrieve values for _score, you must sort by it.', - }); - - return ; -} diff --git a/src/plugins/discover/public/components/doc_table/components/table_header/table_header.test.tsx b/src/plugins/discover/public/components/doc_table/components/table_header/table_header.test.tsx deleted file mode 100644 index 7aa3988444388..0000000000000 --- a/src/plugins/discover/public/components/doc_table/components/table_header/table_header.test.tsx +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the "Elastic License - * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side - * Public License v 1"; you may not use this file except in compliance with, at - * your election, the "Elastic License 2.0", the "GNU Affero General Public - * License v3.0 only", or the "Server Side Public License, v 1". - */ - -import React from 'react'; -import { mountWithIntl } from '@kbn/test-jest-helpers'; -import type { DataView, DataViewField } from '@kbn/data-views-plugin/public'; -import type { SortOrder } from '@kbn/saved-search-plugin/public'; -import { TableHeader } from './table_header'; -import { findTestSubject } from '@elastic/eui/lib/test'; -import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public'; -import { DOC_HIDE_TIME_COLUMN_SETTING } from '@kbn/discover-utils'; -import { FORMATS_UI_SETTINGS } from '@kbn/field-formats-plugin/common'; - -const defaultUiSettings = { - get: (key: string) => { - if (key === DOC_HIDE_TIME_COLUMN_SETTING) { - return false; - } else if (key === FORMATS_UI_SETTINGS.SHORT_DOTS_ENABLE) { - return false; - } - }, -}; - -function getMockDataView() { - return { - id: 'test', - title: 'Test', - timeFieldName: 'time', - fields: [], - isTimeNanosBased: () => false, - getFieldByName: (name: string) => { - if (name === 'test1') { - return { - name, - displayName: name, - type: 'string', - aggregatable: false, - searchable: true, - sortable: true, - } as DataViewField; - } else { - return { - name, - displayName: name, - type: 'string', - aggregatable: false, - searchable: true, - sortable: false, - } as DataViewField; - } - }, - } as unknown as DataView; -} - -function getMockProps(props = {}) { - const defaultProps = { - dataView: getMockDataView(), - hideTimeColumn: false, - columns: ['first', 'middle', 'last'], - defaultSortOrder: 'desc', - sortOrder: [['time', 'asc']] as SortOrder[], - isShortDots: true, - onRemoveColumn: jest.fn(), - onChangeSortOrder: jest.fn(), - onMoveColumn: jest.fn(), - onPageNext: jest.fn(), - onPagePrevious: jest.fn(), - }; - - return Object.assign({}, defaultProps, props); -} - -describe('TableHeader with time column', () => { - const props = getMockProps(); - - const wrapper = mountWithIntl( - - - - - -
-
- ); - - test('renders correctly', () => { - const docTableHeader = findTestSubject(wrapper, 'docTableHeader'); - expect(docTableHeader.getDOMNode()).toMatchSnapshot(); - }); - - test('time column is sortable with button, cycling sort direction', () => { - findTestSubject(wrapper, 'docTableHeaderFieldSort_time').simulate('click'); - expect(props.onChangeSortOrder).toHaveBeenCalledWith([['time', 'desc']]); - }); - - test('time column is not removeable, no button displayed', () => { - const removeButton = findTestSubject(wrapper, 'docTableRemoveHeader-time'); - expect(removeButton.length).toBe(0); - }); - - test('time column is not moveable, no button displayed', () => { - const moveButtonLeft = findTestSubject(wrapper, 'docTableMoveLeftHeader-time'); - expect(moveButtonLeft.length).toBe(0); - const moveButtonRight = findTestSubject(wrapper, 'docTableMoveRightHeader-time'); - expect(moveButtonRight.length).toBe(0); - }); - - test('first column is removeable', () => { - const removeButton = findTestSubject(wrapper, 'docTableRemoveHeader-first'); - expect(removeButton.length).toBe(1); - removeButton.simulate('click'); - expect(props.onRemoveColumn).toHaveBeenCalledWith('first'); - }); - - test('first column is not moveable to the left', () => { - const moveButtonLeft = findTestSubject(wrapper, 'docTableMoveLeftHeader-first'); - expect(moveButtonLeft.length).toBe(0); - }); - - test('first column is moveable to the right', () => { - const moveButtonRight = findTestSubject(wrapper, 'docTableMoveRightHeader-first'); - expect(moveButtonRight.length).toBe(1); - moveButtonRight.simulate('click'); - expect(props.onMoveColumn).toHaveBeenCalledWith('first', 1); - }); - - test('middle column is moveable to the left', () => { - const moveButtonLeft = findTestSubject(wrapper, 'docTableMoveLeftHeader-middle'); - expect(moveButtonLeft.length).toBe(1); - moveButtonLeft.simulate('click'); - expect(props.onMoveColumn).toHaveBeenCalledWith('middle', 0); - }); - - test('middle column is moveable to the right', () => { - const moveButtonRight = findTestSubject(wrapper, 'docTableMoveRightHeader-middle'); - expect(moveButtonRight.length).toBe(1); - moveButtonRight.simulate('click'); - expect(props.onMoveColumn).toHaveBeenCalledWith('middle', 2); - }); - - test('last column moveable to the left', () => { - const moveButtonLeft = findTestSubject(wrapper, 'docTableMoveLeftHeader-last'); - expect(moveButtonLeft.length).toBe(1); - moveButtonLeft.simulate('click'); - expect(props.onMoveColumn).toHaveBeenCalledWith('last', 1); - }); -}); - -describe('TableHeader without time column', () => { - const props = getMockProps({ hideTimeColumn: true }); - - const wrapper = mountWithIntl( - { - if (key === DOC_HIDE_TIME_COLUMN_SETTING) { - return true; - } - }, - }, - }} - > - - - - -
-
- ); - - test('renders correctly', () => { - const docTableHeader = findTestSubject(wrapper, 'docTableHeader'); - expect(docTableHeader.getDOMNode()).toMatchSnapshot(); - }); - - test('first column is removeable', () => { - const removeButton = findTestSubject(wrapper, 'docTableRemoveHeader-first'); - expect(removeButton.length).toBe(1); - removeButton.simulate('click'); - expect(props.onRemoveColumn).toHaveBeenCalledWith('first'); - }); - - test('first column is not moveable to the left', () => { - const moveButtonLeft = findTestSubject(wrapper, 'docTableMoveLeftHeader-first'); - expect(moveButtonLeft.length).toBe(0); - }); - - test('first column is moveable to the right', () => { - const moveButtonRight = findTestSubject(wrapper, 'docTableMoveRightHeader-first'); - expect(moveButtonRight.length).toBe(1); - moveButtonRight.simulate('click'); - expect(props.onMoveColumn).toHaveBeenCalledWith('first', 1); - }); - - test('middle column is moveable to the left', () => { - const moveButtonLeft = findTestSubject(wrapper, 'docTableMoveLeftHeader-middle'); - expect(moveButtonLeft.length).toBe(1); - moveButtonLeft.simulate('click'); - expect(props.onMoveColumn).toHaveBeenCalledWith('middle', 0); - }); - - test('middle column is moveable to the right', () => { - const moveButtonRight = findTestSubject(wrapper, 'docTableMoveRightHeader-middle'); - expect(moveButtonRight.length).toBe(1); - moveButtonRight.simulate('click'); - expect(props.onMoveColumn).toHaveBeenCalledWith('middle', 2); - }); - - test('last column moveable to the left', () => { - const moveButtonLeft = findTestSubject(wrapper, 'docTableMoveLeftHeader-last'); - expect(moveButtonLeft.length).toBe(1); - moveButtonLeft.simulate('click'); - expect(props.onMoveColumn).toHaveBeenCalledWith('last', 1); - }); -}); diff --git a/src/plugins/discover/public/components/doc_table/components/table_header/table_header.tsx b/src/plugins/discover/public/components/doc_table/components/table_header/table_header.tsx deleted file mode 100644 index 04583c893841f..0000000000000 --- a/src/plugins/discover/public/components/doc_table/components/table_header/table_header.tsx +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the "Elastic License - * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side - * Public License v 1"; you may not use this file except in compliance with, at - * your election, the "Elastic License 2.0", the "GNU Affero General Public - * License v3.0 only", or the "Server Side Public License, v 1". - */ - -import React, { useMemo } from 'react'; -import type { DataView } from '@kbn/data-views-plugin/public'; -import { FORMATS_UI_SETTINGS } from '@kbn/field-formats-plugin/common'; -import type { SortOrder } from '@kbn/saved-search-plugin/public'; -import { DOC_HIDE_TIME_COLUMN_SETTING, SORT_DEFAULT_ORDER_SETTING } from '@kbn/discover-utils'; -import { TableHeaderColumn } from './table_header_column'; -import { getDisplayedColumns } from './helpers'; -import { getDefaultSort } from '../../../../utils/sorting'; -import { useDiscoverServices } from '../../../../hooks/use_discover_services'; - -interface Props { - columns: string[]; - dataView: DataView; - onChangeSortOrder?: (sortOrder: SortOrder[]) => void; - onMoveColumn?: (name: string, index: number) => void; - onRemoveColumn?: (name: string) => void; - sortOrder: SortOrder[]; -} - -export function TableHeader({ - columns, - dataView, - onChangeSortOrder, - onMoveColumn, - onRemoveColumn, - sortOrder, -}: Props) { - const { uiSettings } = useDiscoverServices(); - const [defaultSortOrder, hideTimeColumn, isShortDots] = useMemo( - () => [ - uiSettings.get(SORT_DEFAULT_ORDER_SETTING, 'desc'), - uiSettings.get(DOC_HIDE_TIME_COLUMN_SETTING, false), - uiSettings.get(FORMATS_UI_SETTINGS.SHORT_DOTS_ENABLE), - ], - [uiSettings] - ); - const displayedColumns = getDisplayedColumns(columns, dataView, hideTimeColumn, isShortDots); - - return ( - - - {displayedColumns.map((col, index) => { - return ( - - ); - })} - - ); -} diff --git a/src/plugins/discover/public/components/doc_table/components/table_header/table_header_column.tsx b/src/plugins/discover/public/components/doc_table/components/table_header/table_header_column.tsx deleted file mode 100644 index cbb1cb598f2c5..0000000000000 --- a/src/plugins/discover/public/components/doc_table/components/table_header/table_header_column.tsx +++ /dev/null @@ -1,234 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the "Elastic License - * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side - * Public License v 1"; you may not use this file except in compliance with, at - * your election, the "Elastic License 2.0", the "GNU Affero General Public - * License v3.0 only", or the "Server Side Public License, v 1". - */ - -import React from 'react'; -import { i18n } from '@kbn/i18n'; -import { EuiButtonIcon, EuiToolTip, EuiIconTip } from '@elastic/eui'; -import type { SortOrder } from '@kbn/saved-search-plugin/public'; -import { DocViewTableScoreSortWarning } from './score_sort_warning'; - -interface Props { - colLeftIdx: number; // idx of the column to the left, -1 if moving is not possible - colRightIdx: number; // idx of the column to the right, -1 if moving is not possible - displayName?: string; - isRemoveable: boolean; - isSortable: boolean; - isTimeColumn: boolean; - customLabel?: string; - name: string; - onChangeSortOrder?: (sortOrder: SortOrder[]) => void; - onMoveColumn?: (name: string, idx: number) => void; - onRemoveColumn?: (name: string) => void; - sortOrder: SortOrder[]; -} - -interface IconProps { - iconType: string; - color: 'primary' | 'text'; -} - -interface IconButtonProps { - active: boolean; - ariaLabel: string; - className: string; - iconProps: IconProps; - onClick: () => void | undefined; - testSubject: string; - tooltip: string; -} - -const sortDirectionToIcon: Record = { - desc: { iconType: 'sortDown', color: 'primary' }, - asc: { iconType: 'sortUp', color: 'primary' }, - '': { iconType: 'sortable', color: 'text' }, -}; - -const ICON_BUTTON_STYLE = { width: 12, height: 12 }; - -export function TableHeaderColumn({ - colLeftIdx, - colRightIdx, - displayName, - isRemoveable, - isSortable, - isTimeColumn, - customLabel, - name, - onChangeSortOrder, - onMoveColumn, - onRemoveColumn, - sortOrder, -}: Props) { - const [, sortDirection = ''] = sortOrder.find((sortPair) => name === sortPair[0]) || []; - const curSortWithoutCol = sortOrder.filter((pair) => pair[0] !== name); - const curColSort = sortOrder.find((pair) => pair[0] === name); - const curColSortDir = (curColSort && curColSort[1]) || ''; - - const fieldName = customLabel ?? displayName; - const timeAriaLabel = i18n.translate( - 'discover.docTable.tableHeader.timeFieldIconTooltipAriaLabel', - { - defaultMessage: '{timeFieldName} - this field represents the time that events occurred.', - values: { timeFieldName: fieldName }, - } - ); - const timeTooltip = i18n.translate('discover.docTable.tableHeader.timeFieldIconTooltip', { - defaultMessage: 'This field represents the time that events occurred.', - }); - - // If this is the _score column, and _score is not one of the columns inside the sort, show a - // warning that the _score will not be retrieved from Elasticsearch - const showScoreSortWarning = name === '_score' && !curColSort; - - const handleChangeSortOrder = () => { - if (!onChangeSortOrder) return; - - // Cycle goes Unsorted -> Asc -> Desc -> Unsorted - if (curColSort === undefined) { - onChangeSortOrder([...curSortWithoutCol, [name, 'asc']]); - } else if (curColSortDir === 'asc') { - onChangeSortOrder([...curSortWithoutCol, [name, 'desc']]); - } else if (curColSortDir === 'desc' && curSortWithoutCol.length === 0) { - // If we're at the end of the cycle and this is the only existing sort, we switch - // back to ascending sort instead of removing it. - onChangeSortOrder([[name, 'asc']]); - } else { - onChangeSortOrder(curSortWithoutCol); - } - }; - - const getSortButtonAriaLabel = () => { - const sortAscendingMessage = i18n.translate( - 'discover.docTable.tableHeader.sortByColumnAscendingAriaLabel', - { - defaultMessage: 'Sort {columnName} ascending', - values: { columnName: name }, - } - ); - const sortDescendingMessage = i18n.translate( - 'discover.docTable.tableHeader.sortByColumnDescendingAriaLabel', - { - defaultMessage: 'Sort {columnName} descending', - values: { columnName: name }, - } - ); - const stopSortingMessage = i18n.translate( - 'discover.docTable.tableHeader.sortByColumnUnsortedAriaLabel', - { - defaultMessage: 'Stop sorting on {columnName}', - values: { columnName: name }, - } - ); - - if (curColSort === undefined) { - return sortAscendingMessage; - } else if (sortDirection === 'asc') { - return sortDescendingMessage; - } else if (sortDirection === 'desc' && curSortWithoutCol.length === 0) { - return sortAscendingMessage; - } else { - return stopSortingMessage; - } - }; - - // action buttons displayed on the right side of the column name - const buttons: IconButtonProps[] = [ - // Sort Button - { - active: isSortable && typeof onChangeSortOrder === 'function', - ariaLabel: getSortButtonAriaLabel(), - className: !sortDirection ? 'kbnDocTableHeader__sortChange' : '', - iconProps: sortDirectionToIcon[sortDirection], - onClick: handleChangeSortOrder, - testSubject: `docTableHeaderFieldSort_${name}`, - tooltip: getSortButtonAriaLabel(), - }, - // Remove Button - { - active: isRemoveable && typeof onRemoveColumn === 'function', - ariaLabel: i18n.translate('discover.docTable.tableHeader.removeColumnButtonAriaLabel', { - defaultMessage: 'Remove {columnName} column', - values: { columnName: name }, - }), - className: 'kbnDocTableHeader__move', - iconProps: { iconType: 'cross', color: 'text' }, - onClick: () => onRemoveColumn && onRemoveColumn(name), - testSubject: `docTableRemoveHeader-${name}`, - tooltip: i18n.translate('discover.docTable.tableHeader.removeColumnButtonTooltip', { - defaultMessage: 'Remove Column', - }), - }, - // Move Left Button - { - active: colLeftIdx >= 0 && typeof onMoveColumn === 'function', - ariaLabel: i18n.translate('discover.docTable.tableHeader.moveColumnLeftButtonAriaLabel', { - defaultMessage: 'Move {columnName} column to the left', - values: { columnName: name }, - }), - className: 'kbnDocTableHeader__move', - iconProps: { iconType: 'sortLeft', color: 'text' }, - onClick: () => onMoveColumn && onMoveColumn(name, colLeftIdx), - testSubject: `docTableMoveLeftHeader-${name}`, - tooltip: i18n.translate('discover.docTable.tableHeader.moveColumnLeftButtonTooltip', { - defaultMessage: 'Move column to the left', - }), - }, - // Move Right Button - { - active: colRightIdx >= 0 && typeof onMoveColumn === 'function', - ariaLabel: i18n.translate('discover.docTable.tableHeader.moveColumnRightButtonAriaLabel', { - defaultMessage: 'Move {columnName} column to the right', - values: { columnName: name }, - }), - className: 'kbnDocTableHeader__move', - iconProps: { iconType: 'sortRight', color: 'text' }, - onClick: () => onMoveColumn && onMoveColumn(name, colRightIdx), - testSubject: `docTableMoveRightHeader-${name}`, - tooltip: i18n.translate('discover.docTable.tableHeader.moveColumnRightButtonTooltip', { - defaultMessage: 'Move column to the right', - }), - }, - ]; - - return ( - - - {showScoreSortWarning && } - {fieldName} - {isTimeColumn && ( - - )} - {buttons - .filter((button) => button.active) - .map((button, idx) => ( - - - - ))} - - - ); -} diff --git a/src/plugins/discover/public/components/doc_table/components/table_row.test.tsx b/src/plugins/discover/public/components/doc_table/components/table_row.test.tsx deleted file mode 100644 index 3452da4abc57e..0000000000000 --- a/src/plugins/discover/public/components/doc_table/components/table_row.test.tsx +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the "Elastic License - * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side - * Public License v 1"; you may not use this file except in compliance with, at - * your election, the "Elastic License 2.0", the "GNU Affero General Public - * License v3.0 only", or the "Server Side Public License, v 1". - */ - -import React from 'react'; -import { mountWithIntl, findTestSubject } from '@kbn/test-jest-helpers'; -import { TableRow, TableRowProps } from './table_row'; -import { createFilterManagerMock } from '@kbn/data-plugin/public/query/filter_manager/filter_manager.mock'; -import { dataViewWithTimefieldMock } from '../../../__mocks__/data_view_with_timefield'; -import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public'; -import { discoverServiceMock } from '../../../__mocks__/services'; - -import { DOC_HIDE_TIME_COLUMN_SETTING, MAX_DOC_FIELDS_DISPLAYED } from '@kbn/discover-utils'; -import { buildDataTableRecord } from '@kbn/discover-utils'; -import type { EsHitRecord } from '@kbn/discover-utils/types'; - -jest.mock('../utils/row_formatter', () => { - const originalModule = jest.requireActual('../utils/row_formatter'); - return { - ...originalModule, - formatRow: () => { - return mocked_document_cell; - }, - }; -}); - -const mountComponent = (props: TableRowProps) => { - return mountWithIntl( - { - if (key === DOC_HIDE_TIME_COLUMN_SETTING) { - return true; - } else if (key === MAX_DOC_FIELDS_DISPLAYED) { - return 100; - } - }, - }, - }} - > - - - - -
-
- ); -}; - -const mockHit = { - _index: 'mock_index', - _id: '1', - _score: 1, - _type: '_doc', - fields: [ - { - timestamp: '2020-20-01T12:12:12.123', - }, - ], - _source: { message: 'mock_message', bytes: 20 }, -} as unknown as EsHitRecord; - -const mockFilterManager = createFilterManagerMock(); - -describe('Doc table row component', () => { - const mockInlineFilter = jest.fn(); - const defaultProps = { - columns: ['_source'], - filter: mockInlineFilter, - dataView: dataViewWithTimefieldMock, - row: buildDataTableRecord(mockHit, dataViewWithTimefieldMock), - useNewFieldsApi: true, - filterManager: mockFilterManager, - addBasePath: (path: string) => path, - } as unknown as TableRowProps; - - it('should render __document__ column', () => { - const component = mountComponent({ ...defaultProps, columns: [] }); - const docTableField = findTestSubject(component, 'docTableField'); - expect(docTableField.first().text()).toBe('mocked_document_cell'); - }); - - it('should render message, _index and bytes fields', () => { - const component = mountComponent({ ...defaultProps, columns: ['message', '_index', 'bytes'] }); - - const fields = findTestSubject(component, 'docTableField'); - expect(fields.first().text()).toBe('mock_message'); - expect(fields.last().text()).toBe('20'); - expect(fields.length).toBe(3); - }); - - it('should apply filter when pressed', () => { - const component = mountComponent({ ...defaultProps, columns: ['bytes'] }); - - const fields = findTestSubject(component, 'docTableField'); - expect(fields.first().text()).toBe('20'); - - const filterInButton = findTestSubject(component, 'docTableCellFilter'); - filterInButton.simulate('click'); - expect(mockInlineFilter).toHaveBeenCalledWith( - dataViewWithTimefieldMock.getFieldByName('bytes'), - 20, - '+' - ); - }); - - describe('details row', () => { - it('should be empty by default', () => { - const component = mountComponent(defaultProps); - expect(findTestSubject(component, 'docViewerRowDetailsTitle').exists()).toBeFalsy(); - }); - - it('should expand the detail row when the toggle arrow is clicked', () => { - const component = mountComponent(defaultProps); - const toggleButton = findTestSubject(component, 'docTableExpandToggleColumn'); - - expect(findTestSubject(component, 'docViewerRowDetailsTitle').exists()).toBeFalsy(); - toggleButton.simulate('click'); - expect(findTestSubject(component, 'docViewerRowDetailsTitle').exists()).toBeTruthy(); - }); - - it('should hide the single/surrounding views for ES|QL mode', () => { - const props = { - ...defaultProps, - isEsqlMode: true, - }; - const component = mountComponent(props); - const toggleButton = findTestSubject(component, 'docTableExpandToggleColumn'); - toggleButton.simulate('click'); - expect(findTestSubject(component, 'docViewerRowDetailsTitle').text()).toBe('Expanded result'); - expect(findTestSubject(component, 'docTableRowAction').length).toBeFalsy(); - }); - }); -}); diff --git a/src/plugins/discover/public/components/doc_table/components/table_row.tsx b/src/plugins/discover/public/components/doc_table/components/table_row.tsx deleted file mode 100644 index 40a3a81499a1d..0000000000000 --- a/src/plugins/discover/public/components/doc_table/components/table_row.tsx +++ /dev/null @@ -1,239 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the "Elastic License - * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side - * Public License v 1"; you may not use this file except in compliance with, at - * your election, the "Elastic License 2.0", the "GNU Affero General Public - * License v3.0 only", or the "Server Side Public License, v 1". - */ - -import React, { Fragment, useCallback, useMemo, useState } from 'react'; -import classNames from 'classnames'; -import { i18n } from '@kbn/i18n'; -import { EuiButtonEmpty, EuiIcon } from '@elastic/eui'; -import { DataView } from '@kbn/data-views-plugin/public'; -import { Filter } from '@kbn/es-query'; -import type { - DataTableRecord, - EsHitRecord, - ShouldShowFieldInTableHandler, -} from '@kbn/discover-utils/types'; -import { formatFieldValue } from '@kbn/discover-utils'; -import { DOC_HIDE_TIME_COLUMN_SETTING, MAX_DOC_FIELDS_DISPLAYED } from '@kbn/discover-utils'; -import type { DocViewFilterFn } from '@kbn/unified-doc-viewer/types'; -import { UnifiedDocViewer } from '@kbn/unified-doc-viewer-plugin/public'; -import { TableCell } from './table_row/table_cell'; -import { formatRow, formatTopLevelObject } from '../utils/row_formatter'; -import { TableRowDetails } from './table_row_details'; -import { useDiscoverServices } from '../../../hooks/use_discover_services'; - -export type DocTableRow = EsHitRecord & { - isAnchor?: boolean; -}; - -export interface TableRowProps { - columns: string[]; - filter?: DocViewFilterFn; - filters?: Filter[]; - isEsqlMode?: boolean; - savedSearchId?: string; - row: DataTableRecord; - rows: DataTableRecord[]; - dataView: DataView; - useNewFieldsApi: boolean; - shouldShowFieldHandler: ShouldShowFieldInTableHandler; - onAddColumn?: (column: string) => void; - onRemoveColumn?: (column: string) => void; -} - -export const TableRow = ({ - filters, - isEsqlMode, - columns, - filter, - savedSearchId, - row, - rows, - dataView, - useNewFieldsApi, - shouldShowFieldHandler, - onAddColumn, - onRemoveColumn, -}: TableRowProps) => { - const { uiSettings, fieldFormats } = useDiscoverServices(); - const [maxEntries, hideTimeColumn] = useMemo( - () => [ - uiSettings.get(MAX_DOC_FIELDS_DISPLAYED), - uiSettings.get(DOC_HIDE_TIME_COLUMN_SETTING, false), - ], - [uiSettings] - ); - const [open, setOpen] = useState(false); - const docTableRowClassName = classNames('kbnDocTable__row', { - 'kbnDocTable__row--highlight': row.isAnchor, - }); - const anchorDocTableRowSubj = row.isAnchor ? ' docTableAnchorRow' : ''; - - const mapping = useMemo(() => dataView.fields.getByName, [dataView]); - - // toggle display of the rows details, a full list of the fields from each row - const toggleRow = () => setOpen((prevOpen) => !prevOpen); - - /** - * Fill an element with the value of a field - */ - const displayField = (fieldName: string) => { - // If we're formatting the _source column, don't use the regular field formatter, - // but our Discover mechanism to format a hit in a better human-readable way. - if (fieldName === '_source') { - return formatRow(row, dataView, shouldShowFieldHandler, maxEntries, fieldFormats); - } - - const formattedField = formatFieldValue( - row.flattened[fieldName], - row.raw, - fieldFormats, - dataView, - mapping(fieldName) - ); - - return ( - // formatFieldValue always returns sanitized HTML - // eslint-disable-next-line react/no-danger -
- ); - }; - const inlineFilter = useCallback( - (column: string, type: '+' | '-') => { - const field = dataView.fields.getByName(column); - filter?.(field!, row.flattened[column], type); - }, - [filter, dataView.fields, row.flattened] - ); - - const rowCells = [ - - - {open ? ( - - ) : ( - - )} - - , - ]; - - if (dataView.timeFieldName && !hideTimeColumn) { - rowCells.push( - - ); - } - - if (columns.length === 0 && useNewFieldsApi) { - const formatted = formatRow(row, dataView, shouldShowFieldHandler, maxEntries, fieldFormats); - - rowCells.push( - - ); - } else { - columns.forEach(function (column: string, index) { - const cellKey = `${column}-${index}`; - if (useNewFieldsApi && !mapping(column) && row.raw.fields && !row.raw.fields[column]) { - const innerColumns = Object.fromEntries( - Object.entries(row.raw.fields).filter(([key]) => { - return key.indexOf(`${column}.`) === 0; - }) - ); - - rowCells.push( - - ); - } else { - // Check whether the field is defined as filterable in the mapping and does - // NOT have ignored values in it to determine whether we want to allow filtering. - // We should improve this and show a helpful tooltip why the filter buttons are not - // there/disabled when there are ignored values. - const isFilterable = Boolean( - mapping(column)?.filterable && - typeof filter === 'function' && - !row.raw._ignored?.includes(column) - ); - rowCells.push( - - ); - } - }); - } - - return ( - - - {rowCells} - - - {open && ( - - - - )} - - - ); -}; diff --git a/src/plugins/discover/public/components/doc_table/components/table_row/__snapshots__/table_cell.test.tsx.snap b/src/plugins/discover/public/components/doc_table/components/table_row/__snapshots__/table_cell.test.tsx.snap deleted file mode 100644 index b4f03267ec810..0000000000000 --- a/src/plugins/discover/public/components/doc_table/components/table_row/__snapshots__/table_cell.test.tsx.snap +++ /dev/null @@ -1,369 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Doc table cell component renders a cell with filter buttons if it is filterable 1`] = ` - - formatted content - - } - inlineFilter={[Function]} - sourcefield={false} - timefield={true} -> - - - formatted content - - - - - - - - - - , - "ctr": 2, - "insertionPoint": undefined, - "isSpeedy": false, - "key": "css", - "nonce": undefined, - "prepend": undefined, - "tags": Array [ - , - , - ], - }, - } - } - isStringTag={true} - serialized={ - Object { - "map": undefined, - "name": "jcaat8-euiToolTipAnchor-inlineBlock", - "next": undefined, - "styles": "*[disabled]{pointer-events:none;};label:euiToolTipAnchor;;;display:inline-block;label:inlineBlock;;;", - "toString": [Function], - } - } - /> - - - - - - - - - - - - - , - "ctr": 2, - "insertionPoint": undefined, - "isSpeedy": false, - "key": "css", - "nonce": undefined, - "prepend": undefined, - "tags": Array [ - , - , - ], - }, - } - } - isStringTag={true} - serialized={ - Object { - "map": undefined, - "name": "jcaat8-euiToolTipAnchor-inlineBlock", - "next": undefined, - "styles": "*[disabled]{pointer-events:none;};label:euiToolTipAnchor;;;display:inline-block;label:inlineBlock;;;", - "toString": [Function], - } - } - /> - - - - - - - - - - -`; - -exports[`Doc table cell component renders a cell without filter buttons if it is not filterable 1`] = ` - - formatted content - - } - inlineFilter={[Function]} - sourcefield={false} - timefield={true} -> - - - formatted content - - - - -`; - -exports[`Doc table cell component renders a field that is neither a timefield or sourcefield 1`] = ` - - formatted content - - } - inlineFilter={[Function]} - sourcefield={false} - timefield={false} -> - - - formatted content - - - - -`; - -exports[`Doc table cell component renders a sourcefield 1`] = ` - - formatted content - - } - inlineFilter={[Function]} - sourcefield={true} - timefield={false} -> - - - formatted content - - - - -`; diff --git a/src/plugins/discover/public/components/doc_table/components/table_row/_cell.scss b/src/plugins/discover/public/components/doc_table/components/table_row/_cell.scss deleted file mode 100644 index 2e643c195208c..0000000000000 --- a/src/plugins/discover/public/components/doc_table/components/table_row/_cell.scss +++ /dev/null @@ -1,47 +0,0 @@ -.kbnDocTableCell__dataField { - white-space: pre-wrap; -} - -.kbnDocTableCell__toggleDetails { - padding: $euiSizeXS 0 0 0 !important; -} - -/** - * Fixes time column width in Firefox after toggle display of the rows details. - * Described issue - https://github.com/elastic/kibana/pull/104361#issuecomment-894271241 - */ -.kbnDocTableCell--extraWidth { - width: 1%; -} - -.kbnDocTableCell__filter { - position: absolute; - white-space: nowrap; - right: 0; -} - -.kbnDocTableCell__filterButton { - font-size: $euiFontSizeXS; - padding: $euiSizeXS; -} - -/** - * 1. Align icon with text in cell. - * 2. Use opacity to make this element accessible to screen readers and keyboard. - * 3. Show on focus to enable keyboard accessibility. - */ - -.kbnDocTableRowFilterButton { - appearance: none; - background-color: $euiColorEmptyShade; - border: none; - padding: 0 $euiSizeXS; - font-size: $euiFontSizeS; - line-height: 1; /* 1 */ - display: inline-block; - opacity: 0; /* 2 */ - - &:focus { - opacity: 1; /* 3 */ - } -} diff --git a/src/plugins/discover/public/components/doc_table/components/table_row/_details.scss b/src/plugins/discover/public/components/doc_table/components/table_row/_details.scss deleted file mode 100644 index cc6ccfe9fd29f..0000000000000 --- a/src/plugins/discover/public/components/doc_table/components/table_row/_details.scss +++ /dev/null @@ -1,24 +0,0 @@ -/** - * 1. Visually align the actions with the tabs. We can improve this by using flexbox instead, at a later point. - */ -.kbnDocTableDetails__actions { - float: right; - padding-top: $euiSizeS; /* 1 */ -} - -// Overwrite the border on the bootstrap table -.kbnDocTableDetails__row { - - > td { - // Offsets negative margins from an inner flex group - padding: $euiSizeL !important; - - tr:hover td { - background: tintOrShade($euiColorLightestShade, 50%, 20%); - } - } - - td { - border-top: none !important; - } -} diff --git a/src/plugins/discover/public/components/doc_table/components/table_row/_index.scss b/src/plugins/discover/public/components/doc_table/components/table_row/_index.scss deleted file mode 100644 index c7ccdaa39ff65..0000000000000 --- a/src/plugins/discover/public/components/doc_table/components/table_row/_index.scss +++ /dev/null @@ -1,3 +0,0 @@ -@import 'cell'; -@import 'details'; -@import 'open'; diff --git a/src/plugins/discover/public/components/doc_table/components/table_row/_open.scss b/src/plugins/discover/public/components/doc_table/components/table_row/_open.scss deleted file mode 100644 index 659481e0968b5..0000000000000 --- a/src/plugins/discover/public/components/doc_table/components/table_row/_open.scss +++ /dev/null @@ -1,14 +0,0 @@ -/** - * 1. When switching between open and closed, the toggle changes size - * slightly which is a problem because it forces the entire table to - * re-render which is SLOW. - */ - -.kbnDocTableOpen__button { - appearance: none; - background-color: transparent; - padding: 0; - border: none; - width: 14px; /* 1 */ - height: 14px; -} diff --git a/src/plugins/discover/public/components/doc_table/components/table_row/table_cell.test.tsx b/src/plugins/discover/public/components/doc_table/components/table_row/table_cell.test.tsx deleted file mode 100644 index ed8d05d87949a..0000000000000 --- a/src/plugins/discover/public/components/doc_table/components/table_row/table_cell.test.tsx +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the "Elastic License - * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side - * Public License v 1"; you may not use this file except in compliance with, at - * your election, the "Elastic License 2.0", the "GNU Affero General Public - * License v3.0 only", or the "Server Side Public License, v 1". - */ - -import React from 'react'; -import { mount } from 'enzyme'; -import { CellProps, TableCell } from './table_cell'; - -const mountComponent = (props: Omit) => { - return mount( {}} />); -}; - -describe('Doc table cell component', () => { - test('renders a cell without filter buttons if it is not filterable', () => { - const component = mountComponent({ - filterable: false, - column: 'foo', - timefield: true, - sourcefield: false, - formatted: formatted content, - }); - expect(component).toMatchSnapshot(); - }); - - it('renders a cell with filter buttons if it is filterable', () => { - expect( - mountComponent({ - filterable: true, - column: 'foo', - timefield: true, - sourcefield: false, - formatted: formatted content, - }) - ).toMatchSnapshot(); - }); - - it('renders a sourcefield', () => { - expect( - mountComponent({ - filterable: false, - column: 'foo', - timefield: false, - sourcefield: true, - formatted: formatted content, - }) - ).toMatchSnapshot(); - }); - - it('renders a field that is neither a timefield or sourcefield', () => { - expect( - mountComponent({ - filterable: false, - column: 'foo', - timefield: false, - sourcefield: false, - formatted: formatted content, - }) - ).toMatchSnapshot(); - }); -}); diff --git a/src/plugins/discover/public/components/doc_table/components/table_row/table_cell.tsx b/src/plugins/discover/public/components/doc_table/components/table_row/table_cell.tsx deleted file mode 100644 index 83f60dd50587c..0000000000000 --- a/src/plugins/discover/public/components/doc_table/components/table_row/table_cell.tsx +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the "Elastic License - * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side - * Public License v 1"; you may not use this file except in compliance with, at - * your election, the "Elastic License 2.0", the "GNU Affero General Public - * License v3.0 only", or the "Server Side Public License, v 1". - */ - -import React from 'react'; -import classNames from 'classnames'; -import { TableCellActions } from './table_cell_actions'; -export interface CellProps { - timefield: boolean; - sourcefield?: boolean; - formatted: JSX.Element; - filterable: boolean; - column: string; - inlineFilter: (column: string, type: '+' | '-') => void; -} - -export const TableCell = (props: CellProps) => { - const classes = classNames({ - ['eui-textNoWrap kbnDocTableCell--extraWidth']: props.timefield, - ['eui-textBreakAll eui-textBreakWord']: props.sourcefield, - ['kbnDocTableCell__dataField eui-textBreakAll eui-textBreakWord']: - !props.timefield && !props.sourcefield, - }); - - const handleFilterFor = () => props.inlineFilter(props.column, '+'); - const handleFilterOut = () => props.inlineFilter(props.column, '-'); - - return ( - - {props.formatted} - {props.filterable ? ( - - ) : ( - - )} - - ); -}; diff --git a/src/plugins/discover/public/components/doc_table/components/table_row/table_cell_actions.tsx b/src/plugins/discover/public/components/doc_table/components/table_row/table_cell_actions.tsx deleted file mode 100644 index cc096bd1cafd5..0000000000000 --- a/src/plugins/discover/public/components/doc_table/components/table_row/table_cell_actions.tsx +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the "Elastic License - * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side - * Public License v 1"; you may not use this file except in compliance with, at - * your election, the "Elastic License 2.0", the "GNU Affero General Public - * License v3.0 only", or the "Server Side Public License, v 1". - */ - -import React from 'react'; -import { EuiIcon, EuiToolTip } from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; - -interface TableCellActionsProps { - handleFilterFor: () => void; - handleFilterOut: () => void; -} - -export const TableCellActions = ({ handleFilterFor, handleFilterOut }: TableCellActionsProps) => { - return ( - - - - - - - - - - ); -}; diff --git a/src/plugins/discover/public/components/doc_table/components/table_row_details.tsx b/src/plugins/discover/public/components/doc_table/components/table_row_details.tsx deleted file mode 100644 index eefb0f638935f..0000000000000 --- a/src/plugins/discover/public/components/doc_table/components/table_row_details.tsx +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the "Elastic License - * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side - * Public License v 1"; you may not use this file except in compliance with, at - * your election, the "Elastic License 2.0", the "GNU Affero General Public - * License v3.0 only", or the "Server Side Public License, v 1". - */ - -import React from 'react'; -import { EuiFlexGroup, EuiFlexItem, EuiIcon, EuiButtonEmpty, EuiTitle } from '@elastic/eui'; -import { FormattedMessage } from '@kbn/i18n-react'; -import type { DataView } from '@kbn/data-views-plugin/public'; -import type { Filter } from '@kbn/es-query'; -import { useNavigationProps } from '../../../hooks/use_navigation_props'; - -interface TableRowDetailsProps { - children: JSX.Element; - colLength: number; - rowIndex: string | undefined; - rowId: string | undefined; - columns: string[]; - isTimeBased: boolean; - dataView: DataView; - filters?: Filter[]; - savedSearchId?: string; - isEsqlMode?: boolean; -} - -export const TableRowDetails = ({ - colLength, - isTimeBased, - children, - dataView, - rowIndex, - rowId, - columns, - filters, - savedSearchId, - isEsqlMode, -}: TableRowDetailsProps) => { - const { singleDocHref, contextViewHref, onOpenSingleDoc, onOpenContextView } = useNavigationProps( - { - dataView, - rowIndex, - rowId, - columns, - filters, - savedSearchId, - } - ); - - return ( - - - - - - - - - -

- {isEsqlMode && ( - - )} - {!isEsqlMode && ( - - )} -

-
-
-
-
- {!isEsqlMode && ( - - - - {isTimeBased && ( - /* eslint-disable-next-line @elastic/eui/href-or-on-click */ - - - - )} - - - {/* eslint-disable-next-line @elastic/eui/href-or-on-click */} - - - - - - - )} -
-
{children}
- - ); -}; diff --git a/src/plugins/discover/public/components/doc_table/create_doc_table_embeddable.tsx b/src/plugins/discover/public/components/doc_table/create_doc_table_embeddable.tsx deleted file mode 100644 index 9d12c2fba3377..0000000000000 --- a/src/plugins/discover/public/components/doc_table/create_doc_table_embeddable.tsx +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the "Elastic License - * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side - * Public License v 1"; you may not use this file except in compliance with, at - * your election, the "Elastic License 2.0", the "GNU Affero General Public - * License v3.0 only", or the "Server Side Public License, v 1". - */ - -import React from 'react'; -import { DocTableEmbeddable, DocTableEmbeddableProps } from './doc_table_embeddable'; - -export function DiscoverDocTableEmbeddable(renderProps: DocTableEmbeddableProps) { - return ( - - ); -} diff --git a/src/plugins/discover/public/components/doc_table/doc_table_context.tsx b/src/plugins/discover/public/components/doc_table/doc_table_context.tsx deleted file mode 100644 index c1e685d1d8048..0000000000000 --- a/src/plugins/discover/public/components/doc_table/doc_table_context.tsx +++ /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", the "GNU Affero General Public License v3.0 only", and the "Server Side - * Public License v 1"; you may not use this file except in compliance with, at - * your election, the "Elastic License 2.0", the "GNU Affero General Public - * License v3.0 only", or the "Server Side Public License, v 1". - */ - -import React, { Fragment } from 'react'; -import './index.scss'; -import { SkipBottomButton } from '../../application/main/components/skip_bottom_button'; -import { DocTableProps, DocTableRenderProps, DocTableWrapper } from './doc_table_wrapper'; - -const DocTableWrapperMemoized = React.memo(DocTableWrapper); - -const renderDocTable = (tableProps: DocTableRenderProps) => { - return ( - - - - {tableProps.renderHeader()} - {tableProps.renderRows(tableProps.rows)} -
- - ​ - -
- ); -}; - -export const DocTableContext = (props: DocTableProps) => { - return ; -}; diff --git a/src/plugins/discover/public/components/doc_table/doc_table_embeddable.tsx b/src/plugins/discover/public/components/doc_table/doc_table_embeddable.tsx deleted file mode 100644 index 1c1274a739f1c..0000000000000 --- a/src/plugins/discover/public/components/doc_table/doc_table_embeddable.tsx +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the "Elastic License - * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side - * Public License v 1"; you may not use this file except in compliance with, at - * your election, the "Elastic License 2.0", the "GNU Affero General Public - * License v3.0 only", or the "Server Side Public License, v 1". - */ - -import React, { memo, useCallback, useMemo, useRef } from 'react'; -import './index.scss'; -import { FormattedMessage } from '@kbn/i18n-react'; -import { EuiText } from '@elastic/eui'; -import { usePager } from '@kbn/discover-utils'; -import type { SearchResponseWarning } from '@kbn/search-response-warnings'; -import { - ToolBarPagination, - MAX_ROWS_PER_PAGE_OPTION, -} from './components/pager/tool_bar_pagination'; -import { DocTableProps, DocTableRenderProps, DocTableWrapper } from './doc_table_wrapper'; -import { SavedSearchEmbeddableBase } from '../../embeddable/components/saved_search_embeddable_base'; - -export interface DocTableEmbeddableProps extends Omit { - totalHitCount?: number; - rowsPerPageState?: number; - sampleSizeState: number; - interceptedWarnings?: SearchResponseWarning[]; - onUpdateRowsPerPage?: (rowsPerPage?: number) => void; -} - -export type DocTableEmbeddableSearchProps = Omit< - DocTableEmbeddableProps, - 'sampleSizeState' | 'isEsqlMode' ->; - -const DocTableWrapperMemoized = memo(DocTableWrapper); - -export const DocTableEmbeddable = (props: DocTableEmbeddableProps) => { - const onUpdateRowsPerPage = props.onUpdateRowsPerPage; - const tableWrapperRef = useRef(null); - const { - curPageIndex, - pageSize, - totalPages, - startIndex, - hasNextPage, - changePageIndex, - changePageSize, - } = usePager({ - initialPageSize: - typeof props.rowsPerPageState === 'number' && props.rowsPerPageState > 0 - ? Math.min(props.rowsPerPageState, MAX_ROWS_PER_PAGE_OPTION) - : 50, - totalItems: props.rows.length, - }); - const showPagination = totalPages !== 0; - - const scrollTop = useCallback(() => { - if (tableWrapperRef.current) { - tableWrapperRef.current.scrollTo(0, 0); - } - }, []); - - const pageOfItems = useMemo( - () => props.rows.slice(startIndex, pageSize + startIndex), - [pageSize, startIndex, props.rows] - ); - - const onPageChange = useCallback( - (page: number) => { - scrollTop(); - changePageIndex(page); - }, - [changePageIndex, scrollTop] - ); - - const onPageSizeChange = useCallback( - (size: number) => { - scrollTop(); - changePageSize(size); - onUpdateRowsPerPage?.(size); // to update `rowsPerPage` input param for the embeddable - }, - [changePageSize, scrollTop, onUpdateRowsPerPage] - ); - - const shouldShowLimitedResultsWarning = useMemo( - () => !hasNextPage && props.totalHitCount && props.rows.length < props.totalHitCount, - [hasNextPage, props.rows.length, props.totalHitCount] - ); - - const renderDocTable = useCallback( - (renderProps: DocTableRenderProps) => { - return ( -
- - {renderProps.renderHeader()} - {renderProps.renderRows(pageOfItems)} -
-
- ); - }, - [pageOfItems] - ); - - return ( - - - - ) : undefined - } - append={ - showPagination ? ( - - ) : undefined - } - > - - - ); -}; diff --git a/src/plugins/discover/public/components/doc_table/doc_table_infinite.tsx b/src/plugins/discover/public/components/doc_table/doc_table_infinite.tsx deleted file mode 100644 index 5a667ea6f70d4..0000000000000 --- a/src/plugins/discover/public/components/doc_table/doc_table_infinite.tsx +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the "Elastic License - * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side - * Public License v 1"; you may not use this file except in compliance with, at - * your election, the "Elastic License 2.0", the "GNU Affero General Public - * License v3.0 only", or the "Server Side Public License, v 1". - */ - -import React, { Fragment, memo, useCallback, useEffect, useRef, useState } from 'react'; -import './index.scss'; -import { FormattedMessage } from '@kbn/i18n-react'; -import { debounce } from 'lodash'; -import { EuiButtonEmpty } from '@elastic/eui'; -import { DocTableProps, DocTableRenderProps, DocTableWrapper } from './doc_table_wrapper'; -import { SkipBottomButton } from '../../application/main/components/skip_bottom_button'; -import { shouldLoadNextDocPatch } from './utils/should_load_next_doc_patch'; -import { useDiscoverServices } from '../../hooks/use_discover_services'; -import { getAllowedSampleSize } from '../../utils/get_allowed_sample_size'; -import { useAppStateSelector } from '../../application/main/state_management/discover_app_state_container'; - -const FOOTER_PADDING = { padding: 0 }; - -const DocTableWrapperMemoized = memo(DocTableWrapper); - -interface DocTableInfiniteContentProps extends DocTableRenderProps { - limit: number; - onSetMaxLimit: () => void; - onBackToTop: () => void; -} - -const DocTableInfiniteContent = ({ - rows, - columnLength, - limit, - onSkipBottomButtonClick, - renderHeader, - renderRows, - onSetMaxLimit, - onBackToTop, -}: DocTableInfiniteContentProps) => { - const { uiSettings } = useDiscoverServices(); - const sampleSize = useAppStateSelector((state) => - getAllowedSampleSize(state.sampleSize, uiSettings) - ); - - const onSkipBottomButton = useCallback(() => { - onSetMaxLimit(); - onSkipBottomButtonClick(); - }, [onSetMaxLimit, onSkipBottomButtonClick]); - - return ( - - - - {renderHeader()} - {renderRows(rows.slice(0, limit))} - - - - - -
- {rows.length === sampleSize ? ( -
- - - - -
- ) : ( - - ​ - - )} -
-
- ); -}; - -export const DocTableInfinite = (props: DocTableProps) => { - const tableWrapperRef = useRef(null); - const [limit, setLimit] = useState(50); - - /** - * depending on which version of Discover is displayed, different elements are scrolling - * and have therefore to be considered for calculation of infinite scrolling - */ - useEffect(() => { - // After mounting table wrapper should be initialized - const scrollDiv = tableWrapperRef.current as HTMLDivElement; - const scrollMobileElem = document.documentElement; - - const scheduleCheck = debounce(() => { - const isMobileView = document.getElementsByClassName('dscSidebar__mobile').length > 0; - - const usedScrollDiv = isMobileView ? scrollMobileElem : scrollDiv; - if (shouldLoadNextDocPatch(usedScrollDiv)) { - setLimit((prevLimit) => prevLimit + 50); - } - }, 50); - - scrollDiv.addEventListener('scroll', scheduleCheck); - window.addEventListener('scroll', scheduleCheck); - - scheduleCheck(); - - return () => { - scrollDiv.removeEventListener('scroll', scheduleCheck); - window.removeEventListener('scroll', scheduleCheck); - }; - }, []); - - const onBackToTop = useCallback(() => { - const isMobileView = document.getElementsByClassName('dscSidebar__mobile').length > 0; - const focusElem = document.querySelector('.dscSkipButton') as HTMLElement; - focusElem.focus(); - - // Only the desktop one needs to target a specific container - if (!isMobileView && tableWrapperRef.current) { - tableWrapperRef.current.scrollTo(0, 0); - } else if (window) { - window.scrollTo(0, 0); - } - }, []); - - const setMaxLimit = useCallback(() => setLimit(props.rows.length), [props.rows.length]); - - const renderDocTable = useCallback( - (tableProps: DocTableRenderProps) => ( - - ), - [limit, onBackToTop, setMaxLimit] - ); - - return ; -}; diff --git a/src/plugins/discover/public/components/doc_table/doc_table_wrapper.test.tsx b/src/plugins/discover/public/components/doc_table/doc_table_wrapper.test.tsx deleted file mode 100644 index fbbe460320cdb..0000000000000 --- a/src/plugins/discover/public/components/doc_table/doc_table_wrapper.test.tsx +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the "Elastic License - * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side - * Public License v 1"; you may not use this file except in compliance with, at - * your election, the "Elastic License 2.0", the "GNU Affero General Public - * License v3.0 only", or the "Server Side Public License, v 1". - */ - -import React from 'react'; -import { EuiIcon, EuiLoadingSpinner } from '@elastic/eui'; -import { findTestSubject, mountWithIntl } from '@kbn/test-jest-helpers'; -import { dataViewMock } from '@kbn/discover-utils/src/__mocks__'; -import { DocTableWrapper, DocTableWrapperProps } from './doc_table_wrapper'; -import { discoverServiceMock } from '../../__mocks__/services'; -import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public'; -import { buildDataTableRecord } from '@kbn/discover-utils'; -import type { EsHitRecord } from '@kbn/discover-utils/types'; - -describe('Doc table component', () => { - const mountComponent = (customProps?: Partial) => { - const props = { - columns: ['_source'], - dataView: dataViewMock, - rows: [ - { - _index: 'mock_index', - _id: '1', - _score: 1, - fields: [ - { - timestamp: '2020-20-01T12:12:12.123', - }, - ], - _source: { message: 'mock_message', bytes: 20 }, - } as EsHitRecord, - ].map((row) => buildDataTableRecord(row, dataViewMock)), - sort: [['order_date', 'desc']], - isLoading: false, - searchDescription: '', - onAddColumn: () => {}, - onFilter: () => {}, - onMoveColumn: () => {}, - onRemoveColumn: () => {}, - onSort: () => {}, - useNewFieldsApi: true, - dataTestSubj: 'discoverDocTable', - render: () => { - return
mock
; - }, - ...(customProps || {}), - }; - - return mountWithIntl( - - - - ); - }; - - it('should render infinite table correctly', () => { - const component = mountComponent(); - expect(findTestSubject(component, 'discoverDocTable').exists()).toBeTruthy(); - expect(findTestSubject(component, 'docTable').exists()).toBeTruthy(); - expect(component.find('.kbnDocTable__error').exists()).toBeFalsy(); - }); - - it('should render error fallback if rows array is empty', () => { - const component = mountComponent({ rows: [], isLoading: false }); - expect(findTestSubject(component, 'discoverDocTable').exists()).toBeTruthy(); - expect(findTestSubject(component, 'docTable').exists()).toBeFalsy(); - expect(component.find('.kbnDocTable__error').find(EuiIcon).exists()).toBeTruthy(); - }); - - it('should render loading indicator', () => { - const component = mountComponent({ rows: [], isLoading: true }); - expect(findTestSubject(component, 'discoverDocTable').exists()).toBeTruthy(); - expect(findTestSubject(component, 'docTable').exists()).toBeFalsy(); - expect(component.find('.kbnDocTable__error').find(EuiLoadingSpinner).exists()).toBeTruthy(); - }); -}); diff --git a/src/plugins/discover/public/components/doc_table/doc_table_wrapper.tsx b/src/plugins/discover/public/components/doc_table/doc_table_wrapper.tsx deleted file mode 100644 index b9fb8b6681e20..0000000000000 --- a/src/plugins/discover/public/components/doc_table/doc_table_wrapper.tsx +++ /dev/null @@ -1,253 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the "Elastic License - * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side - * Public License v 1"; you may not use this file except in compliance with, at - * your election, the "Elastic License 2.0", the "GNU Affero General Public - * License v3.0 only", or the "Server Side Public License, v 1". - */ - -import React, { forwardRef, useCallback, useMemo } from 'react'; -import { EuiIcon, EuiLoadingSpinner, EuiSpacer, EuiText } from '@elastic/eui'; -import type { DataView, DataViewField } from '@kbn/data-views-plugin/public'; -import type { SortOrder } from '@kbn/saved-search-plugin/public'; -import { FormattedMessage } from '@kbn/i18n-react'; -import { Filter } from '@kbn/es-query'; -import type { DataTableRecord } from '@kbn/discover-utils/types'; -import { SHOW_MULTIFIELDS, getShouldShowFieldHandler } from '@kbn/discover-utils'; -import type { DocViewFilterFn } from '@kbn/unified-doc-viewer/types'; -import { TableHeader } from './components/table_header/table_header'; -import { TableRow } from './components/table_row'; -import { useDiscoverServices } from '../../hooks/use_discover_services'; - -export interface DocTableProps { - /** - * Rows of classic table - */ - rows: DataTableRecord[]; - /** - * Columns of classic table - */ - columns: string[]; - /** - * Current DataView - */ - dataView: DataView; - /** - * Current sorting - */ - sort: string[][]; - /** - * New fields api switch - */ - useNewFieldsApi: boolean; - /** - * Current search description - */ - searchDescription?: string; - /** - * Current shared item title - */ - sharedItemTitle?: string; - /** - * Current data test subject - */ - dataTestSubj: string; - /** - * Loading state - */ - isLoading: boolean; - /** - * Filters applied by embeddalbe - */ - filters?: Filter[]; - /** - * Flag which identifies if Discover operates - * in ES|QL mode - */ - isEsqlMode?: boolean; - /** - * Saved search id - */ - savedSearchId?: string; - /** - * Filter callback - */ - onFilter?: DocViewFilterFn; - /** - * Sorting callback - */ - onSort?: (sort: string[][]) => void; - /** - * Add columns callback - */ - onAddColumn?: (column: string) => void; - /** - * Reordering column callback - */ - onMoveColumn?: (columns: string, newIdx: number) => void; - /** - * Remove column callback - */ - onRemoveColumn?: (column: string) => void; -} - -export interface DocTableRenderProps { - columnLength: number; - rows: DataTableRecord[]; - renderRows: (row: DataTableRecord[]) => JSX.Element[]; - renderHeader: () => JSX.Element; - onSkipBottomButtonClick: () => void; -} - -export interface DocTableWrapperProps extends DocTableProps { - /** - * Renders Doc table content - */ - render: (params: DocTableRenderProps) => JSX.Element; -} - -const wait = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)); - -export const DocTableWrapper = forwardRef( - ( - { - render, - columns, - filters, - isEsqlMode, - savedSearchId, - rows, - dataView, - onSort, - onAddColumn, - onMoveColumn, - onRemoveColumn, - sort, - onFilter, - useNewFieldsApi, - searchDescription, - sharedItemTitle, - dataTestSubj, - isLoading, - }: DocTableWrapperProps, - ref - ) => { - const { uiSettings } = useDiscoverServices(); - const showMultiFields = useMemo(() => uiSettings.get(SHOW_MULTIFIELDS, false), [uiSettings]); - - const onSkipBottomButtonClick = useCallback(async () => { - // delay scrolling to after the rows have been rendered - const bottomMarker = document.getElementById('discoverBottomMarker'); - - while (rows.length !== document.getElementsByClassName('kbnDocTable__row').length) { - await wait(50); - } - bottomMarker!.focus(); - await wait(50); - bottomMarker!.blur(); - }, [rows]); - - const shouldShowFieldHandler = useMemo( - () => - getShouldShowFieldHandler( - dataView.fields.map((field: DataViewField) => field.name), - dataView, - showMultiFields - ), - [dataView, showMultiFields] - ); - - const renderHeader = useCallback( - () => ( - - ), - [columns, dataView, onMoveColumn, onRemoveColumn, onSort, sort] - ); - - const renderRows = useCallback( - (rowsToRender: DataTableRecord[]) => { - return rowsToRender.map((current) => ( - - )); - }, - [ - columns, - filters, - savedSearchId, - onFilter, - dataView, - useNewFieldsApi, - shouldShowFieldHandler, - onAddColumn, - onRemoveColumn, - isEsqlMode, - rows, - ] - ); - - return ( -
} - > - {rows.length !== 0 && - render({ - columnLength: columns.length, - rows, - onSkipBottomButtonClick, - renderHeader, - renderRows, - })} - {!rows.length && ( -
- - {isLoading ? ( - <> - - - - - ) : ( - <> - - - - - )} - -
- )} -
- ); - } -); diff --git a/src/plugins/discover/public/components/doc_table/index.scss b/src/plugins/discover/public/components/doc_table/index.scss deleted file mode 100644 index 3663d807851c4..0000000000000 --- a/src/plugins/discover/public/components/doc_table/index.scss +++ /dev/null @@ -1,2 +0,0 @@ -@import 'doc_table'; -@import 'components/index'; diff --git a/src/plugins/discover/public/components/doc_table/utils/row_formatter.scss b/src/plugins/discover/public/components/doc_table/utils/row_formatter.scss deleted file mode 100644 index ede39feed30b6..0000000000000 --- a/src/plugins/discover/public/components/doc_table/utils/row_formatter.scss +++ /dev/null @@ -1,7 +0,0 @@ -// Special handling for images coming from the image field formatter -// See discover_grid.scss for more explanation on those values -.rowFormatter__value img { - vertical-align: middle; - max-height: lineHeightFromBaseline(2) !important; - max-width: ($euiSizeXXL * 12.5) !important; -} diff --git a/src/plugins/discover/public/components/doc_table/utils/row_formatter.test.ts b/src/plugins/discover/public/components/doc_table/utils/row_formatter.test.ts deleted file mode 100644 index d7cb720b78814..0000000000000 --- a/src/plugins/discover/public/components/doc_table/utils/row_formatter.test.ts +++ /dev/null @@ -1,313 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the "Elastic License - * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side - * Public License v 1"; you may not use this file except in compliance with, at - * your election, the "Elastic License 2.0", the "GNU Affero General Public - * License v3.0 only", or the "Server Side Public License, v 1". - */ - -import ReactDOM from 'react-dom/server'; -import { formatRow, formatTopLevelObject } from './row_formatter'; -import { DataView } from '@kbn/data-views-plugin/public'; -import { fieldFormatsMock } from '@kbn/field-formats-plugin/common/mocks'; -import { DiscoverServices } from '../../../build_services'; -import { stubbedSavedObjectIndexPattern } from '@kbn/data-plugin/common/stubs'; -import { buildDataTableRecord } from '@kbn/discover-utils'; - -describe('Row formatter', () => { - let services: DiscoverServices; - - const createIndexPattern = () => { - const id = 'my-index'; - const { - type, - version, - attributes: { timeFieldName, fields, title }, - } = stubbedSavedObjectIndexPattern(id); - - return new DataView({ - spec: { id, type, version, timeFieldName, fields: JSON.parse(fields), title }, - fieldFormats: fieldFormatsMock, - shortDotsEnable: false, - metaFields: ['_id', '_type', '_score'], - }); - }; - - const dataView = createIndexPattern(); - const rawHit = { - _id: 'a', - _index: 'foo', - _score: 1, - _source: { - foo: 'bar', - number: 42, - hello: '

World

', - also: 'with "quotes" or \'single quotes\'', - }, - }; - const hit = buildDataTableRecord(rawHit, dataView); - - const shouldShowField = (fieldName: string) => - dataView.fields.getAll().some((fld) => fld.name === fieldName); - - beforeEach(() => { - services = { - fieldFormats: { - getDefaultInstance: jest.fn(() => ({ convert: (value: unknown) => value })), - getFormatterForField: jest.fn(() => ({ convert: (value: unknown) => value })), - }, - } as unknown as DiscoverServices; - }); - - it('formats document properly', () => { - expect(formatRow(hit, dataView, shouldShowField, 100, services.fieldFormats)) - .toMatchInlineSnapshot(` - World", - "hello", - ], - Array [ - "number", - 42, - "number", - ], - Array [ - "_id", - "a", - "_id", - ], - Array [ - "_score", - 1, - "_score", - ], - ] - } - /> - `); - }); - - it('limits number of rendered items', () => { - services = { - uiSettings: { - get: () => 1, - }, - fieldFormats: { - getDefaultInstance: jest.fn(() => ({ convert: (value: unknown) => value })), - getFormatterForField: jest.fn(() => ({ convert: (value: unknown) => value })), - }, - } as unknown as DiscoverServices; - expect(formatRow(hit, dataView, () => false, 1, services.fieldFormats)).toMatchInlineSnapshot(` - - `); - }); - - it('formats document with highlighted fields first', () => { - const highLightHit = buildDataTableRecord( - { ...rawHit, highlight: { number: ['42'] } }, - dataView - ); - - expect(formatRow(highLightHit, dataView, shouldShowField, 100, services.fieldFormats)) - .toMatchInlineSnapshot(` - World", - "hello", - ], - Array [ - "_id", - "a", - "_id", - ], - Array [ - "_score", - 1, - "_score", - ], - ] - } - /> - `); - }); - - it('formats top level objects using formatter', () => { - dataView.getFieldByName = jest.fn().mockReturnValue({ - name: 'subfield', - }); - dataView.getFormatterForField = jest.fn().mockReturnValue({ - convert: () => 'formatted', - }); - expect( - formatTopLevelObject( - { - fields: { - 'object.value': [5, 10], - }, - }, - { - 'object.value': [5, 10], - getByName: jest.fn(), - }, - dataView, - 100 - ) - ).toMatchInlineSnapshot(` - - `); - }); - - it('formats top level objects in alphabetical order', () => { - dataView.getFieldByName = jest.fn().mockReturnValue({ - name: 'subfield', - }); - dataView.getFormatterForField = jest.fn().mockReturnValue({ - convert: () => 'formatted', - }); - const formatted = ReactDOM.renderToStaticMarkup( - formatTopLevelObject( - { fields: { 'a.zzz': [100], 'a.ccc': [50] } }, - { 'a.zzz': [100], 'a.ccc': [50], getByName: jest.fn() }, - dataView, - 100 - ) - ); - expect(formatted.indexOf('
a.ccc:
')).toBeLessThan(formatted.indexOf('
a.zzz:
')); - }); - - it('formats top level objects with subfields and highlights', () => { - dataView.getFieldByName = jest.fn().mockReturnValue({ - name: 'subfield', - }); - dataView.getFormatterForField = jest.fn().mockReturnValue({ - convert: () => 'formatted', - }); - expect( - formatTopLevelObject( - { - fields: { - 'object.value': [5, 10], - 'object.keys': ['a', 'b'], - }, - highlight: { - 'object.keys': 'a', - }, - }, - { - 'object.value': [5, 10], - 'object.keys': ['a', 'b'], - getByName: jest.fn(), - }, - dataView, - 100 - ) - ).toMatchInlineSnapshot(` - - `); - }); - - it('formats top level objects, converting unknown fields to string', () => { - dataView.getFieldByName = jest.fn(); - dataView.getFormatterForField = jest.fn(); - expect( - formatTopLevelObject( - { - fields: { - 'object.value': [5, 10], - }, - }, - { - 'object.value': [5, 10], - getByName: jest.fn(), - }, - dataView, - 100 - ) - ).toMatchInlineSnapshot(` - - `); - }); -}); diff --git a/src/plugins/discover/public/components/doc_table/utils/row_formatter.tsx b/src/plugins/discover/public/components/doc_table/utils/row_formatter.tsx deleted file mode 100644 index ec33f5c16be09..0000000000000 --- a/src/plugins/discover/public/components/doc_table/utils/row_formatter.tsx +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the "Elastic License - * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side - * Public License v 1"; you may not use this file except in compliance with, at - * your election, the "Elastic License 2.0", the "GNU Affero General Public - * License v3.0 only", or the "Server Side Public License, v 1". - */ - -import React, { Fragment } from 'react'; -import type { DataView } from '@kbn/data-views-plugin/public'; -import { FieldFormatsStart } from '@kbn/field-formats-plugin/public'; -import type { - DataTableRecord, - ShouldShowFieldInTableHandler, - FormattedHit, -} from '@kbn/discover-utils/types'; -import { formatHit } from '@kbn/discover-utils'; - -import './row_formatter.scss'; - -interface Props { - defPairs: FormattedHit; -} -const TemplateComponent = ({ defPairs }: Props) => { - return ( -
- {defPairs.map((pair, idx) => ( - -
- {pair[0]} - {!!pair[1] && ':'} -
-
{' '} - - ))} -
- ); -}; - -export const formatRow = ( - hit: DataTableRecord, - dataView: DataView, - shouldShowFieldHandler: ShouldShowFieldInTableHandler, - maxEntries: number, - fieldFormats: FieldFormatsStart -) => { - const pairs = formatHit(hit, dataView, shouldShowFieldHandler, maxEntries, fieldFormats); - return ; -}; - -export const formatTopLevelObject = ( - // eslint-disable-next-line @typescript-eslint/no-explicit-any - row: Record, - // eslint-disable-next-line @typescript-eslint/no-explicit-any - fields: Record, - dataView: DataView, - maxEntries: number -) => { - const highlights = row.highlight ?? {}; - const highlightPairs: FormattedHit = []; - const sourcePairs: FormattedHit = []; - const sorted = Object.entries(fields).sort(([keyA], [keyB]) => keyA.localeCompare(keyB)); - sorted.forEach(([key, values]) => { - const field = dataView.getFieldByName(key); - const displayKey = fields.getByName ? fields.getByName(key)?.displayName : undefined; - const formatter = field - ? dataView.getFormatterForField(field) - : { convert: (v: unknown, ..._: unknown[]) => String(v) }; - if (!values.map) return; - const formatted = values - .map((val: unknown) => - formatter.convert(val, 'html', { - field, - hit: row, - }) - ) - .join(', '); - const pairs = highlights[key] ? highlightPairs : sourcePairs; - pairs.push([displayKey ? displayKey : key, formatted, key]); - }); - return ; -}; diff --git a/src/plugins/discover/public/components/doc_table/utils/should_load_next_doc_patch.test.ts b/src/plugins/discover/public/components/doc_table/utils/should_load_next_doc_patch.test.ts deleted file mode 100644 index 25d5ef59c5f4e..0000000000000 --- a/src/plugins/discover/public/components/doc_table/utils/should_load_next_doc_patch.test.ts +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the "Elastic License - * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side - * Public License v 1"; you may not use this file except in compliance with, at - * your election, the "Elastic License 2.0", the "GNU Affero General Public - * License v3.0 only", or the "Server Side Public License, v 1". - */ - -import { shouldLoadNextDocPatch } from './should_load_next_doc_patch'; - -describe('shouldLoadNextDocPatch', () => { - test('next patch should not be loaded', () => { - const scrollingDomEl = { - scrollHeight: 500, - scrollTop: 100, - clientHeight: 100, - } as HTMLElement; - - expect(shouldLoadNextDocPatch(scrollingDomEl)).toBeFalsy(); - }); - - test('next patch should be loaded', () => { - const scrollingDomEl = { - scrollHeight: 500, - scrollTop: 350, - clientHeight: 100, - } as HTMLElement; - - expect(shouldLoadNextDocPatch(scrollingDomEl)).toBeTruthy(); - }); - - test("next patch should be loaded even there's a decimal scroll height", () => { - const scrollingDomEl = { - scrollHeight: 500, - scrollTop: 350.34234234, - clientHeight: 100, - } as HTMLElement; - - expect(shouldLoadNextDocPatch(scrollingDomEl)).toBeTruthy(); - }); -}); diff --git a/src/plugins/discover/public/components/doc_table/utils/should_load_next_doc_patch.ts b/src/plugins/discover/public/components/doc_table/utils/should_load_next_doc_patch.ts deleted file mode 100644 index cfb4f93a2adb5..0000000000000 --- a/src/plugins/discover/public/components/doc_table/utils/should_load_next_doc_patch.ts +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the "Elastic License - * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side - * Public License v 1"; you may not use this file except in compliance with, at - * your election, the "Elastic License 2.0", the "GNU Affero General Public - * License v3.0 only", or the "Server Side Public License, v 1". - */ - -// use a buffer to start rendering more documents before the user completely scrolles down -const verticalScrollBuffer = 100; - -/** - * Helper function to determine if the next patch of 50 documents should be loaded - */ -export function shouldLoadNextDocPatch(domEl: HTMLElement) { - // the height of the scrolling div, including content not visible on the screen due to overflow. - const scrollHeight = domEl.scrollHeight; - // the number of pixels that the div is is scrolled vertically - const scrollTop = domEl.scrollTop; - // the inner height of the scrolling div, excluding content that's visible on the screen - const clientHeight = domEl.clientHeight; - - const consumedHeight = scrollTop + clientHeight; - const remainingHeight = scrollHeight - consumedHeight; - return remainingHeight < verticalScrollBuffer; -} diff --git a/src/plugins/discover/public/components/view_mode_toggle/view_mode_toggle.tsx b/src/plugins/discover/public/components/view_mode_toggle/view_mode_toggle.tsx index 43960f98ea2b8..5b77a184d9253 100644 --- a/src/plugins/discover/public/components/view_mode_toggle/view_mode_toggle.tsx +++ b/src/plugins/discover/public/components/view_mode_toggle/view_mode_toggle.tsx @@ -11,7 +11,7 @@ import React, { useMemo, useEffect, useState, type ReactElement, useCallback } f import { EuiFlexGroup, EuiFlexItem, EuiTab, EuiTabs, useEuiTheme } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; import { css } from '@emotion/react'; -import { isLegacyTableEnabled, SHOW_FIELD_STATISTICS } from '@kbn/discover-utils'; +import { SHOW_FIELD_STATISTICS } from '@kbn/discover-utils'; import type { DataView } from '@kbn/data-views-plugin/common'; import useMountedState from 'react-use/lib/useMountedState'; import { VIEW_MODE } from '../../../common/constants'; @@ -42,10 +42,6 @@ export const DocumentViewModeToggle = ({ dataVisualizer: dataVisualizerService, aiops: aiopsService, } = useDiscoverServices(); - const isLegacy = useMemo( - () => isLegacyTableEnabled({ uiSettings, isEsqlMode }), - [uiSettings, isEsqlMode] - ); const [showPatternAnalysisTab, setShowPatternAnalysisTab] = useState(null); const showFieldStatisticsTab = useMemo( @@ -93,7 +89,7 @@ export const DocumentViewModeToggle = ({ } }, [showPatternAnalysisTab, viewMode, setDiscoverViewMode]); - const includesNormalTabsStyle = viewMode === VIEW_MODE.AGGREGATED_LEVEL || isLegacy; + const includesNormalTabsStyle = viewMode === VIEW_MODE.AGGREGATED_LEVEL; const containerPadding = includesNormalTabsStyle ? euiTheme.size.s : 0; const containerCss = css` diff --git a/src/plugins/discover/public/context_awareness/__mocks__/index.tsx b/src/plugins/discover/public/context_awareness/__mocks__/index.tsx index 8fb4a0bd769aa..ab179a87778a3 100644 --- a/src/plugins/discover/public/context_awareness/__mocks__/index.tsx +++ b/src/plugins/discover/public/context_awareness/__mocks__/index.tsx @@ -25,6 +25,7 @@ import { ProfileProviderServices } from '../profile_providers/profile_provider_s import { ProfilesManager } from '../profiles_manager'; import { DiscoverEBTManager } from '../../services/discover_ebt_manager'; import { createLogsContextServiceMock } from '@kbn/discover-utils/src/__mocks__'; +import { discoverSharedPluginMock } from '@kbn/discover-shared-plugin/public/mocks'; export const createContextAwarenessMocks = ({ shouldRegisterProviders = true, @@ -181,5 +182,6 @@ export const createContextAwarenessMocks = ({ const createProfileProviderServicesMock = () => { return { logsContextService: createLogsContextServiceMock(), + discoverShared: discoverSharedPluginMock.createStartContract(), } as ProfileProviderServices; }; diff --git a/src/plugins/discover/public/context_awareness/profile_providers/security/accessors/create_app_wrapper_accessor.ts b/src/plugins/discover/public/context_awareness/profile_providers/security/accessors/create_app_wrapper_accessor.ts new file mode 100644 index 0000000000000..42382f088b7a3 --- /dev/null +++ b/src/plugins/discover/public/context_awareness/profile_providers/security/accessors/create_app_wrapper_accessor.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", the "GNU Affero General Public License v3.0 only", and the "Server Side + * Public License v 1"; you may not use this file except in compliance with, at + * your election, the "Elastic License 2.0", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +import type { SecuritySolutionAppWrapperFeature } from '@kbn/discover-shared-plugin/public'; + +export const createAppWrapperAccessor = async ( + appWrapperFeature?: SecuritySolutionAppWrapperFeature +) => { + if (!appWrapperFeature) return undefined; + return appWrapperFeature.getWrapper(); +}; diff --git a/src/plugins/discover/public/context_awareness/profile_providers/security/accessors/get_cell_renderer_accessor.test.tsx b/src/plugins/discover/public/context_awareness/profile_providers/security/accessors/get_cell_renderer_accessor.test.tsx new file mode 100644 index 0000000000000..9774bafdb69b3 --- /dev/null +++ b/src/plugins/discover/public/context_awareness/profile_providers/security/accessors/get_cell_renderer_accessor.test.tsx @@ -0,0 +1,57 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the "Elastic License + * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side + * Public License v 1"; you may not use this file except in compliance with, at + * your election, the "Elastic License 2.0", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +import React from 'react'; +import type { SecuritySolutionCellRendererFeature } from '@kbn/discover-shared-plugin/public'; +import { DataGridCellValueElementProps } from '@kbn/unified-data-table'; +import { createCellRendererAccessor } from './get_cell_renderer_accessor'; +import { render } from '@testing-library/react'; + +const cellRendererFeature: SecuritySolutionCellRendererFeature = { + id: 'security-solution-cell-renderer', + getRenderer: async () => (fieldName: string) => { + if (fieldName === 'host.name') { + return (props: DataGridCellValueElementProps) => { + return
{props.columnId}
; + }; + } + }, +}; + +const mockCellProps = { + columnId: 'host.name', + row: { + id: '1', + raw: {}, + flattened: {}, + }, +} as DataGridCellValueElementProps; + +describe('getCellRendererAccessort', () => { + it('should return a cell renderer', async () => { + const getCellRenderer = await createCellRendererAccessor(cellRendererFeature); + expect(getCellRenderer).toBeDefined(); + const CellRenderer = getCellRenderer?.('host.name') as React.FC; + expect(CellRenderer).toBeDefined(); + const { getByTestId } = render(); + expect(getByTestId('cell-render-feature')).toBeVisible(); + expect(getByTestId('cell-render-feature')).toHaveTextContent('host.name'); + }); + + it('should return undefined if cellRendererFeature is not defined', async () => { + const getCellRenderer = await createCellRendererAccessor(); + expect(getCellRenderer).toBeUndefined(); + }); + + it('should return undefined if cellRendererGetter returns undefined', async () => { + const getCellRenderer = await createCellRendererAccessor(cellRendererFeature); + const cellRenderer = getCellRenderer?.('user.name'); + expect(cellRenderer).toBeUndefined(); + }); +}); diff --git a/src/plugins/discover/public/context_awareness/profile_providers/security/accessors/get_cell_renderer_accessor.tsx b/src/plugins/discover/public/context_awareness/profile_providers/security/accessors/get_cell_renderer_accessor.tsx new file mode 100644 index 0000000000000..9f1d18d4a4d90 --- /dev/null +++ b/src/plugins/discover/public/context_awareness/profile_providers/security/accessors/get_cell_renderer_accessor.tsx @@ -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", the "GNU Affero General Public License v3.0 only", and the "Server Side + * Public License v 1"; you may not use this file except in compliance with, at + * your election, the "Elastic License 2.0", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +import React from 'react'; +import type { SecuritySolutionCellRendererFeature } from '@kbn/discover-shared-plugin/public'; +import { DataGridCellValueElementProps } from '@kbn/unified-data-table'; + +export const createCellRendererAccessor = async ( + cellRendererFeature?: SecuritySolutionCellRendererFeature +) => { + if (!cellRendererFeature) return undefined; + const cellRendererGetter = await cellRendererFeature.getRenderer(); + function getCellRenderer(fieldName: string) { + const CellRenderer = cellRendererGetter(fieldName); + if (!CellRenderer) return undefined; + return React.memo(function SecuritySolutionCellRenderer(props: DataGridCellValueElementProps) { + return ; + }); + } + + return getCellRenderer; +}; diff --git a/src/plugins/discover/public/context_awareness/profile_providers/security/security_root_profile/profile.tsx b/src/plugins/discover/public/context_awareness/profile_providers/security/security_root_profile/profile.tsx index 602879125a331..572c86a0e515b 100644 --- a/src/plugins/discover/public/context_awareness/profile_providers/security/security_root_profile/profile.tsx +++ b/src/plugins/discover/public/context_awareness/profile_providers/security/security_root_profile/profile.tsx @@ -7,25 +7,71 @@ * License v3.0 only", or the "Server Side Public License, v 1". */ +import React, { FunctionComponent, PropsWithChildren } from 'react'; +import { DataGridCellValueElementProps } from '@kbn/unified-data-table'; import { RootProfileProvider, SolutionType } from '../../../profiles'; import { ProfileProviderServices } from '../../profile_provider_services'; import { SecurityProfileProviderFactory } from '../types'; +import { createCellRendererAccessor } from '../accessors/get_cell_renderer_accessor'; +import { createAppWrapperAccessor } from '../accessors/create_app_wrapper_accessor'; + +interface SecurityRootProfileContext { + appWrapper?: FunctionComponent>; + getCellRenderer?: ( + fieldName: string + ) => FunctionComponent | undefined; +} + +const EmptyAppWrapper: FunctionComponent> = ({ children }) => <>{children}; export const createSecurityRootProfileProvider: SecurityProfileProviderFactory< - RootProfileProvider -> = (services: ProfileProviderServices) => ({ - profileId: 'security-root-profile', - isExperimental: true, - profile: { - getCellRenderers: (prev) => (params) => ({ - ...prev(params), - }), - }, - resolve: (params) => { - if (params.solutionNavId === SolutionType.Security) { - return { isMatch: true, context: { solutionType: SolutionType.Security } }; - } + RootProfileProvider +> = (services: ProfileProviderServices) => { + const { discoverShared } = services; + const discoverFeaturesRegistry = discoverShared.features.registry; + const cellRendererFeature = discoverFeaturesRegistry.getById('security-solution-cell-renderer'); + const appWrapperFeature = discoverFeaturesRegistry.getById('security-solution-app-wrapper'); + + return { + profileId: 'security-root-profile', + isExperimental: true, + profile: { + getRenderAppWrapper: (PrevWrapper, params) => { + const AppWrapper = params.context.appWrapper ?? EmptyAppWrapper; + return ({ children }) => ( + + {children} + + ); + }, + getCellRenderers: + (prev, { context }) => + (params) => { + const entries = prev(params); + ['host.name', 'user.name', 'source.ip', 'destination.ip'].forEach((fieldName) => { + entries[fieldName] = context.getCellRenderer?.(fieldName) ?? entries[fieldName]; + }); + return entries; + }, + }, + resolve: async (params) => { + if (params.solutionNavId !== SolutionType.Security) { + return { + isMatch: false, + }; + } + + const getAppWrapper = await createAppWrapperAccessor(appWrapperFeature); + const getCellRenderer = await createCellRendererAccessor(cellRendererFeature); - return { isMatch: false }; - }, -}); + return { + isMatch: true, + context: { + solutionType: SolutionType.Security, + appWrapper: getAppWrapper?.(), + getCellRenderer, + }, + }; + }, + }; +}; diff --git a/src/plugins/discover/public/context_awareness/types.ts b/src/plugins/discover/public/context_awareness/types.ts index 51034e97155b6..70e40df3f8f63 100644 --- a/src/plugins/discover/public/context_awareness/types.ts +++ b/src/plugins/discover/public/context_awareness/types.ts @@ -20,7 +20,7 @@ import type { EuiIconType } from '@elastic/eui/src/components/icon/icon'; import type { AggregateQuery, Filter, Query, TimeRange } from '@kbn/es-query'; import type { OmitIndexSignature } from 'type-fest'; import type { Trigger } from '@kbn/ui-actions-plugin/public'; -import type { PropsWithChildren, ReactElement } from 'react'; +import type { FunctionComponent, PropsWithChildren } from 'react'; import type { DocViewFilterFn } from '@kbn/unified-doc-viewer/types'; import type { DiscoverDataSource } from '../../common/data_sources'; import type { DiscoverAppState } from '../application/main/state_management/discover_app_state_container'; @@ -268,7 +268,7 @@ export interface Profile { * @param props The app wrapper props * @returns The custom app wrapper component */ - getRenderAppWrapper: (props: PropsWithChildren<{}>) => ReactElement; + getRenderAppWrapper: FunctionComponent>; /** * Gets default Discover app state that should be used when the profile is resolved diff --git a/src/plugins/discover/public/embeddable/components/saved_search_embeddable_base.tsx b/src/plugins/discover/public/embeddable/components/saved_search_embeddable_base.tsx index deea7aa43c9fc..f723ae1ea7495 100644 --- a/src/plugins/discover/public/embeddable/components/saved_search_embeddable_base.tsx +++ b/src/plugins/discover/public/embeddable/components/saved_search_embeddable_base.tsx @@ -69,7 +69,7 @@ export const SavedSearchEmbeddableBase: FC )} - {children} + {children} {Boolean(append) && {append}} diff --git a/src/plugins/discover/public/embeddable/components/saved_search_grid.tsx b/src/plugins/discover/public/embeddable/components/saved_search_grid.tsx index f6c77dc6cddf5..0a2919fe1540c 100644 --- a/src/plugins/discover/public/embeddable/components/saved_search_grid.tsx +++ b/src/plugins/discover/public/embeddable/components/saved_search_grid.tsx @@ -36,12 +36,13 @@ interface DiscoverGridEmbeddableProps extends Omit void; onRemoveColumn: (column: string) => void; savedSearchId?: string; + enableDocumentViewer: boolean; } export const DiscoverGridMemoized = React.memo(DiscoverGrid); export function DiscoverGridEmbeddable(props: DiscoverGridEmbeddableProps) { - const { interceptedWarnings, ...gridProps } = props; + const { interceptedWarnings, enableDocumentViewer, ...gridProps } = props; const [expandedDoc, setExpandedDoc] = useState(undefined); @@ -131,7 +132,7 @@ export function DiscoverGridEmbeddable(props: DiscoverGridEmbeddableProps) { expandedDoc={expandedDoc} showMultiFields={props.services.uiSettings.get(SHOW_MULTIFIELDS)} maxDocFieldsDisplayed={props.services.uiSettings.get(MAX_DOC_FIELDS_DISPLAYED)} - renderDocumentView={renderDocumentView} + renderDocumentView={enableDocumentViewer ? renderDocumentView : undefined} renderCustomToolbar={renderCustomToolbarWithElements} externalCustomRenderers={cellRenderers} enableComparisonMode diff --git a/src/plugins/discover/public/embeddable/components/search_embeddable_grid_component.tsx b/src/plugins/discover/public/embeddable/components/search_embeddable_grid_component.tsx index 44d3c1685cbfe..8375e72aa34de 100644 --- a/src/plugins/discover/public/embeddable/components/search_embeddable_grid_component.tsx +++ b/src/plugins/discover/public/embeddable/components/search_embeddable_grid_component.tsx @@ -15,7 +15,6 @@ import { DOC_HIDE_TIME_COLUMN_SETTING, SEARCH_FIELDS_FROM_SOURCE, SORT_DEFAULT_ORDER_SETTING, - isLegacyTableEnabled, } from '@kbn/discover-utils'; import { FetchContext, @@ -28,7 +27,6 @@ import { DataGridDensity, DataLoadingState, useColumns } from '@kbn/unified-data import { DocViewFilterFn } from '@kbn/unified-doc-viewer/types'; import { DiscoverGridSettings } from '@kbn/saved-search-plugin/common'; import useObservable from 'react-use/lib/useObservable'; -import { DiscoverDocTableEmbeddable } from '../../components/doc_table/create_doc_table_embeddable'; import { useDiscoverServices } from '../../hooks/use_discover_services'; import { getSortForEmbeddable } from '../../utils'; import { getAllowedSampleSize, getMaxAllowedSampleSize } from '../../utils/get_allowed_sample_size'; @@ -49,16 +47,17 @@ interface SavedSearchEmbeddableComponentProps { }; dataView: DataView; onAddFilter?: DocViewFilterFn; + enableDocumentViewer: boolean; stateManager: SearchEmbeddableStateManager; } -const DiscoverDocTableEmbeddableMemoized = React.memo(DiscoverDocTableEmbeddable); const DiscoverGridEmbeddableMemoized = React.memo(DiscoverGridEmbeddable); export function SearchEmbeddableGridComponent({ api, dataView, onAddFilter, + enableDocumentViewer, stateManager, }: SavedSearchEmbeddableComponentProps) { const discoverServices = useDiscoverServices(); @@ -103,14 +102,6 @@ export function SearchEmbeddableGridComponent({ ); const isEsql = useMemo(() => isEsqlMode(savedSearch), [savedSearch]); - const useLegacyTable = useMemo( - () => - isLegacyTableEnabled({ - uiSettings: discoverServices.uiSettings, - isEsqlMode: isEsql, - }), - [discoverServices, isEsql] - ); const sort = useMemo(() => { return getSortForEmbeddable(savedSearch.sort, dataView, discoverServices.uiSettings, isEsql); @@ -231,19 +222,6 @@ export function SearchEmbeddableGridComponent({ useNewFieldsApi, }; - if (useLegacyTable) { - return ( - - ); - } - return ( ); } diff --git a/src/plugins/discover/public/embeddable/get_search_embeddable_factory.tsx b/src/plugins/discover/public/embeddable/get_search_embeddable_factory.tsx index 37213b17c377d..4117a36a4e048 100644 --- a/src/plugins/discover/public/embeddable/get_search_embeddable_factory.tsx +++ b/src/plugins/discover/public/embeddable/get_search_embeddable_factory.tsx @@ -37,6 +37,7 @@ import { initializeEditApi } from './initialize_edit_api'; import { initializeFetch, isEsqlMode } from './initialize_fetch'; import { initializeSearchEmbeddableApi } from './initialize_search_embeddable_api'; import { + NonPersistedDisplayOptions, SearchEmbeddableApi, SearchEmbeddableRuntimeState, SearchEmbeddableSerializedState, @@ -84,6 +85,11 @@ export const getSearchEmbeddableFactory = ({ initialState?.savedObjectDescription ); + /** By-value SavedSearchComponent package (non-dashboard contexts) state, to adhere to the comparator contract of an embeddable. */ + const nonPersistedDisplayOptions$ = new BehaviorSubject< + NonPersistedDisplayOptions | undefined + >(initialState?.nonPersistedDisplayOptions); + /** All other state */ const blockingError$ = new BehaviorSubject(undefined); const dataLoading$ = new BehaviorSubject(true); @@ -201,6 +207,10 @@ export const getSearchEmbeddableFactory = ({ defaultPanelDescription$, (value) => defaultPanelDescription$.next(value), ], + nonPersistedDisplayOptions: [ + nonPersistedDisplayOptions$, + (value) => nonPersistedDisplayOptions$.next(value), + ], } ); @@ -304,7 +314,18 @@ export const getSearchEmbeddableFactory = ({ diff --git a/src/plugins/discover/public/embeddable/initialize_search_embeddable_api.tsx b/src/plugins/discover/public/embeddable/initialize_search_embeddable_api.tsx index e824fb6fdc021..7b6f20927d347 100644 --- a/src/plugins/discover/public/embeddable/initialize_search_embeddable_api.tsx +++ b/src/plugins/discover/public/embeddable/initialize_search_embeddable_api.tsx @@ -15,8 +15,8 @@ import { ISearchSource, SerializedSearchSourceFields } from '@kbn/data-plugin/co import { DataView } from '@kbn/data-views-plugin/common'; import { DataTableRecord } from '@kbn/discover-utils/types'; import type { - PublishesDataViews, - PublishesUnifiedSearch, + PublishesWritableUnifiedSearch, + PublishesWritableDataViews, StateComparators, } from '@kbn/presentation-publishing'; import { DiscoverGridSettings, SavedSearch } from '@kbn/saved-search-plugin/common'; @@ -71,7 +71,7 @@ export const initializeSearchEmbeddableApi = async ( discoverServices: DiscoverServices; } ): Promise<{ - api: PublishesSavedSearch & PublishesDataViews & Partial; + api: PublishesSavedSearch & PublishesWritableDataViews & Partial; stateManager: SearchEmbeddableStateManager; comparators: StateComparators; cleanup: () => void; @@ -110,6 +110,8 @@ export const initializeSearchEmbeddableApi = async ( searchSource.getField('query') ); + const canEditUnifiedSearch = () => false; + /** This is the state that has to be fetched */ const rows$ = new BehaviorSubject([]); const columnsMeta$ = new BehaviorSubject(undefined); @@ -144,6 +146,25 @@ export const initializeSearchEmbeddableApi = async ( pick(stateManager, EDITABLE_SAVED_SEARCH_KEYS) ); + /** APIs for updating search source properties */ + const setDataViews = (nextDataViews: DataView[]) => { + searchSource.setField('index', nextDataViews[0]); + dataViews.next(nextDataViews); + searchSource$.next(searchSource); + }; + + const setFilters = (filters: Filter[] | undefined) => { + searchSource.setField('filter', filters); + filters$.next(filters); + searchSource$.next(searchSource); + }; + + const setQuery = (query: Query | AggregateQuery | undefined) => { + searchSource.setField('query', query); + query$.next(query); + searchSource$.next(searchSource); + }; + /** Keep the saved search in sync with any state changes */ const syncSavedSearch = combineLatest([onAnyStateChange, searchSource$]) .pipe( @@ -163,10 +184,14 @@ export const initializeSearchEmbeddableApi = async ( syncSavedSearch.unsubscribe(); }, api: { + setDataViews, dataViews, savedSearch$, filters$, + setFilters, query$, + setQuery, + canEditUnifiedSearch, }, stateManager, comparators: { diff --git a/src/plugins/discover/public/embeddable/types.ts b/src/plugins/discover/public/embeddable/types.ts index 1b7ab4a96c2de..64cf5a390da3a 100644 --- a/src/plugins/discover/public/embeddable/types.ts +++ b/src/plugins/discover/public/embeddable/types.ts @@ -15,10 +15,9 @@ import { HasInPlaceLibraryTransforms, PublishesBlockingError, PublishesDataLoading, - PublishesDataViews, PublishesSavedObjectId, - PublishesUnifiedSearch, PublishesWritablePanelTitle, + PublishesWritableUnifiedSearch, PublishingSubject, SerializedTimeRange, SerializedTitles, @@ -30,6 +29,7 @@ import { } from '@kbn/saved-search-plugin/common/types'; import { DataTableColumnsMeta } from '@kbn/unified-data-table'; import { BehaviorSubject } from 'rxjs'; +import { PublishesWritableDataViews } from '@kbn/presentation-publishing/interfaces/publishes_data_views'; import { EDITABLE_SAVED_SEARCH_KEYS } from './constants'; export type SearchEmbeddableState = Pick< @@ -59,6 +59,13 @@ export type SearchEmbeddableSerializedAttributes = Omit< > & Pick; +// These are options that are not persisted in the saved object, but can be used by solutions +// when utilising the SavedSearchComponent package outside of dashboard contexts. +export interface NonPersistedDisplayOptions { + enableDocumentViewer?: boolean; + enableFilters?: boolean; +} + export type SearchEmbeddableSerializedState = SerializedTitles & SerializedTimeRange & Partial> & { @@ -66,6 +73,7 @@ export type SearchEmbeddableSerializedState = SerializedTitles & attributes?: SavedSearchAttributes & { references: SavedSearch['references'] }; // by reference savedObjectId?: string; + nonPersistedDisplayOptions?: NonPersistedDisplayOptions; }; export type SearchEmbeddableRuntimeState = SearchEmbeddableSerializedAttributes & @@ -74,20 +82,20 @@ export type SearchEmbeddableRuntimeState = SearchEmbeddableSerializedAttributes savedObjectTitle?: string; savedObjectId?: string; savedObjectDescription?: string; + nonPersistedDisplayOptions?: NonPersistedDisplayOptions; }; export type SearchEmbeddableApi = DefaultEmbeddableApi< SearchEmbeddableSerializedState, SearchEmbeddableRuntimeState > & - PublishesDataViews & PublishesSavedObjectId & PublishesDataLoading & PublishesBlockingError & PublishesWritablePanelTitle & PublishesSavedSearch & - PublishesDataViews & - PublishesUnifiedSearch & + PublishesWritableDataViews & + PublishesWritableUnifiedSearch & HasInPlaceLibraryTransforms & HasTimeRange & Partial; diff --git a/src/plugins/discover/public/embeddable/utils/serialization_utils.ts b/src/plugins/discover/public/embeddable/utils/serialization_utils.ts index 191a37fe3326e..f193d52054a3c 100644 --- a/src/plugins/discover/public/embeddable/utils/serialization_utils.ts +++ b/src/plugins/discover/public/embeddable/utils/serialization_utils.ts @@ -67,6 +67,7 @@ export const deserializeState = async ({ return { ...savedSearch, ...panelState, + nonPersistedDisplayOptions: serializedState.rawState.nonPersistedDisplayOptions, }; } }; diff --git a/src/plugins/discover/public/index.ts b/src/plugins/discover/public/index.ts index b5d4308010f1f..b54665bdc50a0 100644 --- a/src/plugins/discover/public/index.ts +++ b/src/plugins/discover/public/index.ts @@ -35,6 +35,10 @@ export { type PublishesSavedSearch, type HasTimeRange, type SearchEmbeddableSerializedState, + type SearchEmbeddableRuntimeState, + type SearchEmbeddableApi, + type NonPersistedDisplayOptions, } from './embeddable'; export { loadSharingDataHelpers } from './utils'; export { LogsExplorerTabs, type LogsExplorerTabsProps } from './components/logs_explorer_tabs'; +export type { DiscoverServices } from './build_services'; diff --git a/src/plugins/discover/public/plugin.tsx b/src/plugins/discover/public/plugin.tsx index 0ee80da03a7d1..e29922d05f2c0 100644 --- a/src/plugins/discover/public/plugin.tsx +++ b/src/plugins/discover/public/plugin.tsx @@ -21,14 +21,13 @@ import { import { DEFAULT_APP_CATEGORIES } from '@kbn/core/public'; import { ENABLE_ESQL } from '@kbn/esql-utils'; import { setStateToKbnUrl } from '@kbn/kibana-utils-plugin/public'; -import { SEARCH_EMBEDDABLE_TYPE, TRUNCATE_MAX_HEIGHT } from '@kbn/discover-utils'; +import { SEARCH_EMBEDDABLE_TYPE } from '@kbn/discover-utils'; import { SavedSearchAttributes, SavedSearchType } from '@kbn/saved-search-plugin/common'; import { i18n } from '@kbn/i18n'; import { PLUGIN_ID } from '../common'; import { registerFeature } from './register_feature'; import { buildServices, UrlTracker } from './build_services'; import { ViewSavedSearchAction } from './embeddable/actions/view_saved_search_action'; -import { injectTruncateStyles } from './utils/truncate_styles'; import { initializeKbnUrlTracking } from './utils/initialize_kbn_url_tracking'; import { DiscoverContextAppLocator, @@ -285,7 +284,6 @@ export class DiscoverPlugin plugins.uiActions.addTriggerAction('CONTEXT_MENU_TRIGGER', viewSavedSearchAction); plugins.uiActions.registerTrigger(SEARCH_EMBEDDABLE_CELL_ACTIONS_TRIGGER); plugins.uiActions.registerTrigger(DISCOVER_CELL_ACTIONS_TRIGGER); - injectTruncateStyles(core.uiSettings.get(TRUNCATE_MAX_HEIGHT)); const isEsqlEnabled = core.uiSettings.get(ENABLE_ESQL); diff --git a/src/plugins/discover/public/types.ts b/src/plugins/discover/public/types.ts index 2ef380db98703..4b16e3e58df7c 100644 --- a/src/plugins/discover/public/types.ts +++ b/src/plugins/discover/public/types.ts @@ -42,7 +42,7 @@ import type { AiopsPluginStart } from '@kbn/aiops-plugin/public'; import type { DataVisualizerPluginStart } from '@kbn/data-visualizer-plugin/public'; import type { FieldsMetadataPublicStart } from '@kbn/fields-metadata-plugin/public'; import type { LogsDataAccessPluginStart } from '@kbn/logs-data-access-plugin/public'; -import { DiscoverSharedPublicStart } from '@kbn/discover-shared-plugin/public'; +import type { DiscoverSharedPublicStart } from '@kbn/discover-shared-plugin/public'; import { DiscoverAppLocator } from '../common'; import { DiscoverCustomizationContext } from './customizations'; import { type DiscoverContainerProps } from './components/discover_container'; diff --git a/src/plugins/discover/public/utils/truncate_styles.ts b/src/plugins/discover/public/utils/truncate_styles.ts deleted file mode 100644 index 953144c4b90c3..0000000000000 --- a/src/plugins/discover/public/utils/truncate_styles.ts +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the "Elastic License - * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side - * Public License v 1"; you may not use this file except in compliance with, at - * your election, the "Elastic License 2.0", the "GNU Affero General Public - * License v3.0 only", or the "Server Side Public License, v 1". - */ - -import createCache from '@emotion/cache'; -import { cache } from '@emotion/css'; -import { serializeStyles } from '@emotion/serialize'; - -/** - * The following emotion cache management was introduced here - * https://ntsim.uk/posts/how-to-update-or-remove-global-styles-in-emotion/ - */ -const TRUNCATE_GRADIENT_HEIGHT = 15; -const globalThemeCache = createCache({ key: 'truncation' }); - -const buildStylesheet = (maxHeight: number) => { - if (!maxHeight) { - return [ - ` - .dscTruncateByHeight { - max-height: none; - }`, - ]; - } - return [ - ` - .dscTruncateByHeight { - overflow: hidden; - max-height: ${maxHeight}px !important; - } - .dscTruncateByHeight:before { - top: ${maxHeight - TRUNCATE_GRADIENT_HEIGHT}px; - } - `, - ]; -}; - -export const injectTruncateStyles = (maxHeight: number) => { - const serialized = serializeStyles(buildStylesheet(maxHeight), cache.registered); - if (!globalThemeCache.inserted[serialized.name]) { - globalThemeCache.insert('', serialized, globalThemeCache.sheet, true); - } -}; diff --git a/src/plugins/discover/server/ui_settings.ts b/src/plugins/discover/server/ui_settings.ts index 9d0905b27bfad..7dd84c9728696 100644 --- a/src/plugins/discover/server/ui_settings.ts +++ b/src/plugins/discover/server/ui_settings.ts @@ -23,13 +23,10 @@ import { CONTEXT_DEFAULT_SIZE_SETTING, CONTEXT_STEP_SETTING, CONTEXT_TIE_BREAKER_FIELDS_SETTING, - DOC_TABLE_LEGACY, MODIFY_COLUMNS_ON_SWITCH, SEARCH_FIELDS_FROM_SOURCE, MAX_DOC_FIELDS_DISPLAYED, SHOW_MULTIFIELDS, - TRUNCATE_MAX_HEIGHT, - TRUNCATE_MAX_HEIGHT_DEFAULT_VALUE, SHOW_FIELD_STATISTICS, ROW_HEIGHT_OPTION, } from '@kbn/discover-utils'; @@ -183,42 +180,6 @@ export const getUiSettings: ( category: ['discover'], schema: schema.arrayOf(schema.string()), }, - [DOC_TABLE_LEGACY]: { - name: i18n.translate('discover.advancedSettings.disableDocumentExplorer', { - defaultMessage: 'Document Explorer or classic view', - }), - value: false, - description: i18n.translate('discover.advancedSettings.disableDocumentExplorerDescription', { - defaultMessage: - 'To use the new {documentExplorerDocs} instead of the classic view, turn off this option. ' + - 'The Document Explorer offers better data sorting, resizable columns, and a full screen view.', - values: { - documentExplorerDocs: - `` + - i18n.translate('discover.advancedSettings.documentExplorerLinkText', { - defaultMessage: 'Document Explorer', - }) + - '', - }, - }), - requiresPageReload: true, - category: ['discover'], - schema: schema.boolean(), - metric: { - type: METRIC_TYPE.CLICK, - name: 'discover:useLegacyDataGrid', - }, - deprecation: { - message: i18n.translate( - 'discover.advancedSettings.discover.disableDocumentExplorerDeprecation', - { - defaultMessage: 'This setting is deprecated and will be removed in Kibana 9.0.', - } - ), - docLinksKey: 'discoverSettings', - }, - }, [MODIFY_COLUMNS_ON_SWITCH]: { name: i18n.translate('discover.advancedSettings.discover.modifyColumnsOnSwitchTitle', { defaultMessage: 'Modify columns when changing data views', @@ -316,23 +277,4 @@ export const getUiSettings: ( }), schema: schema.number({ min: -1 }), }, - [TRUNCATE_MAX_HEIGHT]: { - name: i18n.translate('discover.advancedSettings.params.maxCellHeightTitle', { - defaultMessage: 'Maximum cell height in the classic table', - }), - value: TRUNCATE_MAX_HEIGHT_DEFAULT_VALUE, - category: ['discover'], - description: i18n.translate('discover.advancedSettings.params.maxCellHeightText', { - defaultMessage: - 'The maximum height that a cell in a table should occupy. Set to 0 to disable truncation.', - }), - schema: schema.number({ min: 0 }), - requiresPageReload: true, - deprecation: { - message: i18n.translate('discover.advancedSettings.discover.maxCellHeightDeprecation', { - defaultMessage: 'This setting is deprecated and will be removed in Kibana 9.0.', - }), - docLinksKey: 'discoverSettings', - }, - }, }); diff --git a/src/plugins/discover/tsconfig.json b/src/plugins/discover/tsconfig.json index 1bb3aa10acce0..36655983db13a 100644 --- a/src/plugins/discover/tsconfig.json +++ b/src/plugins/discover/tsconfig.json @@ -95,9 +95,9 @@ "@kbn/presentation-containers", "@kbn/observability-ai-assistant-plugin", "@kbn/fields-metadata-plugin", + "@kbn/discover-contextual-components", "@kbn/logs-data-access-plugin", "@kbn/core-lifecycle-browser", - "@kbn/discover-contextual-components", "@kbn/esql-ast", "@kbn/discover-shared-plugin" ], diff --git a/src/plugins/discover_shared/public/index.ts b/src/plugins/discover_shared/public/index.ts index f58a9eaf44f84..4be7a75c817a8 100644 --- a/src/plugins/discover_shared/public/index.ts +++ b/src/plugins/discover_shared/public/index.ts @@ -17,5 +17,9 @@ export type { DiscoverSharedPublicSetup, DiscoverSharedPublicStart } from './typ export type { ObservabilityLogsAIAssistantFeatureRenderDeps, ObservabilityLogsAIAssistantFeature, + SecuritySolutionCellRendererFeature, + SecuritySolutionAppWrapperFeature, DiscoverFeature, -} from './services/discover_features'; + DiscoverFeaturesServiceSetup, + DiscoverFeaturesServiceStart, +} from './services/discover_features/types'; diff --git a/src/plugins/discover_shared/public/services/discover_features/types.ts b/src/plugins/discover_shared/public/services/discover_features/types.ts index cdf78b3335507..a40a4f87a3eb9 100644 --- a/src/plugins/discover_shared/public/services/discover_features/types.ts +++ b/src/plugins/discover_shared/public/services/discover_features/types.ts @@ -7,7 +7,9 @@ * License v3.0 only", or the "Server Side Public License, v 1". */ -import { DataTableRecord } from '@kbn/discover-utils'; +import type { DataTableRecord } from '@kbn/discover-utils'; +import type { FunctionComponent, PropsWithChildren } from 'react'; +import type { DataGridCellValueElementProps } from '@kbn/unified-data-table'; import { FeaturesRegistry } from '../../../common'; /** @@ -38,8 +40,31 @@ export interface ObservabilityCreateSLOFeature { }) => React.ReactNode; } +/** **************** Security Solution ****************/ + +export interface SecuritySolutionCellRendererFeature { + id: 'security-solution-cell-renderer'; + getRenderer: () => Promise< + (fieldName: string) => FunctionComponent | undefined + >; +} + +export interface SecuritySolutionAppWrapperFeature { + id: 'security-solution-app-wrapper'; + getWrapper: () => Promise<() => FunctionComponent>>; +} + +export type SecuritySolutionFeature = + | SecuritySolutionCellRendererFeature + | SecuritySolutionAppWrapperFeature; + +/** ****************************************************************************************/ + // This should be a union of all the available client features. -export type DiscoverFeature = ObservabilityLogsAIAssistantFeature | ObservabilityCreateSLOFeature; +export type DiscoverFeature = + | ObservabilityLogsAIAssistantFeature + | ObservabilityCreateSLOFeature + | SecuritySolutionFeature; /** * Service types diff --git a/src/plugins/discover_shared/tsconfig.json b/src/plugins/discover_shared/tsconfig.json index 9d2b07eb7aae9..d8bda5214c747 100644 --- a/src/plugins/discover_shared/tsconfig.json +++ b/src/plugins/discover_shared/tsconfig.json @@ -13,5 +13,6 @@ "kbn_references": [ "@kbn/discover-utils", "@kbn/core", + "@kbn/unified-data-table", ] } diff --git a/src/plugins/es_ui_shared/static/forms/docs/examples/dynamic_fields.mdx b/src/plugins/es_ui_shared/static/forms/docs/examples/dynamic_fields.mdx index 82516423424f6..e48e5192f189e 100644 --- a/src/plugins/es_ui_shared/static/forms/docs/examples/dynamic_fields.mdx +++ b/src/plugins/es_ui_shared/static/forms/docs/examples/dynamic_fields.mdx @@ -65,7 +65,7 @@ export const DynamicFields = () => { onClick={() => removeItem(item.id)} iconType="minusInCircle" aria-label="Remove item" - style={{ marginTop: '28px' }} + css={{ marginTop: '28px' }} /> @@ -155,7 +155,7 @@ export const DynamicFieldsValidation = () => { onClick={() => removeItem(item.id)} iconType="minusInCircle" aria-label="Remove item" - style={{ marginTop: '28px' }} + css={{ marginTop: '28px' }} /> @@ -218,7 +218,7 @@ export const DynamicFieldsReorder = () => { return ( -
+
@@ -245,7 +245,7 @@ export const DynamicFieldsReorder = () => { onClick={() => removeItem(item.id)} iconType="minusInCircle" aria-label="Remove item" - style={{ marginTop: '28px' }} + css={{ marginTop: '28px' }} /> @@ -273,4 +273,4 @@ export const DynamicFieldsReorder = () => { ); }; -``` \ No newline at end of file +``` diff --git a/src/plugins/es_ui_shared/static/forms/docs/examples/fields_composition.mdx b/src/plugins/es_ui_shared/static/forms/docs/examples/fields_composition.mdx index 7e7cce5e81332..0851440400814 100644 --- a/src/plugins/es_ui_shared/static/forms/docs/examples/fields_composition.mdx +++ b/src/plugins/es_ui_shared/static/forms/docs/examples/fields_composition.mdx @@ -7,8 +7,8 @@ tags: ['forms', 'kibana', 'dev'] date: 2021-04-14 --- -If your form does not have a fix set of fields (single interface) and you need to add/remove fields dynamically, you can leverage the power of field composition with the form lib. It let's you swap fields in your form whenever needed. Any field that **is not in the DOM** is automatically cleared when unmounting and its value won't be returned in the form data. -If you _do_ need to keep a field value, but hide the field in the UI, then you need to use CSS (`
...
`) +If your form does not have a fix set of fields (single interface) and you need to add/remove fields dynamically, you can leverage the power of field composition with the form lib. It let's you swap fields in your form whenever needed. Any field that **is not in the DOM** is automatically cleared when unmounting and its value won't be returned in the form data. +If you _do_ need to keep a field value, but hide the field in the UI, then you need to use CSS (`
...
`) Imagine you're building an app that lets people buy a car online. You want to build a form that lets the user select the model of the car (`sedan`, `golf cart`, `clown mobile`), and based on their selection you'll show a different form for configuring the selected model's options. diff --git a/src/plugins/es_ui_shared/static/forms/docs/examples/serializers_deserializers.mdx b/src/plugins/es_ui_shared/static/forms/docs/examples/serializers_deserializers.mdx index dd3b402e85e3f..3ab849d262db2 100644 --- a/src/plugins/es_ui_shared/static/forms/docs/examples/serializers_deserializers.mdx +++ b/src/plugins/es_ui_shared/static/forms/docs/examples/serializers_deserializers.mdx @@ -90,7 +90,7 @@ export const SerializersAndDeserializers = () => { {/* We don't remove it from the DOM as we would lose the value entered in the field. */} -
+
diff --git a/src/plugins/es_ui_shared/static/forms/hook_form_lib/components/__stories__/use_array_complex.tsx b/src/plugins/es_ui_shared/static/forms/hook_form_lib/components/__stories__/use_array_complex.tsx index f920eb91ea3cc..b777ecd4a85b8 100644 --- a/src/plugins/es_ui_shared/static/forms/hook_form_lib/components/__stories__/use_array_complex.tsx +++ b/src/plugins/es_ui_shared/static/forms/hook_form_lib/components/__stories__/use_array_complex.tsx @@ -43,7 +43,7 @@ const percentageOptions = [ { value: 'percentage_config_1', inputDisplay: ( - + Percentage 1 ), @@ -51,7 +51,7 @@ const percentageOptions = [ { value: 'percentage_config_2', inputDisplay: ( - + Percentage 2 ), @@ -59,7 +59,7 @@ const percentageOptions = [ { value: 'percentage_config_3', inputDisplay: ( - + Percentage 3 ), @@ -70,7 +70,7 @@ const valueOptions = [ { value: 'value_config_1', inputDisplay: ( - + Value 1 ), @@ -78,7 +78,7 @@ const valueOptions = [ { value: 'value_config_2', inputDisplay: ( - + Value 2 ), @@ -86,7 +86,7 @@ const valueOptions = [ { value: 'value_config_3', inputDisplay: ( - + Value 3 ), @@ -188,7 +188,7 @@ const ProcessorsConfigurator: FC<{ ruleType: string }> = ({ ruleType }) => { component={TextField} componentProps={{ euiFieldProps: { - style: { + css: { maxWidth: '180px', }, }, @@ -303,7 +303,7 @@ const percentageOptions = [ { value: 'percentage_config_1', inputDisplay: ( - + Percentage 1 ), @@ -311,7 +311,7 @@ const percentageOptions = [ { value: 'percentage_config_2', inputDisplay: ( - + Percentage 2 ), @@ -319,7 +319,7 @@ const percentageOptions = [ { value: 'percentage_config_3', inputDisplay: ( - + Percentage 3 ), @@ -330,7 +330,7 @@ const valueOptions = [ { value: 'value_config_1', inputDisplay: ( - + Value 1 ), @@ -338,7 +338,7 @@ const valueOptions = [ { value: 'value_config_2', inputDisplay: ( - + Value 2 ), @@ -346,7 +346,7 @@ const valueOptions = [ { value: 'value_config_3', inputDisplay: ( - + Value 3 ), @@ -448,7 +448,7 @@ const ProcessorsConfigurator: FC<{ ruleType: string }> = ({ ruleType }) => { component={TextField} componentProps={{ euiFieldProps: { - style: { + css: { maxWidth: '180px', }, }, diff --git a/src/plugins/es_ui_shared/static/forms/hook_form_lib/components/__stories__/use_array_dynamic_data.tsx b/src/plugins/es_ui_shared/static/forms/hook_form_lib/components/__stories__/use_array_dynamic_data.tsx index 83beef1fc8387..098919fb96c2a 100644 --- a/src/plugins/es_ui_shared/static/forms/hook_form_lib/components/__stories__/use_array_dynamic_data.tsx +++ b/src/plugins/es_ui_shared/static/forms/hook_form_lib/components/__stories__/use_array_dynamic_data.tsx @@ -46,7 +46,7 @@ const percentageOptions = [ { value: 'percentage_config_1', inputDisplay: ( - + Percentage 1 ), @@ -54,7 +54,7 @@ const percentageOptions = [ { value: 'percentage_config_2', inputDisplay: ( - + Percentage 2 ), @@ -62,7 +62,7 @@ const percentageOptions = [ { value: 'percentage_config_3', inputDisplay: ( - + Percentage 3 ), @@ -73,7 +73,7 @@ const valueOptions = [ { value: 'value_config_1', inputDisplay: ( - + Value 1 ), @@ -81,7 +81,7 @@ const valueOptions = [ { value: 'value_config_2', inputDisplay: ( - + Value 2 ), @@ -89,7 +89,7 @@ const valueOptions = [ { value: 'value_config_3', inputDisplay: ( - + Value 3 ), @@ -223,7 +223,7 @@ const ProcessorsConfigurator: FC<{ ruleType: string }> = ({ ruleType }) => { component={TextField} componentProps={{ euiFieldProps: { - style: { + css: { maxWidth: '180px', }, }, @@ -384,7 +384,7 @@ const percentageOptions = [ { value: 'percentage_config_1', inputDisplay: ( - + Percentage 1 ), @@ -392,7 +392,7 @@ const percentageOptions = [ { value: 'percentage_config_2', inputDisplay: ( - + Percentage 2 ), @@ -400,7 +400,7 @@ const percentageOptions = [ { value: 'percentage_config_3', inputDisplay: ( - + Percentage 3 ), @@ -411,7 +411,7 @@ const valueOptions = [ { value: 'value_config_1', inputDisplay: ( - + Value 1 ), @@ -419,7 +419,7 @@ const valueOptions = [ { value: 'value_config_2', inputDisplay: ( - + Value 2 ), @@ -427,7 +427,7 @@ const valueOptions = [ { value: 'value_config_3', inputDisplay: ( - + Value 3 ), @@ -561,7 +561,7 @@ const ProcessorsConfigurator: FC<{ ruleType: string }> = ({ ruleType }) => { component={TextField} componentProps={{ euiFieldProps: { - style: { + css: { maxWidth: '180px', }, }, diff --git a/src/plugins/es_ui_shared/static/forms/hook_form_lib/components/__stories__/use_array_reorder.tsx b/src/plugins/es_ui_shared/static/forms/hook_form_lib/components/__stories__/use_array_reorder.tsx index fb56fded77e3a..807412a33a92b 100644 --- a/src/plugins/es_ui_shared/static/forms/hook_form_lib/components/__stories__/use_array_reorder.tsx +++ b/src/plugins/es_ui_shared/static/forms/hook_form_lib/components/__stories__/use_array_reorder.tsx @@ -87,7 +87,7 @@ export function Reorder() {
@@ -214,7 +214,7 @@ const MyFormComponent = () => {
diff --git a/src/plugins/es_ui_shared/static/forms/hook_form_lib/components/__stories__/use_field_field_types.tsx b/src/plugins/es_ui_shared/static/forms/hook_form_lib/components/__stories__/use_field_field_types.tsx index c24df488ce8a0..18b4cf2fd1d48 100644 --- a/src/plugins/es_ui_shared/static/forms/hook_form_lib/components/__stories__/use_field_field_types.tsx +++ b/src/plugins/es_ui_shared/static/forms/hook_form_lib/components/__stories__/use_field_field_types.tsx @@ -98,7 +98,7 @@ const getPropsForType = (type: FieldType) => { { value: 'warning', inputDisplay: ( - + Warning ), @@ -107,7 +107,7 @@ const getPropsForType = (type: FieldType) => { { value: 'minor', inputDisplay: ( - + Minor ), @@ -115,7 +115,7 @@ const getPropsForType = (type: FieldType) => { { value: 'critical', inputDisplay: ( - + Critical ), diff --git a/src/plugins/esql_datagrid/public/create_datagrid.tsx b/src/plugins/esql_datagrid/public/create_datagrid.tsx index 7df7d84fb8080..4c281519edfb8 100644 --- a/src/plugins/esql_datagrid/public/create_datagrid.tsx +++ b/src/plugins/esql_datagrid/public/create_datagrid.tsx @@ -44,7 +44,7 @@ export const ESQLDataGrid = (props: ESQLDataGridProps) => { }, []); const getWrapper = (children: JSX.Element) => { - return props.fullHeight ?
{children}
: <>{children}; + return props.fullHeight ?
{children}
: <>{children}; }; const deps = value?.[0]; diff --git a/src/plugins/expression_error/public/components/error/error.tsx b/src/plugins/expression_error/public/components/error/error.tsx index fac0ee484fb06..93e10470c320e 100644 --- a/src/plugins/expression_error/public/components/error/error.tsx +++ b/src/plugins/expression_error/public/components/error/error.tsx @@ -40,14 +40,14 @@ export const Error: FC = ({ payload, onClose }) => { return (

{message ? strings.getDescription() : ''}

{message && ( -

+

{message}

)} diff --git a/src/plugins/expression_error/public/components/error/show_debugging.tsx b/src/plugins/expression_error/public/components/error/show_debugging.tsx index ddb9cbeea7a19..49ef1acb90d3d 100644 --- a/src/plugins/expression_error/public/components/error/show_debugging.tsx +++ b/src/plugins/expression_error/public/components/error/show_debugging.tsx @@ -24,7 +24,7 @@ export const ShowDebugging: FC = ({ payload }) => { See Details {expanded && ( -
+
)} diff --git a/src/plugins/expression_repeat_image/public/components/repeat_image_component.tsx b/src/plugins/expression_repeat_image/public/components/repeat_image_component.tsx index bdc28e714cd8f..82b21e60c8453 100644 --- a/src/plugins/expression_repeat_image/public/components/repeat_image_component.tsx +++ b/src/plugins/expression_repeat_image/public/components/repeat_image_component.tsx @@ -94,7 +94,7 @@ export function RepeatImageComponent({ } return ( -
+
{imagesToRender}
); diff --git a/src/plugins/expressions/public/react_expression_renderer/react_expression_renderer.tsx b/src/plugins/expressions/public/react_expression_renderer/react_expression_renderer.tsx index 32c7d85fa5695..eb9bc34d40b3e 100644 --- a/src/plugins/expressions/public/react_expression_renderer/react_expression_renderer.tsx +++ b/src/plugins/expressions/public/react_expression_renderer/react_expression_renderer.tsx @@ -61,7 +61,7 @@ export function ReactExpressionRenderer({
{isEmpty && } {isLoading && ( - + )} {!isLoading && error && renderError?.(error.message, error)}
diff --git a/src/plugins/guided_onboarding/public/components/guide_button_popover.tsx b/src/plugins/guided_onboarding/public/components/guide_button_popover.tsx index 4fa03569756a4..fccfaef00e77f 100644 --- a/src/plugins/guided_onboarding/public/components/guide_button_popover.tsx +++ b/src/plugins/guided_onboarding/public/components/guide_button_popover.tsx @@ -51,7 +51,7 @@ export const GuideButtonPopover = ({ )} - + {description &&

{description}

}
diff --git a/src/plugins/home/public/application/components/recently_accessed.js b/src/plugins/home/public/application/components/recently_accessed.js index e873b5eda5996..be9d8d0ac1923 100644 --- a/src/plugins/home/public/application/components/recently_accessed.js +++ b/src/plugins/home/public/application/components/recently_accessed.js @@ -58,7 +58,7 @@ export class RecentlyAccessed extends Component { for (let i = NUM_LONG_LINKS; i < this.props.recentlyAccessed.length; i++) { dropdownLinks.push(
  • diff --git a/src/plugins/home/public/application/components/tutorial/__snapshots__/instruction_set.test.js.snap b/src/plugins/home/public/application/components/tutorial/__snapshots__/instruction_set.test.js.snap index 5235392121ab0..b11a936807c9f 100644 --- a/src/plugins/home/public/application/components/tutorial/__snapshots__/instruction_set.test.js.snap +++ b/src/plugins/home/public/application/components/tutorial/__snapshots__/instruction_set.test.js.snap @@ -7,7 +7,7 @@ exports[`render 1`] = ` paddingSize="none" > - {this.renderTabs()} + {this.renderTabs()} {this.renderHeader()} diff --git a/src/plugins/image_embeddable/public/components/image_editor/image_editor_flyout.tsx b/src/plugins/image_embeddable/public/components/image_editor/image_editor_flyout.tsx index 1a5ee3bc64e1d..0a680e317dc72 100644 --- a/src/plugins/image_embeddable/public/components/image_editor/image_editor_flyout.tsx +++ b/src/plugins/image_embeddable/public/components/image_editor/image_editor_flyout.tsx @@ -205,7 +205,7 @@ export function ImageEditorFlyout(props: ImageEditorFlyoutProps) {
  • } /> -

    +

    setIsFilePickerOpen(true)} data-test-subj="imageEmbeddableEditorSelectFiles" diff --git a/src/plugins/image_embeddable/public/components/image_viewer/image_viewer.tsx b/src/plugins/image_embeddable/public/components/image_viewer/image_viewer.tsx index 4eb8edc0a0695..ff4b2233a97d3 100644 --- a/src/plugins/image_embeddable/public/components/image_viewer/image_viewer.tsx +++ b/src/plugins/image_embeddable/public/components/image_viewer/image_viewer.tsx @@ -126,7 +126,7 @@ export function ImageViewer({ )} {onClear && ( { } return ( - + {controlComponent} ); diff --git a/src/plugins/inspector/public/views/requests/components/details/clusters_view/clusters_table/__snapshots__/cluster_view.test.tsx.snap b/src/plugins/inspector/public/views/requests/components/details/clusters_view/clusters_table/__snapshots__/cluster_view.test.tsx.snap index e063ccea48cc2..42b8d1a99c1dc 100644 --- a/src/plugins/inspector/public/views/requests/components/details/clusters_view/clusters_table/__snapshots__/cluster_view.test.tsx.snap +++ b/src/plugins/inspector/public/views/requests/components/details/clusters_view/clusters_table/__snapshots__/cluster_view.test.tsx.snap @@ -2,13 +2,13 @@ exports[`render partial should display callout when request timed out 1`] = ` + {clusterDetails.timed_out ? ( - + {host} diff --git a/src/plugins/interactive_setup/public/enrollment_token_form.tsx b/src/plugins/interactive_setup/public/enrollment_token_form.tsx index 65765291fb79a..3cfc7d3fe33a2 100644 --- a/src/plugins/interactive_setup/public/enrollment_token_form.tsx +++ b/src/plugins/interactive_setup/public/enrollment_token_form.tsx @@ -184,7 +184,7 @@ const EnrollmentTokenDetails: FunctionComponent = ( defaultMessage="Connect to" /> - + {token.adr[0]} diff --git a/src/plugins/interactive_setup/public/single_chars_field.tsx b/src/plugins/interactive_setup/public/single_chars_field.tsx index 27bb6ce3e60a0..13af3f1f7ba3f 100644 --- a/src/plugins/interactive_setup/public/single_chars_field.tsx +++ b/src/plugins/interactive_setup/public/single_chars_field.tsx @@ -73,13 +73,13 @@ export const SingleCharsField: FunctionComponent = ({ ); } children.push( - + { inputRefs.current[i] = el; @@ -125,7 +125,7 @@ export const SingleCharsField: FunctionComponent = ({ }} maxLength={1} isInvalid={isInvalid} - style={{ textAlign: 'center' }} + css={{ textAlign: 'center' }} aria-label={i18n.translate('interactiveSetup.singleCharsField.digitLabel', { defaultMessage: 'Digit {index}', values: { index: i + 1 }, diff --git a/src/plugins/kibana_react/public/page_template/no_data_page/action_cards/action_cards.tsx b/src/plugins/kibana_react/public/page_template/no_data_page/action_cards/action_cards.tsx index 3631ae86e1ec3..228e6d5f8cb15 100644 --- a/src/plugins/kibana_react/public/page_template/no_data_page/action_cards/action_cards.tsx +++ b/src/plugins/kibana_react/public/page_template/no_data_page/action_cards/action_cards.tsx @@ -23,7 +23,7 @@ export const ActionCards = ({ actionCards }: ActionCardsProps) => { )); return ( - + {cards} ); diff --git a/src/plugins/kibana_react/public/page_template/no_data_page/no_data_card/__snapshots__/elastic_agent_card.test.tsx.snap b/src/plugins/kibana_react/public/page_template/no_data_page/no_data_card/__snapshots__/elastic_agent_card.test.tsx.snap index 9782a4cf1da65..fdee5059e7876 100644 --- a/src/plugins/kibana_react/public/page_template/no_data_page/no_data_card/__snapshots__/elastic_agent_card.test.tsx.snap +++ b/src/plugins/kibana_react/public/page_template/no_data_page/no_data_card/__snapshots__/elastic_agent_card.test.tsx.snap @@ -27,8 +27,7 @@ exports[`ElasticAgentCard props button 1`] = ` image={ } @@ -78,8 +78,7 @@ exports[`ElasticAgentCard props category 1`] = ` image={ } @@ -129,8 +129,7 @@ exports[`ElasticAgentCard props href 1`] = ` image={ } @@ -185,8 +185,7 @@ exports[`ElasticAgentCard props recommended 1`] = ` image={ } @@ -236,8 +236,7 @@ exports[`ElasticAgentCard renders 1`] = ` image={ } diff --git a/src/plugins/kibana_react/public/page_template/no_data_page/no_data_card/elastic_agent_card.tsx b/src/plugins/kibana_react/public/page_template/no_data_page/no_data_card/elastic_agent_card.tsx index c4849e814edd4..1c8169ac5a732 100644 --- a/src/plugins/kibana_react/public/page_template/no_data_page/no_data_card/elastic_agent_card.tsx +++ b/src/plugins/kibana_react/public/page_template/no_data_page/no_data_card/elastic_agent_card.tsx @@ -43,7 +43,7 @@ export const ElasticAgentCard: FunctionComponent = ({ const image = ( = { type: 'keyword', _meta: { description: 'Non-default value of setting.' }, }, - 'truncate:maxHeight': { - type: 'long', - _meta: { description: 'Non-default value of setting.' }, - }, 'timepicker:timeDefaults': { type: 'keyword', _meta: { description: 'Non-default value of setting.' }, @@ -424,10 +420,6 @@ export const stackManagementSchema: MakeSchemaFrom = { type: 'boolean', _meta: { description: 'Non-default value of setting.' }, }, - 'doc_table:legacy': { - type: 'boolean', - _meta: { description: 'Non-default value of setting.' }, - }, 'discover:modifyColumnsOnSwitch': { type: 'boolean', _meta: { description: 'Non-default value of setting.' }, diff --git a/src/plugins/kibana_usage_collection/server/collectors/management/types.ts b/src/plugins/kibana_usage_collection/server/collectors/management/types.ts index 9796436007357..4c6f17a85914c 100644 --- a/src/plugins/kibana_usage_collection/server/collectors/management/types.ts +++ b/src/plugins/kibana_usage_collection/server/collectors/management/types.ts @@ -30,7 +30,6 @@ export interface UsageStats { 'autocomplete:valueSuggestionMethod': string; 'search:timeout': number; 'visualization:visualize:legacyHeatmapChartsLibrary': boolean; - 'doc_table:legacy': boolean; 'discover:modifyColumnsOnSwitch': boolean; 'discover:searchFieldsFromSource': boolean; 'discover:showFieldStatistics': boolean; @@ -101,7 +100,6 @@ export interface UsageStats { 'fileUpload:maxFileSize': string; 'ml:anomalyDetection:results:enableTimeDefaults': boolean; 'ml:anomalyDetection:results:timeDefaults': string; - 'truncate:maxHeight': number; 'timepicker:timeDefaults': string; 'timepicker:refreshIntervalDefaults': string; 'timepicker:quickRanges': string; diff --git a/src/plugins/presentation_panel/public/panel_component/panel_header/presentation_panel_hover_actions.tsx b/src/plugins/presentation_panel/public/panel_component/panel_header/presentation_panel_hover_actions.tsx index b29563713d365..7954a7f7dfc65 100644 --- a/src/plugins/presentation_panel/public/panel_component/panel_header/presentation_panel_hover_actions.tsx +++ b/src/plugins/presentation_panel/public/panel_component/panel_header/presentation_panel_hover_actions.tsx @@ -393,7 +393,7 @@ export const PresentationPanelHoverActions = ({ notification.execute({ embeddable: api, trigger: panelNotificationTrigger }) } diff --git a/src/plugins/presentation_panel/public/panel_component/panel_header/use_presentation_panel_header_actions.tsx b/src/plugins/presentation_panel/public/panel_component/panel_header/use_presentation_panel_header_actions.tsx index b48a4eca7ae1f..795fd6b566a9b 100644 --- a/src/plugins/presentation_panel/public/panel_component/panel_header/use_presentation_panel_header_actions.tsx +++ b/src/plugins/presentation_panel/public/panel_component/panel_header/use_presentation_panel_header_actions.tsx @@ -167,7 +167,7 @@ export const usePresentationPanelHeaderActions = < notification.execute({ embeddable: api, trigger: panelNotificationTrigger }) } diff --git a/src/plugins/presentation_util/public/components/labs/environment_switch.tsx b/src/plugins/presentation_util/public/components/labs/environment_switch.tsx index 94e71fe432fc5..d8727b4e2dbae 100644 --- a/src/plugins/presentation_util/public/components/labs/environment_switch.tsx +++ b/src/plugins/presentation_util/public/components/labs/environment_switch.tsx @@ -44,13 +44,13 @@ export const EnvironmentSwitch = ({ env, isChecked, onChange, name }: Props) => const canSet = env === 'kibana' ? canSetAdvancedSettings : true; return ( - + @@ -63,7 +63,7 @@ export const EnvironmentSwitch = ({ env, isChecked, onChange, name }: Props) => compressed /> - + diff --git a/src/plugins/presentation_util/public/components/labs/labs_beaker_button.tsx b/src/plugins/presentation_util/public/components/labs/labs_beaker_button.tsx index 1d454050963d9..8da1fe97455a6 100644 --- a/src/plugins/presentation_util/public/components/labs/labs_beaker_button.tsx +++ b/src/plugins/presentation_util/public/components/labs/labs_beaker_button.tsx @@ -34,7 +34,7 @@ export const LabsBeakerButton = ({ solutions, ...props }: Props) => { {overrideCount > 0 ? ( - + {overrideCount} ) : null} diff --git a/src/plugins/saved_objects_management/public/management_section/objects_table/components/flyout.tsx b/src/plugins/saved_objects_management/public/management_section/objects_table/components/flyout.tsx index 4e29f34dedb73..575f13b66b59a 100644 --- a/src/plugins/saved_objects_management/public/management_section/objects_table/components/flyout.tsx +++ b/src/plugins/saved_objects_management/public/management_section/objects_table/components/flyout.tsx @@ -326,7 +326,7 @@ export class FlyoutClass extends Component< ), render: (list: any[]) => { return ( -

      +
        {take(list, 3).map((obj, key) => (
      • {obj.title}
      • ))} diff --git a/src/plugins/telemetry/schema/oss_plugins.json b/src/plugins/telemetry/schema/oss_plugins.json index fe0f599dd6ca1..35e0242b57624 100644 --- a/src/plugins/telemetry/schema/oss_plugins.json +++ b/src/plugins/telemetry/schema/oss_plugins.json @@ -10492,12 +10492,6 @@ "description": "Non-default value of setting." } }, - "truncate:maxHeight": { - "type": "long", - "_meta": { - "description": "Non-default value of setting." - } - }, "timepicker:timeDefaults": { "type": "keyword", "_meta": { @@ -10765,12 +10759,6 @@ "description": "Non-default value of setting." } }, - "doc_table:legacy": { - "type": "boolean", - "_meta": { - "description": "Non-default value of setting." - } - }, "discover:modifyColumnsOnSwitch": { "type": "boolean", "_meta": { diff --git a/src/plugins/telemetry/server/fetcher.ts b/src/plugins/telemetry/server/fetcher.ts index 445f780c07c53..82db03ed08ed5 100644 --- a/src/plugins/telemetry/server/fetcher.ts +++ b/src/plugins/telemetry/server/fetcher.ts @@ -29,9 +29,8 @@ import type { TelemetryCollectionManagerPluginStart } from '@kbn/telemetry-colle import { type PluginInitializerContext, type Logger, - type SavedObjectsClientContract, - SavedObjectsClient, type CoreStart, + type ISavedObjectsRepository, } from '@kbn/core/server'; import { getTelemetryChannelEndpoint } from '../common/telemetry_config'; import { @@ -77,7 +76,7 @@ export class FetcherTask { private readonly subscriptions = new Subscription(); private readonly isOnline$ = new BehaviorSubject(false); // Let's initially assume we are not online private readonly lastReported$ = new BehaviorSubject(0); - private internalRepository?: SavedObjectsClientContract; + private internalRepository?: ISavedObjectsRepository; private telemetryCollectionManager?: TelemetryCollectionManagerPluginStart; constructor(initializerContext: PluginInitializerContext) { @@ -87,9 +86,7 @@ export class FetcherTask { } public start({ savedObjects }: CoreStart, { telemetryCollectionManager }: FetcherTaskDepsStart) { - this.internalRepository = new SavedObjectsClient( - savedObjects.createInternalRepository([TELEMETRY_SAVED_OBJECT_TYPE]) - ); + this.internalRepository = savedObjects.createInternalRepository([TELEMETRY_SAVED_OBJECT_TYPE]); this.telemetryCollectionManager = telemetryCollectionManager; this.subscriptions.add(this.validateConnectivity()); diff --git a/src/plugins/ui_actions_enhanced/public/components/action_wizard/action_wizard.tsx b/src/plugins/ui_actions_enhanced/public/components/action_wizard/action_wizard.tsx index db3a0b8845420..009016a63a906 100644 --- a/src/plugins/ui_actions_enhanced/public/components/action_wizard/action_wizard.tsx +++ b/src/plugins/ui_actions_enhanced/public/components/action_wizard/action_wizard.tsx @@ -187,7 +187,7 @@ const TriggerPicker: React.FC = ({ ), }} - style={{ maxWidth: `80%` }} + css={{ maxWidth: `80%` }} > {triggers.map((trigger) => ( diff --git a/src/plugins/ui_actions_enhanced/public/components/action_wizard/test_data.tsx b/src/plugins/ui_actions_enhanced/public/components/action_wizard/test_data.tsx index cfe7784ec99fd..7b48712ff7d64 100644 --- a/src/plugins/ui_actions_enhanced/public/components/action_wizard/test_data.tsx +++ b/src/plugins/ui_actions_enhanced/public/components/action_wizard/test_data.tsx @@ -263,7 +263,7 @@ export function Demo({ getTriggerInfo={mockGetTriggerInfo} triggers={[VALUE_CLICK_TRIGGER, APPLY_FILTER_TRIGGER, SELECT_RANGE_TRIGGER]} /> -
        +

        Action Factory Id: {state.currentActionFactory?.id}
        Action Factory Config: {JSON.stringify(state.config)}
        diff --git a/src/plugins/ui_actions_enhanced/public/drilldowns/drilldown_manager/components/drilldown_table/drilldown_table.tsx b/src/plugins/ui_actions_enhanced/public/drilldowns/drilldown_manager/components/drilldown_table/drilldown_table.tsx index 1859067212cb9..17c9aa98aa6e1 100644 --- a/src/plugins/ui_actions_enhanced/public/drilldowns/drilldown_manager/components/drilldown_table/drilldown_table.tsx +++ b/src/plugins/ui_actions_enhanced/public/drilldowns/drilldown_manager/components/drilldown_table/drilldown_table.tsx @@ -81,7 +81,7 @@ export const DrilldownTable: React.FC = ({ title={drilldown.error} aria-label={drilldown.error} data-test-subj={`drilldownError-${drilldown.id}`} - style={{ marginLeft: '4px' }} /* a bit of spacing from text */ + css={{ marginLeft: '4px' }} /* a bit of spacing from text */ /> )} diff --git a/src/plugins/ui_actions_enhanced/public/drilldowns/drilldown_manager/components/drilldown_template_table/drilldown_template_table.tsx b/src/plugins/ui_actions_enhanced/public/drilldowns/drilldown_manager/components/drilldown_template_table/drilldown_template_table.tsx index c918dbdef215a..cb23fa2d576d8 100644 --- a/src/plugins/ui_actions_enhanced/public/drilldowns/drilldown_manager/components/drilldown_template_table/drilldown_template_table.tsx +++ b/src/plugins/ui_actions_enhanced/public/drilldowns/drilldown_manager/components/drilldown_template_table/drilldown_template_table.tsx @@ -58,8 +58,8 @@ export const DrilldownTemplateTable: React.FC = ({ name: txtNameColumnTitle, sortable: true, render: (omit, item: DrilldownTemplateTableItem) => ( -
        -
        {item.name}
        +
        +
        {item.name}
        {item.description} diff --git a/src/plugins/ui_actions_enhanced/public/drilldowns/drilldown_manager/components/flyout_frame/flyout_frame.tsx b/src/plugins/ui_actions_enhanced/public/drilldowns/drilldown_manager/components/flyout_frame/flyout_frame.tsx index 246cf5d7362ba..23633a52be35d 100644 --- a/src/plugins/ui_actions_enhanced/public/drilldowns/drilldown_manager/components/flyout_frame/flyout_frame.tsx +++ b/src/plugins/ui_actions_enhanced/public/drilldowns/drilldown_manager/components/flyout_frame/flyout_frame.tsx @@ -45,7 +45,7 @@ export const FlyoutFrame: FC> = ({ {onBack && ( -
        +
        > = ({ )} {!!children && ( - + {tooltip ? ( {children} diff --git a/src/plugins/ui_actions_enhanced/public/drilldowns/drilldown_manager/components/trigger_picker/trigger_picker.tsx b/src/plugins/ui_actions_enhanced/public/drilldowns/drilldown_manager/components/trigger_picker/trigger_picker.tsx index 35bdcbe4d2c9f..1c4653b3e8630 100644 --- a/src/plugins/ui_actions_enhanced/public/drilldowns/drilldown_manager/components/trigger_picker/trigger_picker.tsx +++ b/src/plugins/ui_actions_enhanced/public/drilldowns/drilldown_manager/components/trigger_picker/trigger_picker.tsx @@ -74,7 +74,7 @@ export const TriggerPicker: React.FC = ({ ), }} - style={{ maxWidth: `80%` }} + css={{ maxWidth: `80%` }} > {items.map((trigger) => ( data-test-subj="urlDrilldownAdditionalOptions" > - + { diff --git a/src/plugins/ui_actions_enhanced/public/drilldowns/url_drilldown/components/variable_popover/index.tsx b/src/plugins/ui_actions_enhanced/public/drilldowns/url_drilldown/components/variable_popover/index.tsx index 656ff07623dc5..e308969881429 100644 --- a/src/plugins/ui_actions_enhanced/public/drilldowns/url_drilldown/components/variable_popover/index.tsx +++ b/src/plugins/ui_actions_enhanced/public/drilldowns/url_drilldown/components/variable_popover/index.tsx @@ -74,7 +74,7 @@ export const VariablePopover: React.FC = ({ variables, onSelect, variable }} > {(list, search) => ( -
        +
        {search} {list} {variablesHelpLink && ( 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 5e97ff9cc55da..a3f70c2badc0c 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 @@ -32,31 +32,17 @@ describe('getHeight', () => { test('when using document explorer, returning the available height in the flyout', () => { const monacoMock = getMonacoMock(500, 0); - const height = getHeight(monacoMock, true, DEFAULT_MARGIN_BOTTOM); + const height = getHeight(monacoMock, DEFAULT_MARGIN_BOTTOM); expect(height).toBe(484); - const heightCustom = getHeight(monacoMock, true, 80); + const heightCustom = getHeight(monacoMock, 80); expect(heightCustom).toBe(420); }); 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, DEFAULT_MARGIN_BOTTOM); + const height = getHeight(monacoMock, DEFAULT_MARGIN_BOTTOM); expect(height).toBe(400); }); - - test('when using classic table, its displayed inline without scrolling', () => { - const monacoMock = getMonacoMock(100); - - const height = getHeight(monacoMock, false, DEFAULT_MARGIN_BOTTOM); - expect(height).toBe(1020); - }); - - test('when using classic table, limited height > 500 lines to allow scrolling', () => { - const monacoMock = getMonacoMock(1000); - - const height = getHeight(monacoMock, false, DEFAULT_MARGIN_BOTTOM); - expect(height).toBe(5020); - }); }); 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 514c994e5d423..68619b6048338 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 @@ -8,7 +8,7 @@ */ import { monaco } from '@kbn/monaco'; -import { MAX_LINES_CLASSIC_TABLE, MIN_HEIGHT } from './source'; +import { MIN_HEIGHT } from './source'; // Displayed margin of the tab content to the window bottom export const DEFAULT_MARGIN_BOTTOM = 16; @@ -28,7 +28,6 @@ export function getTabContentAvailableHeight( export function getHeight( editor: monaco.editor.IStandaloneCodeEditor, - useDocExplorer: boolean, decreaseAvailableHeightBy: number ) { const editorElement = editor?.getDomNode(); @@ -36,17 +35,6 @@ export function getHeight( return 0; } - let result; - if (useDocExplorer) { - result = getTabContentAvailableHeight(editorElement, decreaseAvailableHeightBy); - } else { - // takes care of the classic table, display a maximum of 500 lines - // why not display it all? Due to performance issues when the browser needs to render it all - const lineHeight = editor.getOption(monaco.editor.EditorOption.lineHeight); - const lineCount = editor.getModel()?.getLineCount() || 1; - const displayedLineCount = - lineCount > MAX_LINES_CLASSIC_TABLE ? MAX_LINES_CLASSIC_TABLE : lineCount; - result = editor.getTopForLineNumber(displayedLineCount + 1) + lineHeight; - } + const result = getTabContentAvailableHeight(editorElement, decreaseAvailableHeightBy); 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 5b4ba36cd03f1..3bd1137cabccf 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 @@ -17,7 +17,7 @@ import { i18n } from '@kbn/i18n'; import type { DataView } from '@kbn/data-views-plugin/public'; import type { DataTableRecord } from '@kbn/discover-utils/types'; import { ElasticRequestState } from '@kbn/unified-doc-viewer'; -import { isLegacyTableEnabled, SEARCH_FIELDS_FROM_SOURCE } from '@kbn/discover-utils'; +import { SEARCH_FIELDS_FROM_SOURCE } from '@kbn/discover-utils'; import { omit } from 'lodash'; import { getUnifiedDocViewerServices } from '../../plugin'; import { useEsDocSearch } from '../../hooks'; @@ -36,9 +36,6 @@ interface SourceViewerProps { onRefresh: () => void; } -// Ihe number of lines displayed without scrolling used for classic table, which renders the component -// inline limitation was necessary to enable virtualized scrolling, which improves performance -export const MAX_LINES_CLASSIC_TABLE = 500; // Minimum height for the source content to guarantee minimum space when the flyout is scrollable. export const MIN_HEIGHT = 400; @@ -57,10 +54,6 @@ export const DocViewerSource = ({ const [jsonValue, setJsonValue] = useState(''); const { uiSettings } = getUnifiedDocViewerServices(); const useNewFieldsApi = !uiSettings.get(SEARCH_FIELDS_FROM_SOURCE); - const useDocExplorer = !isLegacyTableEnabled({ - uiSettings, - isEsqlMode: Array.isArray(textBasedHits), - }); const [requestState, hit] = useEsDocSearch({ id, index, @@ -75,9 +68,7 @@ export const DocViewerSource = ({ } }, [requestState, hit]); - // setting editor height - // - classic view: based on lines height and count to stretch and fit its content - // - explorer: to fill the available space of the document flyout + // setting editor height to fill the available space of the document flyout useEffect(() => { if (!editor) { return; @@ -88,11 +79,7 @@ export const DocViewerSource = ({ return; } - const height = getHeight( - editor, - useDocExplorer, - decreaseAvailableHeightBy ?? DEFAULT_MARGIN_BOTTOM - ); + const height = getHeight(editor, decreaseAvailableHeightBy ?? DEFAULT_MARGIN_BOTTOM); if (height === 0) { return; } @@ -102,7 +89,7 @@ export const DocViewerSource = ({ } else { setEditorHeight(height); } - }, [editor, jsonValue, useDocExplorer, setEditorHeight, decreaseAvailableHeightBy]); + }, [editor, jsonValue, setEditorHeight, decreaseAvailableHeightBy]); const loadingState = (
        diff --git a/src/plugins/unified_doc_viewer/public/components/doc_viewer_table/legacy/table.test.tsx b/src/plugins/unified_doc_viewer/public/components/doc_viewer_table/legacy/table.test.tsx deleted file mode 100644 index 43f2d21eb8fd1..0000000000000 --- a/src/plugins/unified_doc_viewer/public/components/doc_viewer_table/legacy/table.test.tsx +++ /dev/null @@ -1,452 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the "Elastic License - * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side - * Public License v 1"; you may not use this file except in compliance with, at - * your election, the "Elastic License 2.0", the "GNU Affero General Public - * License v3.0 only", or the "Server Side Public License, v 1". - */ - -import React from 'react'; -import { mountWithIntl } from '@kbn/test-jest-helpers'; -import { findTestSubject } from '@elastic/eui/lib/test'; -import { DocViewerLegacyTable } from './table'; -import type { DataView } from '@kbn/data-views-plugin/public'; -import type { DocViewRenderProps } from '@kbn/unified-doc-viewer/types'; -import { buildDataTableRecord } from '@kbn/discover-utils'; -import { setUnifiedDocViewerServices } from '../../../plugin'; -import type { UnifiedDocViewerServices } from '../../../types'; - -const services = { - uiSettings: { - get: (key: string) => { - if (key === 'discover:showMultiFields') { - return true; - } - }, - }, - fieldFormats: { - getDefaultInstance: jest.fn(() => ({ convert: (value: unknown) => value })), - getFormatterForField: jest.fn(() => ({ convert: (value: unknown) => value })), - }, -}; - -const dataView = { - fields: { - getAll: () => [ - { - name: '_index', - type: 'string', - scripted: false, - filterable: true, - }, - { - name: 'message', - type: 'string', - scripted: false, - filterable: false, - }, - { - name: 'extension', - type: 'string', - scripted: false, - filterable: true, - }, - { - name: 'bytes', - type: 'number', - scripted: false, - filterable: true, - }, - { - name: 'scripted', - type: 'number', - scripted: true, - filterable: false, - }, - ], - }, - metaFields: ['_index', '_score'], - getFormatterForField: jest.fn(() => ({ convert: (value: unknown) => value })), -} as unknown as DataView; - -dataView.fields.getByName = (name: string) => { - return dataView.fields.getAll().find((field) => field.name === name); -}; - -const mountComponent = ( - props: DocViewRenderProps, - overrides?: Partial -) => { - setUnifiedDocViewerServices({ ...services, ...overrides } as UnifiedDocViewerServices); - return mountWithIntl(); -}; - -describe('DocViewTable at Discover', () => { - // At Discover's main view, all buttons are rendered - // check for existence of action buttons and warnings - - const hit = buildDataTableRecord( - { - _index: 'logstash-2014.09.09', - _id: 'id123', - _score: 1, - _source: { - message: - 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit. \ - Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus \ - et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, \ - ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. \ - Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, \ - rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. \ - Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. \ - Phasellus ullamcorper ipsum rutrum nunc. Nunc nonummy metus. Vestibulum volutpat pretium libero. Cras id dui. Aenean ut', - extension: 'html', - not_mapped: 'yes', - bytes: 100, - objectArray: [{ foo: true }], - relatedContent: { - test: 1, - }, - scripted: 123, - _underscore: 123, - }, - }, - dataView - ); - - const props = { - hit, - columns: ['extension'], - dataView, - filter: jest.fn(), - onAddColumn: jest.fn(), - onRemoveColumn: jest.fn(), - }; - const component = mountComponent(props); - [ - { - _property: '_index', - addInclusiveFilterButton: true, - noMappingWarning: false, - toggleColumnButton: true, - underscoreWarning: false, - }, - { - _property: 'message', - addInclusiveFilterButton: false, - noMappingWarning: false, - toggleColumnButton: true, - underscoreWarning: false, - }, - { - _property: '_underscore', - addInclusiveFilterButton: false, - noMappingWarning: false, - toggleColumnButton: true, - underScoreWarning: true, - }, - { - _property: 'scripted', - addInclusiveFilterButton: false, - noMappingWarning: false, - toggleColumnButton: true, - underScoreWarning: false, - }, - { - _property: 'not_mapped', - addInclusiveFilterButton: false, - noMappingWarning: true, - toggleColumnButton: true, - underScoreWarning: false, - }, - ].forEach((check) => { - const rowComponent = findTestSubject(component, `tableDocViewRow-${check._property}`); - - it(`renders row for ${check._property}`, () => { - expect(rowComponent.length).toBe(1); - }); - - (['addInclusiveFilterButton', 'toggleColumnButton', 'underscoreWarning'] as const).forEach( - (element) => { - const elementExist = check[element]; - - if (typeof elementExist === 'boolean') { - const btn = findTestSubject(rowComponent, element, '^='); - - it(`renders ${element} for '${check._property}' correctly`, () => { - const disabled = btn.length ? btn.props().disabled : true; - const clickAble = btn.length && !disabled ? true : false; - expect(clickAble).toBe(elementExist); - }); - } - } - ); - }); -}); - -describe('DocViewTable at Discover Context', () => { - // here no toggleColumnButtons are rendered - const hit = buildDataTableRecord( - { - _index: 'logstash-2014.09.09', - _id: 'id123', - _score: 1, - _source: { - message: - 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit. \ - Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus \ - et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, \ - ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. \ - Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, \ - rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. \ - Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. \ - Phasellus ullamcorper ipsum rutrum nunc. Nunc nonummy metus. Vestibulum volutpat pretium libero. Cras id dui. Aenean ut', - }, - }, - dataView - ); - const props = { - hit, - columns: ['extension'], - dataView, - filter: jest.fn(), - }; - - const component = mountComponent(props); - - it(`renders no toggleColumnButton`, () => { - const foundLength = findTestSubject(component, 'toggleColumnButtons').length; - expect(foundLength).toBe(0); - }); - - it(`renders addInclusiveFilterButton`, () => { - const row = findTestSubject(component, `tableDocViewRow-_index`); - const btn = findTestSubject(row, 'addInclusiveFilterButton'); - expect(btn.length).toBe(1); - btn.simulate('click'); - expect(props.filter).toBeCalled(); - }); -}); - -describe('DocViewTable at Discover Doc', () => { - const hit = buildDataTableRecord( - { - _index: 'logstash-2014.09.09', - _score: 1, - _id: 'id123', - _source: { - extension: 'html', - not_mapped: 'yes', - }, - }, - dataView - ); - // here no action buttons are rendered - const props = { - hit, - dataView, - hideActionsColumn: true, - }; - const component = mountComponent(props); - const foundLength = findTestSubject(component, 'addInclusiveFilterButton').length; - - it(`renders no action buttons`, () => { - expect(foundLength).toBe(0); - }); -}); - -describe('DocViewTable at Discover Doc with Fields API', () => { - const dataViewCommerce = { - fields: { - getAll: () => [ - { - name: '_index', - type: 'string', - scripted: false, - filterable: true, - }, - { - name: 'category', - type: 'string', - scripted: false, - filterable: true, - }, - { - name: 'category.keyword', - displayName: 'category.keyword', - type: 'string', - scripted: false, - filterable: true, - spec: { - subType: { - multi: { - parent: 'category', - }, - }, - }, - }, - { - name: 'customer_first_name', - type: 'string', - scripted: false, - filterable: true, - }, - { - name: 'customer_first_name.keyword', - displayName: 'customer_first_name.keyword', - type: 'string', - scripted: false, - filterable: false, - spec: { - subType: { - multi: { - parent: 'customer_first_name', - }, - }, - }, - }, - { - name: 'customer_first_name.nickname', - displayName: 'customer_first_name.nickname', - type: 'string', - scripted: false, - filterable: false, - spec: { - subType: { - multi: { - parent: 'customer_first_name', - }, - }, - }, - }, - { - name: 'city', - displayName: 'city', - type: 'keyword', - isMapped: true, - readFromDocValues: true, - searchable: true, - shortDotsEnable: false, - scripted: false, - filterable: false, - }, - { - name: 'city.raw', - displayName: 'city.raw', - type: 'string', - isMapped: true, - spec: { - subType: { - multi: { - parent: 'city', - }, - }, - }, - shortDotsEnable: false, - scripted: false, - filterable: false, - }, - ], - }, - metaFields: ['_index', '_type', '_score', '_id'], - getFormatterForField: jest.fn(() => ({ convert: (value: unknown) => value })), - } as unknown as DataView; - - dataViewCommerce.fields.getByName = (name: string) => { - return dataViewCommerce.fields.getAll().find((field) => field.name === name); - }; - - const fieldsHit = buildDataTableRecord( - { - _index: 'logstash-2014.09.09', - _id: 'id123', - _score: 1.0, - fields: { - category: "Women's Clothing", - 'category.keyword': "Women's Clothing", - customer_first_name: 'Betty', - 'customer_first_name.keyword': 'Betty', - 'customer_first_name.nickname': 'Betsy', - 'city.raw': 'Los Angeles', - }, - }, - dataView - ); - const props = { - hit: fieldsHit, - columns: ['Document'], - dataView: dataViewCommerce, - filter: jest.fn(), - onAddColumn: jest.fn(), - onRemoveColumn: jest.fn(), - }; - - it('renders multifield rows if showMultiFields flag is set', () => { - const component = mountComponent(props); - - const categoryKeywordRow = findTestSubject(component, 'tableDocViewRow-category.keyword'); - expect(categoryKeywordRow.length).toBe(1); - - expect(findTestSubject(component, 'tableDocViewRow-customer_first_name.keyword').length).toBe( - 1 - ); - expect(findTestSubject(component, 'tableDocViewRow-customer_first_name.nickname').length).toBe( - 1 - ); - - expect( - findTestSubject(component, 'tableDocViewRow-category.keyword-multifieldBadge').length - ).toBe(1); - - expect( - findTestSubject(component, 'tableDocViewRow-customer_first_name.keyword-multifieldBadge') - .length - ).toBe(1); - - expect( - findTestSubject(component, 'tableDocViewRow-customer_first_name.nickname-multifieldBadge') - .length - ).toBe(1); - - expect(findTestSubject(component, 'tableDocViewRow-city.raw').length).toBe(1); - }); - - it('does not render multifield rows if showMultiFields flag is not set', () => { - const overridedServices = { - uiSettings: { - get: (key: string) => { - if (key === 'discover:showMultiFields') { - return false; - } - }, - }, - } as unknown as UnifiedDocViewerServices; - const component = mountComponent(props, overridedServices); - - const categoryKeywordRow = findTestSubject(component, 'tableDocViewRow-category.keyword'); - expect(categoryKeywordRow.length).toBe(0); - - expect(findTestSubject(component, 'tableDocViewRow-customer_first_name.keyword').length).toBe( - 0 - ); - - expect(findTestSubject(component, 'tableDocViewRow-customer_first_name.nickname').length).toBe( - 0 - ); - - expect( - findTestSubject(component, 'tableDocViewRow-customer_first_name.keyword-multifieldBadge') - .length - ).toBe(0); - - expect(findTestSubject(component, 'tableDocViewRow-customer_first_name').length).toBe(1); - expect( - findTestSubject(component, 'tableDocViewRow-customer_first_name.nickname-multifieldBadge') - .length - ).toBe(0); - - expect(findTestSubject(component, 'tableDocViewRow-city').length).toBe(0); - expect(findTestSubject(component, 'tableDocViewRow-city.raw').length).toBe(1); - }); -}); diff --git a/src/plugins/unified_doc_viewer/public/components/doc_viewer_table/legacy/table.tsx b/src/plugins/unified_doc_viewer/public/components/doc_viewer_table/legacy/table.tsx deleted file mode 100644 index e834bef5d664e..0000000000000 --- a/src/plugins/unified_doc_viewer/public/components/doc_viewer_table/legacy/table.tsx +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the "Elastic License - * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side - * Public License v 1"; you may not use this file except in compliance with, at - * your election, the "Elastic License 2.0", the "GNU Affero General Public - * License v3.0 only", or the "Server Side Public License, v 1". - */ - -import '../table.scss'; -import React, { useCallback, useMemo } from 'react'; -import { EuiInMemoryTable } from '@elastic/eui'; -import { getFieldIconType } from '@kbn/field-utils/src/utils/get_field_icon_type'; -import { - SHOW_MULTIFIELDS, - formatFieldValue, - getIgnoredReason, - getShouldShowFieldHandler, - isNestedFieldParent, -} from '@kbn/discover-utils'; -import type { DocViewRenderProps, FieldRecordLegacy } from '@kbn/unified-doc-viewer/types'; -import { getUnifiedDocViewerServices } from '../../../plugin'; -import { ACTIONS_COLUMN, MAIN_COLUMNS } from './table_columns'; - -export const DocViewerLegacyTable = ({ - columns, - hit, - dataView, - hideActionsColumn, - filter, - onAddColumn, - onRemoveColumn, -}: DocViewRenderProps) => { - const { fieldFormats, uiSettings } = getUnifiedDocViewerServices(); - const showMultiFields = useMemo(() => uiSettings.get(SHOW_MULTIFIELDS), [uiSettings]); - - const mapping = useCallback((name: string) => dataView.fields.getByName(name), [dataView.fields]); - const tableColumns = useMemo(() => { - return !hideActionsColumn ? [ACTIONS_COLUMN, ...MAIN_COLUMNS] : MAIN_COLUMNS; - }, [hideActionsColumn]); - - const onToggleColumn = useMemo(() => { - if (!onRemoveColumn || !onAddColumn || !columns) { - return undefined; - } - return (field: string) => { - if (columns.includes(field)) { - onRemoveColumn(field); - } else { - onAddColumn(field); - } - }; - }, [onRemoveColumn, onAddColumn, columns]); - - const onSetRowProps = useCallback(({ field: { field } }: FieldRecordLegacy) => { - return { - key: field, - className: 'kbnDocViewer__tableRow', - 'data-test-subj': `tableDocViewRow-${field}`, - }; - }, []); - - const shouldShowFieldHandler = useMemo( - () => getShouldShowFieldHandler(Object.keys(hit.flattened), dataView, showMultiFields), - [hit.flattened, dataView, showMultiFields] - ); - - const items: FieldRecordLegacy[] = Object.keys(hit.flattened) - .filter(shouldShowFieldHandler) - .sort((fieldA, fieldB) => { - const mappingA = mapping(fieldA); - const mappingB = mapping(fieldB); - const nameA = !mappingA || !mappingA.displayName ? fieldA : mappingA.displayName; - const nameB = !mappingB || !mappingB.displayName ? fieldB : mappingB.displayName; - return nameA.localeCompare(nameB); - }) - .map((field) => { - const fieldMapping = mapping(field); - const displayName = fieldMapping?.displayName ?? field; - const fieldType = isNestedFieldParent(field, dataView) - ? 'nested' - : fieldMapping - ? getFieldIconType(fieldMapping) - : undefined; - const ignored = getIgnoredReason(fieldMapping ?? field, hit.raw._ignored); - return { - action: { - onToggleColumn, - onFilter: filter, - isActive: !!columns?.includes(field), - flattenedField: hit.flattened[field], - }, - field: { - field, - displayName, - fieldMapping, - fieldType, - scripted: Boolean(fieldMapping?.scripted), - }, - value: { - formattedValue: formatFieldValue( - hit.flattened[field], - hit.raw, - fieldFormats, - dataView, - fieldMapping - ), - ignored, - }, - }; - }); - - return ( - - ); -}; diff --git a/src/plugins/unified_doc_viewer/public/components/doc_viewer_table/legacy/table_cell_actions.tsx b/src/plugins/unified_doc_viewer/public/components/doc_viewer_table/legacy/table_cell_actions.tsx deleted file mode 100644 index c63c8c1ae70e9..0000000000000 --- a/src/plugins/unified_doc_viewer/public/components/doc_viewer_table/legacy/table_cell_actions.tsx +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the "Elastic License - * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side - * Public License v 1"; you may not use this file except in compliance with, at - * your election, the "Elastic License 2.0", the "GNU Affero General Public - * License v3.0 only", or the "Server Side Public License, v 1". - */ - -import React from 'react'; -import type { DataViewField } from '@kbn/data-views-plugin/public'; -import type { DocViewFilterFn } from '@kbn/unified-doc-viewer/types'; -import { DocViewTableRowBtnFilterRemove } from './table_row_btn_filter_remove'; -import { DocViewTableRowBtnFilterExists } from './table_row_btn_filter_exists'; -import { DocViewTableRowBtnToggleColumn } from './table_row_btn_toggle_column'; -import { DocViewTableRowBtnFilterAdd } from './table_row_btn_filter_add'; - -interface TableActionsProps { - field: string; - isActive: boolean; - flattenedField: unknown; - fieldMapping?: DataViewField; - onFilter: DocViewFilterFn; - onToggleColumn: ((field: string) => void) | undefined; - ignoredValue: boolean; -} - -export const TableActions = ({ - isActive, - field, - fieldMapping, - flattenedField, - onToggleColumn, - onFilter, - ignoredValue, -}: TableActionsProps) => { - return ( -
        - {onFilter && ( - onFilter(fieldMapping, flattenedField, '+')} - /> - )} - {onFilter && ( - onFilter(fieldMapping, flattenedField, '-')} - /> - )} - {onToggleColumn && ( - onToggleColumn(field)} - /> - )} - {onFilter && ( - onFilter('_exists_', field, '+')} - scripted={fieldMapping && fieldMapping.scripted} - /> - )} -
        - ); -}; diff --git a/src/plugins/unified_doc_viewer/public/components/doc_viewer_table/legacy/table_columns.tsx b/src/plugins/unified_doc_viewer/public/components/doc_viewer_table/legacy/table_columns.tsx deleted file mode 100644 index 3b510f6130229..0000000000000 --- a/src/plugins/unified_doc_viewer/public/components/doc_viewer_table/legacy/table_columns.tsx +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the "Elastic License - * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side - * Public License v 1"; you may not use this file except in compliance with, at - * your election, the "Elastic License 2.0", the "GNU Affero General Public - * License v3.0 only", or the "Server Side Public License, v 1". - */ - -import { EuiBasicTableColumn, EuiText } from '@elastic/eui'; -import React from 'react'; -import { FormattedMessage } from '@kbn/i18n-react'; -import type { FieldRecordLegacy } from '@kbn/unified-doc-viewer/types'; -import { FieldName } from '@kbn/unified-doc-viewer'; -import { TableActions } from './table_cell_actions'; -import { TableFieldValue } from '../table_cell_value'; - -export const ACTIONS_COLUMN: EuiBasicTableColumn = { - field: 'action', - className: 'kbnDocViewer__tableActionsCell', - width: '108px', - mobileOptions: { header: false }, - name: ( - - - - - - ), - render: ( - { flattenedField, isActive, onFilter, onToggleColumn }: FieldRecordLegacy['action'], - { field: { field, fieldMapping }, value: { ignored } }: FieldRecordLegacy - ) => { - return ( - - ); - }, -}; -export const MAIN_COLUMNS: Array> = [ - { - field: 'field', - className: 'kbnDocViewer__tableFieldNameCell', - mobileOptions: { header: false }, - width: '30%', - name: ( - - - - - - ), - render: ({ - field, - fieldType, - displayName, - fieldMapping, - scripted, - }: FieldRecordLegacy['field']) => { - return field ? ( - - ) : ( -   - ); - }, - }, - { - field: 'value', - className: 'kbnDocViewer__tableValueCell', - mobileOptions: { header: false }, - name: ( - - - - - - ), - render: ( - { formattedValue, ignored }: FieldRecordLegacy['value'], - { field: { field }, action: { flattenedField } }: FieldRecordLegacy - ) => { - return ( - - ); - }, - }, -]; diff --git a/src/plugins/unified_doc_viewer/public/components/doc_viewer_table/legacy/table_row_btn_filter_add.tsx b/src/plugins/unified_doc_viewer/public/components/doc_viewer_table/legacy/table_row_btn_filter_add.tsx deleted file mode 100644 index 12e3196cac1c9..0000000000000 --- a/src/plugins/unified_doc_viewer/public/components/doc_viewer_table/legacy/table_row_btn_filter_add.tsx +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the "Elastic License - * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side - * Public License v 1"; you may not use this file except in compliance with, at - * your election, the "Elastic License 2.0", the "GNU Affero General Public - * License v3.0 only", or the "Server Side Public License, v 1". - */ - -import React from 'react'; -import { FormattedMessage } from '@kbn/i18n-react'; -import { EuiToolTip, EuiButtonIcon } from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; - -export interface Props { - onClick: () => void; - disabled: boolean; -} - -export function DocViewTableRowBtnFilterAdd({ onClick, disabled = false }: Props) { - const tooltipContent = disabled ? ( - - ) : ( - - ); - - return ( - - - - ); -} diff --git a/src/plugins/unified_doc_viewer/public/components/doc_viewer_table/legacy/table_row_btn_filter_exists.tsx b/src/plugins/unified_doc_viewer/public/components/doc_viewer_table/legacy/table_row_btn_filter_exists.tsx deleted file mode 100644 index 2685b4b7b8e69..0000000000000 --- a/src/plugins/unified_doc_viewer/public/components/doc_viewer_table/legacy/table_row_btn_filter_exists.tsx +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the "Elastic License - * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side - * Public License v 1"; you may not use this file except in compliance with, at - * your election, the "Elastic License 2.0", the "GNU Affero General Public - * License v3.0 only", or the "Server Side Public License, v 1". - */ - -import React from 'react'; -import { FormattedMessage } from '@kbn/i18n-react'; -import { EuiToolTip, EuiButtonIcon } from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; - -export interface Props { - onClick: () => void; - disabled?: boolean; - scripted?: boolean; -} - -export function DocViewTableRowBtnFilterExists({ - onClick, - disabled = false, - scripted = false, -}: Props) { - const tooltipContent = disabled ? ( - scripted ? ( - - ) : ( - - ) - ) : ( - - ); - - return ( - - - - ); -} diff --git a/src/plugins/unified_doc_viewer/public/components/doc_viewer_table/legacy/table_row_btn_filter_remove.tsx b/src/plugins/unified_doc_viewer/public/components/doc_viewer_table/legacy/table_row_btn_filter_remove.tsx deleted file mode 100644 index c9073fc9831c6..0000000000000 --- a/src/plugins/unified_doc_viewer/public/components/doc_viewer_table/legacy/table_row_btn_filter_remove.tsx +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the "Elastic License - * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side - * Public License v 1"; you may not use this file except in compliance with, at - * your election, the "Elastic License 2.0", the "GNU Affero General Public - * License v3.0 only", or the "Server Side Public License, v 1". - */ - -import React from 'react'; -import { FormattedMessage } from '@kbn/i18n-react'; -import { i18n } from '@kbn/i18n'; -import { EuiToolTip, EuiButtonIcon } from '@elastic/eui'; - -export interface Props { - onClick: () => void; - disabled?: boolean; -} - -export function DocViewTableRowBtnFilterRemove({ onClick, disabled = false }: Props) { - const tooltipContent = disabled ? ( - - ) : ( - - ); - - return ( - - - - ); -} diff --git a/src/plugins/unified_doc_viewer/public/components/doc_viewer_table/legacy/table_row_btn_toggle_column.tsx b/src/plugins/unified_doc_viewer/public/components/doc_viewer_table/legacy/table_row_btn_toggle_column.tsx deleted file mode 100644 index 9f999248cf269..0000000000000 --- a/src/plugins/unified_doc_viewer/public/components/doc_viewer_table/legacy/table_row_btn_toggle_column.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", the "GNU Affero General Public License v3.0 only", and the "Server Side - * Public License v 1"; you may not use this file except in compliance with, at - * your election, the "Elastic License 2.0", the "GNU Affero General Public - * License v3.0 only", or the "Server Side Public License, v 1". - */ - -import React from 'react'; -import { FormattedMessage } from '@kbn/i18n-react'; -import { i18n } from '@kbn/i18n'; -import { EuiToolTip, EuiButtonIcon } from '@elastic/eui'; - -export interface Props { - active: boolean; - disabled?: boolean; - onClick: () => void; - fieldname: string; -} - -export function DocViewTableRowBtnToggleColumn({ - onClick, - active, - disabled = false, - fieldname = '', -}: Props) { - if (disabled) { - return ( - - ); - } - return ( - - } - > - - - ); -} diff --git a/src/plugins/unified_doc_viewer/public/components/doc_viewer_table/table.scss b/src/plugins/unified_doc_viewer/public/components/doc_viewer_table/table.scss index 64e700c73fca5..348c8c9784ad8 100644 --- a/src/plugins/unified_doc_viewer/public/components/doc_viewer_table/table.scss +++ b/src/plugins/unified_doc_viewer/public/components/doc_viewer_table/table.scss @@ -1,59 +1,3 @@ -.kbnDocViewer { - .euiTableRowCell { - vertical-align: top; - } -} - -.kbnDocViewer__tableRow { - font-size: $euiFontSizeXS; - font-family: $euiCodeFontFamily; - - // set min-width for each column except actions - .euiTableRowCell:nth-child(n+2) { - min-width: $euiSizeM * 9; - } - - .kbnDocViewer__buttons { - // Show all icons if one is focused, - &:focus-within { - .kbnDocViewer__actionButton { - opacity: 1; - } - } - } - - &:hover { - .kbnDocViewer__actionButton { - opacity: 1; - } - } - - .kbnDocViewer__actionButton { - @include euiBreakpoint('m', 'l', 'xl') { - opacity: 0; - } - - &:focus { - opacity: 1; - } - } -} - -.kbnDocViewer__tableActionsCell, -.kbnDocViewer__tableFieldNameCell { - .euiTableCellContent { - align-items: flex-start; - padding: $euiSizeXS; - } -} - -.kbnDocViewer__tableValueCell { - .euiTableCellContent { - flex-direction: column; - align-items: flex-start; - } -} - .kbnDocViewer__value { word-break: break-all; word-wrap: break-word; diff --git a/src/plugins/unified_doc_viewer/public/components/doc_viewer_table/table.tsx b/src/plugins/unified_doc_viewer/public/components/doc_viewer_table/table.tsx index 16976d43e58f9..632652100069d 100644 --- a/src/plugins/unified_doc_viewer/public/components/doc_viewer_table/table.tsx +++ b/src/plugins/unified_doc_viewer/public/components/doc_viewer_table/table.tsx @@ -497,7 +497,7 @@ export const DocViewerTable = ({ {rows.length === 0 ? ( - +

        { - if (key === TRUNCATE_MAX_HEIGHT) { - return mockTruncateMaxHeightSetting ?? TRUNCATE_MAX_HEIGHT_DEFAULT_VALUE; - } - return; -}) as IUiSettingsClient['get']; - setUnifiedDocViewerServices(mockUnifiedDocViewerServices); let mockScrollHeight = 0; @@ -35,7 +21,6 @@ jest.spyOn(HTMLElement.prototype, 'scrollHeight', 'get').mockImplementation(() = describe('TableFieldValue', () => { afterEach(() => { mockScrollHeight = 0; - mockTruncateMaxHeightSetting = undefined; }); it('should render correctly', async () => { @@ -121,97 +106,4 @@ describe('TableFieldValue', () => { expect(valueElement.getAttribute('css')).toBeNull(); expect(valueElement.classList.contains('kbnDocViewer__value--truncated')).toBe(false); }); - - it('should truncate a long value in legacy table correctly', async () => { - mockScrollHeight = 1000; - - const value = 'long value'.repeat(300); - render( - - ); - - expect(screen.getByText(value)).toBeInTheDocument(); - - let toggleButton = screen.getByTestId('toggleLongFieldValue-message'); - expect(toggleButton).toBeInTheDocument(); - expect(toggleButton.getAttribute('aria-expanded')).toBe('false'); - - let valueElement = screen.getByTestId('tableDocViewRow-message-value'); - expect(valueElement.getAttribute('css')).toBeDefined(); - expect(valueElement.classList.contains('kbnDocViewer__value--truncated')).toBe(true); - - toggleButton.click(); - - toggleButton = screen.getByTestId('toggleLongFieldValue-message'); - expect(toggleButton).toBeInTheDocument(); - expect(toggleButton.getAttribute('aria-expanded')).toBe('true'); - - valueElement = screen.getByTestId('tableDocViewRow-message-value'); - expect(valueElement.getAttribute('css')).toBeNull(); - expect(valueElement.classList.contains('kbnDocViewer__value--truncated')).toBe(false); - - toggleButton.click(); - - toggleButton = screen.getByTestId('toggleLongFieldValue-message'); - expect(toggleButton).toBeInTheDocument(); - expect(toggleButton.getAttribute('aria-expanded')).toBe('false'); - - valueElement = screen.getByTestId('tableDocViewRow-message-value'); - expect(valueElement.getAttribute('css')).toBeDefined(); - expect(valueElement.classList.contains('kbnDocViewer__value--truncated')).toBe(true); - }); - - it('should not truncate a long value in legacy table if limit is not reached', async () => { - mockScrollHeight = 112; - - const value = 'long value'.repeat(300); - render( - - ); - - expect(screen.getByText(value)).toBeInTheDocument(); - expect(screen.queryByTestId('toggleLongFieldValue-message')).toBeNull(); - - const valueElement = screen.getByTestId('tableDocViewRow-message-value'); - expect(valueElement.getAttribute('css')).toBeNull(); - expect(valueElement.classList.contains('kbnDocViewer__value--truncated')).toBe(false); - }); - - it('should not truncate a long value in legacy table if setting is 0', async () => { - mockScrollHeight = 1000; - mockTruncateMaxHeightSetting = 0; - - const value = 'long value'.repeat(300); - render( - - ); - - expect(screen.getByText(value)).toBeInTheDocument(); - expect(screen.queryByTestId('toggleLongFieldValue-message')).toBeNull(); - - const valueElement = screen.getByTestId('tableDocViewRow-message-value'); - expect(valueElement.getAttribute('css')).toBeNull(); - expect(valueElement.classList.contains('kbnDocViewer__value--truncated')).toBe(false); - }); }); diff --git a/src/plugins/unified_doc_viewer/public/components/doc_viewer_table/table_cell_value.tsx b/src/plugins/unified_doc_viewer/public/components/doc_viewer_table/table_cell_value.tsx index 3afe935307ab2..556f671e67cbd 100644 --- a/src/plugins/unified_doc_viewer/public/components/doc_viewer_table/table_cell_value.tsx +++ b/src/plugins/unified_doc_viewer/public/components/doc_viewer_table/table_cell_value.tsx @@ -21,9 +21,7 @@ import { import classnames from 'classnames'; import React, { Fragment, useCallback, useState } from 'react'; import { i18n } from '@kbn/i18n'; -import { IgnoredReason, TRUNCATE_MAX_HEIGHT } from '@kbn/discover-utils'; -import { FieldRecordLegacy } from '@kbn/unified-doc-viewer/types'; -import { getUnifiedDocViewerServices } from '../../plugin'; +import { IgnoredReason } from '@kbn/discover-utils'; const DOC_VIEWER_DEFAULT_TRUNCATE_MAX_HEIGHT = 110; @@ -96,14 +94,14 @@ const IgnoreWarning: React.FC = React.memo(({ rawValue, reas ); }); -type TableFieldValueProps = Pick & { - formattedValue: FieldRecordLegacy['value']['formattedValue']; +interface TableFieldValueProps { + field: string; + formattedValue: string; rawValue: unknown; ignoreReason?: IgnoredReason; isDetails?: boolean; // true when inside EuiDataGrid cell popover - isLegacy?: boolean; // true when inside legacy table isHighlighted?: boolean; // whether it's matching a search term -}; +} export const TableFieldValue = ({ formattedValue, @@ -111,14 +109,10 @@ export const TableFieldValue = ({ rawValue, ignoreReason, isDetails, - isLegacy, isHighlighted, }: TableFieldValueProps) => { const { euiTheme } = useEuiTheme(); - const { uiSettings } = getUnifiedDocViewerServices(); - const truncationHeight = isLegacy - ? uiSettings.get(TRUNCATE_MAX_HEIGHT) - : DOC_VIEWER_DEFAULT_TRUNCATE_MAX_HEIGHT; + const truncationHeight = DOC_VIEWER_DEFAULT_TRUNCATE_MAX_HEIGHT; const [containerRef, setContainerRef] = useState(null); useResizeObserver(containerRef); diff --git a/src/plugins/unified_doc_viewer/public/plugin.tsx b/src/plugins/unified_doc_viewer/public/plugin.tsx index 41db23a52591c..4806d5fce0918 100644 --- a/src/plugins/unified_doc_viewer/public/plugin.tsx +++ b/src/plugins/unified_doc_viewer/public/plugin.tsx @@ -9,7 +9,6 @@ import React from 'react'; import type { CoreSetup, Plugin } from '@kbn/core/public'; -import { isLegacyTableEnabled } from '@kbn/discover-utils'; import { i18n } from '@kbn/i18n'; import { DocViewsRegistry } from '@kbn/unified-doc-viewer'; import { EuiDelayRender, EuiSkeletonText } from '@elastic/eui'; @@ -31,9 +30,6 @@ const fallback = ( ); -const LazyDocViewerLegacyTable = dynamic(() => import('./components/doc_viewer_table/legacy'), { - fallback, -}); const LazyDocViewerTable = dynamic(() => import('./components/doc_viewer_table'), { fallback }); const LazySourceViewer = dynamic(() => import('./components/doc_viewer_source'), { fallback }); @@ -65,17 +61,7 @@ export class UnifiedDocViewerPublicPlugin }), order: 10, component: (props) => { - const { textBasedHits } = props; - const { uiSettings } = getUnifiedDocViewerServices(); - - const LazyDocView = isLegacyTableEnabled({ - uiSettings, - isEsqlMode: Array.isArray(textBasedHits), - }) - ? LazyDocViewerLegacyTable - : LazyDocViewerTable; - - return ; + return ; }, }); diff --git a/src/plugins/unified_search/public/filter_bar/filter_editor/filter_editor.tsx b/src/plugins/unified_search/public/filter_bar/filter_editor/filter_editor.tsx index cc602efa61422..425624c3e194d 100644 --- a/src/plugins/unified_search/public/filter_bar/filter_editor/filter_editor.tsx +++ b/src/plugins/unified_search/public/filter_bar/filter_editor/filter_editor.tsx @@ -280,7 +280,7 @@ class FilterEditorComponent extends Component { diff --git a/src/plugins/unified_search/public/filter_bar/filter_item/filter_item.tsx b/src/plugins/unified_search/public/filter_bar/filter_item/filter_item.tsx index 19ba668092466..9c8e7b074149f 100644 --- a/src/plugins/unified_search/public/filter_bar/filter_item/filter_item.tsx +++ b/src/plugins/unified_search/public/filter_bar/filter_item/filter_item.tsx @@ -388,7 +388,7 @@ function FilterItemComponent(props: FilterItemProps) { ) : ( +

        ); diff --git a/src/plugins/unified_search/public/query_string_input/filter_editor_wrapper.tsx b/src/plugins/unified_search/public/query_string_input/filter_editor_wrapper.tsx index 319d3b0f49846..16ef016ff4006 100644 --- a/src/plugins/unified_search/public/query_string_input/filter_editor_wrapper.tsx +++ b/src/plugins/unified_search/public/query_string_input/filter_editor_wrapper.tsx @@ -105,7 +105,7 @@ export const FilterEditorWrapper = React.memo(function FilterEditorWrapper({ } return ( -
        +
        {newFilter && ( -

        {strings.getNoDataPopoverContent()}

        +

        {strings.getNoDataPopoverContent()}

        } minWidth={300} diff --git a/src/plugins/unified_search/public/query_string_input/query_bar_top_row.tsx b/src/plugins/unified_search/public/query_string_input/query_bar_top_row.tsx index 4d4db4438d74d..037997bbd5c86 100644 --- a/src/plugins/unified_search/public/query_string_input/query_bar_top_row.tsx +++ b/src/plugins/unified_search/public/query_string_input/query_bar_top_row.tsx @@ -628,7 +628,7 @@ export const QueryBarTopRow = React.memo( function renderDataViewsPicker() { if (props.dataViewPickerComponentProps && !Boolean(isQueryLangSelected)) { return ( - + {!isQueryLangSelected ? renderQueryInput() : null} diff --git a/src/plugins/unified_search/public/query_string_input/query_string_input.tsx b/src/plugins/unified_search/public/query_string_input/query_string_input.tsx index 2e3b0fab0a161..2e76341ae6071 100644 --- a/src/plugins/unified_search/public/query_string_input/query_string_input.tsx +++ b/src/plugins/unified_search/public/query_string_input/query_string_input.tsx @@ -808,7 +808,7 @@ export default class QueryStringInputUI extends PureComponent
        -
        +

        - + {props.children} diff --git a/src/plugins/vis_types/timeseries/public/application/components/aggs/percentile_ui.js b/src/plugins/vis_types/timeseries/public/application/components/aggs/percentile_ui.js index f30dfce37e5c6..7a93aa271b5d5 100644 --- a/src/plugins/vis_types/timeseries/public/application/components/aggs/percentile_ui.js +++ b/src/plugins/vis_types/timeseries/public/application/components/aggs/percentile_ui.js @@ -122,7 +122,7 @@ export class Percentiles extends Component { {/* If the series is grouped by, then these colors are not respected, no need to display the color picker */} {!isGroupedBy && !['table', 'metric', 'markdown'].includes(panel.type) && ( - + -

        +
        {i18n.translate('visTypeTimeseries.indexPatternSelect.switchModePopover.title', { defaultMessage: 'Data view mode', diff --git a/src/plugins/vis_types/timeseries/public/application/visualizations/views/timeseries/decorators/__snapshots__/area_decorator.test.js.snap b/src/plugins/vis_types/timeseries/public/application/visualizations/views/timeseries/decorators/__snapshots__/area_decorator.test.js.snap index 7ded8e2254aa9..18ce44a9fb7ec 100644 --- a/src/plugins/vis_types/timeseries/public/application/visualizations/views/timeseries/decorators/__snapshots__/area_decorator.test.js.snap +++ b/src/plugins/vis_types/timeseries/public/application/visualizations/views/timeseries/decorators/__snapshots__/area_decorator.test.js.snap @@ -18,7 +18,7 @@ exports[`src/legacy/core_plugins/metrics/public/visualizations/views/timeseries/ "radius": 1, "stroke": "rgb(0, 156, 224)", "strokeWidth": 5, - "visible": false, + "visible": "never", }, } } diff --git a/src/plugins/vis_types/timeseries/public/application/visualizations/views/timeseries/utils/__snapshots__/series_styles.test.js.snap b/src/plugins/vis_types/timeseries/public/application/visualizations/views/timeseries/utils/__snapshots__/series_styles.test.js.snap index 054ca0f0d8193..28bfd0c698307 100644 --- a/src/plugins/vis_types/timeseries/public/application/visualizations/views/timeseries/utils/__snapshots__/series_styles.test.js.snap +++ b/src/plugins/vis_types/timeseries/public/application/visualizations/views/timeseries/utils/__snapshots__/series_styles.test.js.snap @@ -17,7 +17,7 @@ Object { "radius": 1, "stroke": "rgb(224, 0, 221)", "strokeWidth": 1, - "visible": true, + "visible": "always", }, }, "curve": 7, @@ -41,7 +41,7 @@ Object { "radius": 0.5, "stroke": "#000", "strokeWidth": 5, - "visible": false, + "visible": "never", }, }, "curve": 9, diff --git a/src/plugins/vis_types/timeseries/public/application/visualizations/views/timeseries/utils/series_styles.js b/src/plugins/vis_types/timeseries/public/application/visualizations/views/timeseries/utils/series_styles.js index 0da1e8e474b50..6bfbbb7bfb287 100644 --- a/src/plugins/vis_types/timeseries/public/application/visualizations/views/timeseries/utils/series_styles.js +++ b/src/plugins/vis_types/timeseries/public/application/visualizations/views/timeseries/utils/series_styles.js @@ -27,7 +27,7 @@ export const getAreaStyles = ({ points, lines, color }) => ({ radius: points.radius || 0.5, stroke: color || DEFAULT_COLOR, strokeWidth: points.lineWidth || 5, - visible: points.lineWidth > 0 && Boolean(points.show), + visible: points.lineWidth > 0 && Boolean(points.show) ? 'always' : 'never', }, }, curve: lines.steps ? CurveType.CURVE_STEP_AFTER : CurveType.LINEAR, diff --git a/src/plugins/visualizations/public/components/visualization_missed_saved_object_error.tsx b/src/plugins/visualizations/public/components/visualization_missed_saved_object_error.tsx index d4124ca216d04..e0be21c3272e4 100644 --- a/src/plugins/visualizations/public/components/visualization_missed_saved_object_error.tsx +++ b/src/plugins/visualizations/public/components/visualization_missed_saved_object_error.tsx @@ -49,7 +49,7 @@ export const VisualizationMissedSavedObjectError = ({ path: '/kibana/indexPatterns/create', })} data-test-subj="configuration-failure-reconfigure-indexpatterns" - style={{ width: '100%' }} + css={{ width: '100%' }} > {i18n.translate('visualizations.missedDataView.dataViewReconfigure', { defaultMessage: `Recreate it in the data view management page`, diff --git a/src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx b/src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx index 4993c0168313a..71338e96ea145 100644 --- a/src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx +++ b/src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx @@ -472,7 +472,7 @@ export const getVisualizeEmbeddableFactory: (deps: { return (
        {/* Replicate the loading state for the expression renderer to avoid FOUC */} - + {isLoading && } {!isLoading && error && ( { + await PageObjects.console.enterText(`POST _ingest/pipeline/_simulate +{ + "pipeline": { + "processors": [ + { + "script": {`); + await PageObjects.console.pressEnter(); + await PageObjects.console.sleepForDebouncePeriod(); + await PageObjects.console.enterText(`"`); + expect(PageObjects.console.isAutocompleteVisible()).to.be.eql(true); + + // Iterate on the first 10 suggestions (the ones that are only visible without scrolling) + const suggestions = []; + for (let i = 0; i < 10; i++) { + suggestions.push(await PageObjects.console.getAutocompleteSuggestion(i)); + } + + // and expect the array to not have duplicates + expect(suggestions).to.eql(_.uniq(suggestions)); + }); + describe('Autocomplete behavior', () => { beforeEach(async () => { await PageObjects.console.clearEditorText(); @@ -377,5 +399,41 @@ GET _search expect(await PageObjects.console.getAutocompleteSuggestion(1)).to.be.eql(undefined); }); }); + + describe('Autocomplete shouldnt trigger within', () => { + beforeEach(async () => { + await PageObjects.console.skipTourIfExists(); + await PageObjects.console.clearEditorText(); + }); + + it('a hash comment', async () => { + await PageObjects.console.enterText(`# GET /`); + await PageObjects.console.sleepForDebouncePeriod(); + + expect(PageObjects.console.isAutocompleteVisible()).to.be.eql(false); + }); + + it('a simple double slash comment', async () => { + await PageObjects.console.enterText(`// GET /`); + await PageObjects.console.sleepForDebouncePeriod(); + + expect(PageObjects.console.isAutocompleteVisible()).to.be.eql(false); + }); + + it('a single line block comment', async () => { + await PageObjects.console.enterText(`/* GET /`); + await PageObjects.console.sleepForDebouncePeriod(); + + expect(PageObjects.console.isAutocompleteVisible()).to.be.eql(false); + }); + + it('a multiline block comment', async () => { + await PageObjects.console.enterText(`/* + GET /`); + await PageObjects.console.sleepForDebouncePeriod(); + + expect(PageObjects.console.isAutocompleteVisible()).to.be.eql(false); + }); + }); }); } diff --git a/test/functional/apps/console/_context_menu.ts b/test/functional/apps/console/_context_menu.ts index 4ee3c2cca40a7..0e126467c04c2 100644 --- a/test/functional/apps/console/_context_menu.ts +++ b/test/functional/apps/console/_context_menu.ts @@ -70,6 +70,55 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { } }); + it('doesnt allow to copy kbn requests as anything other than curl', async () => { + const canReadClipboard = await browser.checkBrowserPermission('clipboard-read'); + + await PageObjects.console.clearEditorText(); + await PageObjects.console.enterText('GET _search\n'); + + // Add a kbn request + // pressEnter + await PageObjects.console.enterText('GET kbn:/api/spaces/space'); + // Make sure to select the es and kbn request + await PageObjects.console.selectAllRequests(); + + await PageObjects.console.clickContextMenu(); + await PageObjects.console.clickCopyAsButton(); + + let resultToast = await toasts.getElementByIndex(1); + let toastText = await resultToast.getVisibleText(); + + expect(toastText).to.be('Requests copied to clipboard as curl'); + + // Check if the clipboard has the curl request + if (canReadClipboard) { + const clipboardText = await browser.getClipboardValue(); + expect(clipboardText).to.contain('curl -X GET'); + } + + // Wait until async operation is done + await PageObjects.common.sleep(1000); + + // Focus editor once again + await PageObjects.console.focusInputEditor(); + + // Try to copy as javascript + await PageObjects.console.clickContextMenu(); + await PageObjects.console.changeLanguageAndCopy('javascript'); + + resultToast = await toasts.getElementByIndex(2); + toastText = await resultToast.getVisibleText(); + + expect(toastText).to.be('Kibana requests can only be copied as curl'); + + // Since we tried to copy as javascript, the clipboard should still have + // the curl request + if (canReadClipboard) { + const clipboardText = await browser.getClipboardValue(); + expect(clipboardText).to.contain('curl -X GET'); + } + }); + it.skip('allows to change default language', async () => { await PageObjects.console.clickContextMenu(); diff --git a/test/functional/apps/context/classic/_discover_navigation.ts b/test/functional/apps/context/classic/_discover_navigation.ts deleted file mode 100644 index 476a4bfac9e18..0000000000000 --- a/test/functional/apps/context/classic/_discover_navigation.ts +++ /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", the "GNU Affero General Public License v3.0 only", and the "Server Side - * Public License v 1"; you may not use this file except in compliance with, at - * your election, the "Elastic License 2.0", the "GNU Affero General Public - * License v3.0 only", or the "Server Side Public License, v 1". - */ - -import expect from '@kbn/expect'; -import { FtrProviderContext } from '../../../ftr_provider_context'; - -const TEST_COLUMN_NAMES = ['@message']; -const TEST_FILTER_COLUMN_NAMES = [ - ['extension', 'jpg', 'extension.raw'], - ['geo.src', 'IN', 'geo.src'], -]; - -export default function ({ getService, getPageObjects }: FtrProviderContext) { - const retry = getService('retry'); - const docTable = getService('docTable'); - const filterBar = getService('filterBar'); - const { common, discover, timePicker, dashboard, context, header, unifiedFieldList } = - getPageObjects([ - 'common', - 'discover', - 'timePicker', - 'dashboard', - 'context', - 'header', - 'unifiedFieldList', - ]); - const testSubjects = getService('testSubjects'); - const dashboardAddPanel = getService('dashboardAddPanel'); - const browser = getService('browser'); - const kibanaServer = getService('kibanaServer'); - - describe('context link in discover classic', () => { - before(async () => { - await timePicker.setDefaultAbsoluteRangeViaUiSettings(); - await kibanaServer.uiSettings.update({ - 'doc_table:legacy': true, - defaultIndex: 'logstash-*', - }); - await common.navigateToApp('discover'); - await header.waitUntilLoadingHasFinished(); - for (const columnName of TEST_COLUMN_NAMES) { - await unifiedFieldList.clickFieldListItemAdd(columnName); - } - - for (const [columnName, value] of TEST_FILTER_COLUMN_NAMES) { - await unifiedFieldList.clickFieldListItem(columnName); - await unifiedFieldList.clickFieldListPlusFilter(columnName, value); - } - }); - after(async () => { - await kibanaServer.uiSettings.replace({}); - }); - - it('should open the context view with the same columns', async () => { - const columnNames = await docTable.getHeaderFields(); - expect(columnNames).to.eql(['@timestamp', ...TEST_COLUMN_NAMES]); - }); - - it('should open the context view with the selected document as anchor and allows selecting next anchor', async () => { - /** - * Helper function to get the first timestamp of the document table - * @param isAnchorRow - determins if just the anchor row of context should be selected - */ - const getTimestamp = async (isAnchorRow: boolean = false) => { - const contextFields = await docTable.getFields({ isAnchorRow }); - return contextFields[0][0]; - }; - // get the timestamp of the first row - - const firstDiscoverTimestamp = await getTimestamp(); - - // check the anchor timestamp in the context view - await retry.waitFor('selected document timestamp matches anchor timestamp ', async () => { - // navigate to the context view - await docTable.clickRowToggle({ rowIndex: 0 }); - const rowActions = await docTable.getRowActions({ rowIndex: 0 }); - await rowActions[0].click(); - await context.waitUntilContextLoadingHasFinished(); - const anchorTimestamp = await getTimestamp(true); - return anchorTimestamp === firstDiscoverTimestamp; - }); - - await retry.waitFor('next anchor timestamp matches previous anchor timestamp', async () => { - // get the timestamp of the first row - const firstContextTimestamp = await getTimestamp(false); - await docTable.clickRowToggle({ rowIndex: 0 }); - const rowActions = await docTable.getRowActions({ rowIndex: 0 }); - await rowActions[0].click(); - await context.waitUntilContextLoadingHasFinished(); - const anchorTimestamp = await getTimestamp(true); - return anchorTimestamp === firstContextTimestamp; - }); - }); - - it('should open the context view with the filters disabled', async () => { - let disabledFilterCounter = 0; - for (const [_, value, columnId] of TEST_FILTER_COLUMN_NAMES) { - if (await filterBar.hasFilter(columnId, value, false)) { - disabledFilterCounter++; - } - } - expect(disabledFilterCounter).to.be(TEST_FILTER_COLUMN_NAMES.length); - }); - - // bugfix: https://github.com/elastic/kibana/issues/92099 - it('should navigate to the first document and then back to discover', async () => { - await context.waitUntilContextLoadingHasFinished(); - - // navigate to the doc view - await docTable.clickRowToggle({ rowIndex: 0 }); - - // click the open action - await retry.try(async () => { - const rowActions = await docTable.getRowActions({ rowIndex: 0 }); - if (!rowActions.length) { - throw new Error('row actions empty, trying again'); - } - await rowActions[1].click(); - }); - - const hasDocHit = await testSubjects.exists('doc-hit'); - expect(hasDocHit).to.be(true); - - await testSubjects.click('~breadcrumb & ~first'); - await discover.waitForDiscoverAppOnScreen(); - await discover.waitForDocTableLoadingComplete(); - }); - - it('navigates to doc view from embeddable', async () => { - await common.navigateToApp('discover'); - await discover.saveSearch('my classic search'); - await header.waitUntilLoadingHasFinished(); - - await dashboard.navigateToApp(); - await dashboard.gotoDashboardLandingPage(); - await dashboard.clickNewDashboard(); - - await dashboardAddPanel.addSavedSearch('my classic search'); - await header.waitUntilLoadingHasFinished(); - - await docTable.clickRowToggle({ rowIndex: 0 }); - const rowActions = await docTable.getRowActions({ rowIndex: 0 }); - await rowActions[1].click(); - await common.sleep(250); - - // close popup - const alert = await browser.getAlert(); - await alert?.accept(); - if (await testSubjects.exists('confirmModalConfirmButton')) { - await testSubjects.click('confirmModalConfirmButton'); - } - - await retry.waitFor('navigate to doc view', async () => { - const currentUrl = await browser.getCurrentUrl(); - return currentUrl.includes('#/doc'); - }); - await retry.waitFor('doc view being rendered', async () => { - return await discover.isShowingDocViewer(); - }); - }); - }); -} diff --git a/test/functional/apps/context/classic/_filters.ts b/test/functional/apps/context/classic/_filters.ts deleted file mode 100644 index fd2ce16982f31..0000000000000 --- a/test/functional/apps/context/classic/_filters.ts +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the "Elastic License - * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side - * Public License v 1"; you may not use this file except in compliance with, at - * your election, the "Elastic License 2.0", the "GNU Affero General Public - * License v3.0 only", or the "Server Side Public License, v 1". - */ - -import { FtrProviderContext } from '../../../ftr_provider_context'; - -const TEST_INDEX_PATTERN = 'logstash-*'; -const TEST_ANCHOR_ID = 'AU_x3_BrGFA8no6QjjaI'; -const TEST_ANCHOR_FILTER_FIELD = 'geo.src'; -const TEST_ANCHOR_FILTER_VALUE = 'IN'; -const TEST_COLUMN_NAMES = ['extension', 'geo.src']; - -export default function ({ getService, getPageObjects }: FtrProviderContext) { - const docTable = getService('docTable'); - const filterBar = getService('filterBar'); - const retry = getService('retry'); - const kibanaServer = getService('kibanaServer'); - - const PageObjects = getPageObjects(['common', 'context']); - - describe('context filters', function contextSize() { - before(async function () { - await kibanaServer.uiSettings.update({ 'doc_table:legacy': true }); - }); - - after(async function () { - await kibanaServer.uiSettings.replace({}); - }); - - beforeEach(async function () { - await PageObjects.context.navigateTo(TEST_INDEX_PATTERN, TEST_ANCHOR_ID, { - columns: TEST_COLUMN_NAMES, - }); - }); - - it('inclusive filter should be addable via expanded doc table rows', async function () { - await retry.waitFor(`filter ${TEST_ANCHOR_FILTER_FIELD} in filterbar`, async () => { - await docTable.toggleRowExpanded({ isAnchorRow: true }); - const anchorDetailsRow = await docTable.getAnchorDetailsRow(); - await docTable.addInclusiveFilter(anchorDetailsRow, TEST_ANCHOR_FILTER_FIELD); - await PageObjects.context.waitUntilContextLoadingHasFinished(); - - return await filterBar.hasFilter(TEST_ANCHOR_FILTER_FIELD, TEST_ANCHOR_FILTER_VALUE, true); - }); - await retry.waitFor(`filter matching docs in docTable`, async () => { - const fields = await docTable.getFields(); - return fields - .map((row) => row[2]) - .every((fieldContent) => fieldContent === TEST_ANCHOR_FILTER_VALUE); - }); - }); - - it('filter for presence should be addable via expanded doc table rows', async function () { - await docTable.toggleRowExpanded({ isAnchorRow: true }); - - await retry.waitFor('an exists filter in the filterbar', async () => { - const anchorDetailsRow = await docTable.getAnchorDetailsRow(); - await docTable.addExistsFilter(anchorDetailsRow, TEST_ANCHOR_FILTER_FIELD); - await PageObjects.context.waitUntilContextLoadingHasFinished(); - return await filterBar.hasFilter(TEST_ANCHOR_FILTER_FIELD, 'exists', true); - }); - }); - }); -} diff --git a/test/functional/apps/context/index.ts b/test/functional/apps/context/index.ts index 2cfc8cf855a2d..5cccbf163a8fb 100644 --- a/test/functional/apps/context/index.ts +++ b/test/functional/apps/context/index.ts @@ -33,9 +33,7 @@ export default function ({ getService, getPageObjects, loadTestFile }: FtrProvid loadTestFile(require.resolve('./_context_accessibility')); loadTestFile(require.resolve('./_context_navigation')); loadTestFile(require.resolve('./_discover_navigation')); - loadTestFile(require.resolve('./classic/_discover_navigation')); loadTestFile(require.resolve('./_filters')); - loadTestFile(require.resolve('./classic/_filters')); loadTestFile(require.resolve('./_size')); loadTestFile(require.resolve('./_date_nanos')); loadTestFile(require.resolve('./_date_nanos_custom_timestamp')); diff --git a/test/functional/apps/dashboard/group1/embeddable_data_grid.ts b/test/functional/apps/dashboard/group1/embeddable_data_grid.ts index 07eb00d5817be..014d1dd15ed4f 100644 --- a/test/functional/apps/dashboard/group1/embeddable_data_grid.ts +++ b/test/functional/apps/dashboard/group1/embeddable_data_grid.ts @@ -30,7 +30,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { ); await kibanaServer.uiSettings.replace({ defaultIndex: '0bf35f60-3dc9-11e8-8660-4d65aa086b3c', - 'doc_table:legacy': false, }); await dashboard.navigateToApp(); await filterBar.ensureFieldEditorModalIsClosed(); diff --git a/test/functional/apps/dashboard/group2/dashboard_filter_bar.ts b/test/functional/apps/dashboard/group2/dashboard_filter_bar.ts index e1935a0839966..c80ee8e844cfa 100644 --- a/test/functional/apps/dashboard/group2/dashboard_filter_bar.ts +++ b/test/functional/apps/dashboard/group2/dashboard_filter_bar.ts @@ -23,12 +23,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const browser = getService('browser'); const queryBar = getService('queryBar'); const security = getService('security'); - const { dashboard, discover, header, timePicker } = getPageObjects([ - 'dashboard', - 'discover', - 'header', - 'timePicker', - ]); + const { dashboard, header, timePicker } = getPageObjects(['dashboard', 'header', 'timePicker']); describe('dashboard filter bar', () => { before(async () => { @@ -201,12 +196,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { it('are added when a cell magnifying glass is clicked', async function () { await dashboardAddPanel.addSavedSearch('Rendering-Test:-saved-search'); await dashboard.waitForRenderComplete(); - const isLegacyDefault = await discover.useLegacyTable(); - if (isLegacyDefault) { - await testSubjects.click('docTableCellFilter'); - } else { - await dataGrid.clickCellFilterForButtonExcludingControlColumns(1, 1); - } + await dataGrid.clickCellFilterForButtonExcludingControlColumns(1, 1); const filterCount = await filterBar.getFilterCount(); expect(filterCount).to.equal(1); }); diff --git a/test/functional/apps/dashboard/group3/dashboard_time_picker.ts b/test/functional/apps/dashboard/group3/dashboard_time_picker.ts index 2e5d4217909f0..a1fb468a9dd28 100644 --- a/test/functional/apps/dashboard/group3/dashboard_time_picker.ts +++ b/test/functional/apps/dashboard/group3/dashboard_time_picker.ts @@ -13,16 +13,10 @@ import { PIE_CHART_VIS_NAME } from '../../../page_objects/dashboard_page'; import { FtrProviderContext } from '../../../ftr_provider_context'; export default function ({ getService, getPageObjects }: FtrProviderContext) { - const dashboardExpect = getService('dashboardExpect'); const pieChart = getService('pieChart'); const elasticChart = getService('elasticChart'); const dashboardVisualizations = getService('dashboardVisualizations'); - const { dashboard, header, timePicker, discover } = getPageObjects([ - 'dashboard', - 'header', - 'timePicker', - 'discover', - ]); + const { dashboard, header, timePicker } = getPageObjects(['dashboard', 'header', 'timePicker']); const browser = getService('browser'); const log = getService('log'); const kibanaServer = getService('kibanaServer'); @@ -59,28 +53,13 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { fields: ['bytes', 'agent'], }); - const isLegacyDefault = await discover.useLegacyTable(); - if (isLegacyDefault) { - await dashboardExpect.docTableFieldCount(150); + const docCount = await dataGrid.getDocCount(); + expect(docCount).to.above(10); - // Set to time range with no data - await timePicker.setAbsoluteRange( - 'Jan 1, 2000 @ 00:00:00.000', - 'Jan 1, 2000 @ 01:00:00.000' - ); - await dashboardExpect.docTableFieldCount(0); - } else { - const docCount = await dataGrid.getDocCount(); - expect(docCount).to.above(10); - - // Set to time range with no data - await timePicker.setAbsoluteRange( - 'Jan 1, 2000 @ 00:00:00.000', - 'Jan 1, 2000 @ 01:00:00.000' - ); - const noResults = await dataGrid.hasNoResults(); - expect(noResults).to.be.ok(); - } + // Set to time range with no data + await timePicker.setAbsoluteRange('Jan 1, 2000 @ 00:00:00.000', 'Jan 1, 2000 @ 01:00:00.000'); + const noResults = await dataGrid.hasNoResults(); + expect(noResults).to.be.ok(); }); it('Timepicker start, end, interval values are set by url', async () => { diff --git a/test/functional/apps/discover/classic/_classic_table_doc_navigation.ts b/test/functional/apps/discover/classic/_classic_table_doc_navigation.ts deleted file mode 100644 index c56ecc020f2bf..0000000000000 --- a/test/functional/apps/discover/classic/_classic_table_doc_navigation.ts +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the "Elastic License - * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side - * Public License v 1"; you may not use this file except in compliance with, at - * your election, the "Elastic License 2.0", the "GNU Affero General Public - * License v3.0 only", or the "Server Side Public License, v 1". - */ - -import expect from '@kbn/expect'; - -import { FtrProviderContext } from '../ftr_provider_context'; - -export default function ({ getService, getPageObjects }: FtrProviderContext) { - const docTable = getService('docTable'); - const filterBar = getService('filterBar'); - const testSubjects = getService('testSubjects'); - const { common, discover, timePicker } = getPageObjects(['common', 'discover', 'timePicker']); - const esArchiver = getService('esArchiver'); - const retry = getService('retry'); - const kibanaServer = getService('kibanaServer'); - - describe('classic table doc link', function contextSize() { - before(async () => { - await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/logstash_functional'); - await kibanaServer.importExport.load('test/functional/fixtures/kbn_archiver/discover'); - await timePicker.setDefaultAbsoluteRangeViaUiSettings(); - await kibanaServer.uiSettings.update({ - defaultIndex: 'logstash-*', - 'doc_table:legacy': true, - 'discover:searchFieldsFromSource': true, - }); - }); - after(async () => { - await kibanaServer.importExport.unload('test/functional/fixtures/kbn_archiver/discover'); - await kibanaServer.uiSettings.replace({}); - }); - - beforeEach(async function () { - await timePicker.setDefaultAbsoluteRangeViaUiSettings(); - await common.navigateToApp('discover'); - await discover.waitForDocTableLoadingComplete(); - }); - - it('should open the doc view of the selected document', async function () { - // navigate to the doc view - await docTable.clickRowToggle({ rowIndex: 0 }); - - // click the open action - await retry.try(async () => { - const rowActions = await docTable.getRowActions({ rowIndex: 0 }); - if (!rowActions.length) { - throw new Error('row actions empty, trying again'); - } - await rowActions[1].click(); - }); - - await retry.waitFor('hit loaded', async () => { - const hasDocHit = await testSubjects.exists('doc-hit'); - return !!hasDocHit; - }); - }); - - it('should create an exists filter from the doc view of the selected document', async function () { - await discover.waitUntilSearchingHasFinished(); - - await docTable.toggleRowExpanded(); - const detailsRow = await docTable.getDetailsRow(); - await docTable.addExistsFilter(detailsRow, '@timestamp'); - - const hasExistsFilter = await filterBar.hasFilter('@timestamp', 'exists', true, false, false); - expect(hasExistsFilter).to.be(true); - }); - }); -} diff --git a/test/functional/apps/discover/classic/_discover_fields_api.ts b/test/functional/apps/discover/classic/_discover_fields_api.ts deleted file mode 100644 index e0fe867a25c8b..0000000000000 --- a/test/functional/apps/discover/classic/_discover_fields_api.ts +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the "Elastic License - * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side - * Public License v 1"; you may not use this file except in compliance with, at - * your election, the "Elastic License 2.0", the "GNU Affero General Public - * License v3.0 only", or the "Server Side Public License, v 1". - */ - -import expect from '@kbn/expect'; -import { FtrProviderContext } from '../ftr_provider_context'; - -export default function ({ getService, getPageObjects }: FtrProviderContext) { - const log = getService('log'); - const retry = getService('retry'); - const esArchiver = getService('esArchiver'); - const kibanaServer = getService('kibanaServer'); - const { common, discover, timePicker, settings, unifiedFieldList } = getPageObjects([ - 'common', - 'discover', - 'timePicker', - 'settings', - 'unifiedFieldList', - ]); - const defaultSettings = { - defaultIndex: 'logstash-*', - 'discover:searchFieldsFromSource': false, - 'doc_table:legacy': true, - }; - describe('discover uses fields API test', function describeIndexTests() { - before(async function () { - log.debug('load kibana index with default index pattern'); - await kibanaServer.savedObjects.clean({ types: ['search', 'index-pattern'] }); - await kibanaServer.importExport.load('test/functional/fixtures/kbn_archiver/discover.json'); - await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/logstash_functional'); - await kibanaServer.uiSettings.replace(defaultSettings); - await common.navigateToApp('discover'); - await timePicker.setDefaultAbsoluteRange(); - }); - - after(async () => { - await kibanaServer.uiSettings.replace({}); - }); - - it('should correctly display documents', async function () { - log.debug('check if Document title exists in the grid'); - expect(await discover.getDocHeader()).to.have.string('Document'); - const rowData = await discover.getDocTableIndex(1); - log.debug('check the newest doc timestamp in UTC (check diff timezone in last test)'); - expect(rowData.startsWith('Sep 22, 2015 @ 23:50:13.253')).to.be.ok(); - const expectedHitCount = '14,004'; - await retry.try(async function () { - expect(await discover.getHitCount()).to.be(expectedHitCount); - }); - }); - - it('adding a column removes a default column', async function () { - await unifiedFieldList.clickFieldListItemAdd('_score'); - expect(await discover.getDocHeader()).to.have.string('_score'); - expect(await discover.getDocHeader()).not.to.have.string('Document'); - }); - - it('removing a column adds a default column', async function () { - await unifiedFieldList.clickFieldListItemRemove('_score'); - expect(await discover.getDocHeader()).not.to.have.string('_score'); - expect(await discover.getDocHeader()).to.have.string('Document'); - }); - - it('displays _source viewer in doc viewer', async function () { - await discover.clickDocTableRowToggle(0); - await discover.isShowingDocViewer(); - await discover.clickDocViewerTab('doc_view_source'); - await discover.expectSourceViewerToExist(); - }); - - it('switches to _source column when fields API is no longer used', async function () { - await settings.navigateTo(); - await settings.clickKibanaSettings(); - await settings.toggleAdvancedSettingCheckbox('discover:searchFieldsFromSource'); - - await common.navigateToApp('discover'); - await timePicker.setDefaultAbsoluteRange(); - - expect(await discover.getDocHeader()).to.have.string('_source'); - }); - - it('switches to Document column when fields API is used', async function () { - await settings.navigateTo(); - await settings.clickKibanaSettings(); - await settings.toggleAdvancedSettingCheckbox('discover:searchFieldsFromSource'); - - await common.navigateToApp('discover'); - await timePicker.setDefaultAbsoluteRange(); - - expect(await discover.getDocHeader()).to.have.string('Document'); - }); - }); -} diff --git a/test/functional/apps/discover/classic/_doc_table.ts b/test/functional/apps/discover/classic/_doc_table.ts deleted file mode 100644 index 5c765a6b2ef21..0000000000000 --- a/test/functional/apps/discover/classic/_doc_table.ts +++ /dev/null @@ -1,309 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the "Elastic License - * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side - * Public License v 1"; you may not use this file except in compliance with, at - * your election, the "Elastic License 2.0", the "GNU Affero General Public - * License v3.0 only", or the "Server Side Public License, v 1". - */ - -import expect from '@kbn/expect'; -import { FtrProviderContext } from '../ftr_provider_context'; - -export default function ({ getService, getPageObjects }: FtrProviderContext) { - const browser = getService('browser'); - const log = getService('log'); - const retry = getService('retry'); - const esArchiver = getService('esArchiver'); - const kibanaServer = getService('kibanaServer'); - const docTable = getService('docTable'); - const queryBar = getService('queryBar'); - const find = getService('find'); - const { common, discover, header, timePicker, unifiedFieldList } = getPageObjects([ - 'common', - 'discover', - 'header', - 'timePicker', - 'unifiedFieldList', - ]); - const defaultSettings = { - defaultIndex: 'logstash-*', - hideAnnouncements: true, - 'doc_table:legacy': true, - }; - const testSubjects = getService('testSubjects'); - - describe('discover doc table', function describeIndexTests() { - const rowsHardLimit = 500; - - before(async function () { - log.debug('load kibana index with default index pattern'); - await kibanaServer.savedObjects.cleanStandardList(); - await kibanaServer.importExport.load('test/functional/fixtures/kbn_archiver/discover.json'); - - // and load a set of makelogs data - await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/logstash_functional'); - await kibanaServer.uiSettings.replace(defaultSettings); - await timePicker.setDefaultAbsoluteRangeViaUiSettings(); - log.debug('discover doc table'); - await common.navigateToApp('discover'); - }); - - after(async function () { - await kibanaServer.importExport.unload('test/functional/fixtures/kbn_archiver/discover.json'); - await kibanaServer.savedObjects.cleanStandardList(); - await kibanaServer.uiSettings.replace({}); - }); - - it('should show records by default', async function () { - // with the default range the number of hits is ~14000 - const rows = await discover.getDocTableRows(); - expect(rows.length).to.be.greaterThan(0); - }); - - it('should refresh the table content when changing time window', async function () { - const initialRows = await discover.getDocTableRows(); - - const fromTime = 'Sep 20, 2015 @ 23:00:00.000'; - const toTime = 'Sep 20, 2015 @ 23:14:00.000'; - - await timePicker.setAbsoluteRange(fromTime, toTime); - await discover.waitUntilSearchingHasFinished(); - - const finalRows = await discover.getDocTableRows(); - expect(finalRows.length).to.be.below(initialRows.length); - await timePicker.setDefaultAbsoluteRange(); - }); - - describe('classic table in window 900x700', function () { - before(async () => { - await browser.setWindowSize(900, 700); - await common.navigateToApp('discover'); - await discover.waitUntilSearchingHasFinished(); - }); - - it('should load more rows when scrolling down the document table', async function () { - const initialRows = await testSubjects.findAll('docTableRow'); - await testSubjects.scrollIntoView('discoverBackToTop'); - // now count the rows - await retry.waitFor('next batch of documents to be displayed', async () => { - const actual = await testSubjects.findAll('docTableRow'); - log.debug(`initial doc nr: ${initialRows.length}, actual doc nr: ${actual.length}`); - return actual.length > initialRows.length; - }); - }); - }); - - describe('classic table in window 600x700', function () { - before(async () => { - await browser.setWindowSize(600, 700); - await common.navigateToApp('discover'); - await discover.waitUntilSearchingHasFinished(); - }); - - it('should load more rows when scrolling down the document table', async function () { - const initialRows = await testSubjects.findAll('docTableRow'); - await testSubjects.scrollIntoView('discoverBackToTop'); - // now count the rows - await retry.waitFor('next batch of documents to be displayed', async () => { - const actual = await testSubjects.findAll('docTableRow'); - log.debug(`initial doc nr: ${initialRows.length}, actual doc nr: ${actual.length}`); - return actual.length > initialRows.length; - }); - }); - }); - - describe('legacy', function () { - before(async () => { - await common.navigateToApp('discover'); - await discover.waitUntilSearchingHasFinished(); - }); - after(async () => { - await kibanaServer.uiSettings.replace({}); - }); - it(`should load up to ${rowsHardLimit} rows when scrolling at the end of the table`, async function () { - const initialRows = await testSubjects.findAll('docTableRow'); - // click the Skip to the end of the table - await discover.skipToEndOfDocTable(); - // now count the rows - const finalRows = await testSubjects.findAll('docTableRow'); - expect(finalRows.length).to.be.above(initialRows.length); - expect(finalRows.length).to.be(rowsHardLimit); - await discover.backToTop(); - }); - - it('should go the end and back to top of the classic table when using the accessible buttons', async function () { - // click the Skip to the end of the table - await discover.skipToEndOfDocTable(); - // now check the footer text content - const footer = await discover.getDocTableFooter(); - expect(await footer.getVisibleText()).to.have.string(rowsHardLimit); - await discover.backToTop(); - // check that the skip to end of the table button now has focus - const skipButton = await testSubjects.find('discoverSkipTableButton'); - const activeElement = await find.activeElement(); - const activeElementText = await activeElement.getVisibleText(); - const skipButtonText = await skipButton.getVisibleText(); - expect(skipButtonText === activeElementText).to.be(true); - }); - - describe('expand a document row', function () { - const rowToInspect = 1; - beforeEach(async function () { - // close the toggle if open - const details = await docTable.getDetailsRows(); - if (details.length) { - await docTable.clickRowToggle({ isAnchorRow: false, rowIndex: rowToInspect - 1 }); - } - }); - - it('should expand the detail row when the toggle arrow is clicked', async function () { - await retry.try(async function () { - await docTable.clickRowToggle({ isAnchorRow: false, rowIndex: rowToInspect - 1 }); - const detailsEl = await docTable.getDetailsRows(); - const defaultMessageEl = await detailsEl[0].findByTestSubject( - 'docViewerRowDetailsTitle' - ); - expect(defaultMessageEl).to.be.ok(); - }); - }); - - it('should show the detail panel actions', async function () { - await retry.try(async function () { - await docTable.clickRowToggle({ isAnchorRow: false, rowIndex: rowToInspect - 1 }); - // const detailsEl = await discover.getDocTableRowDetails(rowToInspect); - const [surroundingActionEl, singleActionEl] = await docTable.getRowActions({ - isAnchorRow: false, - rowIndex: rowToInspect - 1, - }); - expect(surroundingActionEl).to.be.ok(); - expect(singleActionEl).to.be.ok(); - // TODO: test something more meaninful here? - }); - }); - - it('should not close the detail panel actions when data is re-requested', async function () { - await retry.try(async function () { - const nrOfFetches = await discover.getNrOfFetches(); - await docTable.clickRowToggle({ isAnchorRow: false, rowIndex: rowToInspect - 1 }); - const detailsEl = await docTable.getDetailsRows(); - const defaultMessageEl = await detailsEl[0].findByTestSubject( - 'docViewerRowDetailsTitle' - ); - expect(defaultMessageEl).to.be.ok(); - await queryBar.submitQuery(); - const nrOfFetchesResubmit = await discover.getNrOfFetches(); - expect(nrOfFetchesResubmit).to.be.above(nrOfFetches); - const defaultMessageElResubmit = await detailsEl[0].findByTestSubject( - 'docViewerRowDetailsTitle' - ); - - expect(defaultMessageElResubmit).to.be.ok(); - }); - }); - - it('should show allow toggling columns from the expanded document', async function () { - await discover.clickNewSearchButton(); - await retry.try(async function () { - await docTable.clickRowToggle({ isAnchorRow: false, rowIndex: rowToInspect - 1 }); - - // add columns - const fields = ['_id', '_index', 'agent']; - for (const field of fields) { - await testSubjects.click(`toggleColumnButton-${field}`); - await testSubjects.click(`tableDocViewRow-${field}`); // to suppress the appeared tooltip - } - - const headerWithFields = await docTable.getHeaderFields(); - expect(headerWithFields.join(' ')).to.contain(fields.join(' ')); - - // remove columns - for (const field of fields) { - await testSubjects.click(`toggleColumnButton-${field}`); - await testSubjects.click(`tableDocViewRow-${field}`); - } - - const headerWithoutFields = await docTable.getHeaderFields(); - expect(headerWithoutFields.join(' ')).not.to.contain(fields.join(' ')); - }); - }); - }); - - describe('add and remove columns', function () { - const extraColumns = ['phpmemory', 'ip']; - const expectedFieldLength: Record = { - phpmemory: 1, - ip: 4, - }; - afterEach(async function () { - for (const column of extraColumns) { - await unifiedFieldList.clickFieldListItemRemove(column); - await header.waitUntilLoadingHasFinished(); - } - }); - - it('should add more columns to the table', async function () { - for (const column of extraColumns) { - await unifiedFieldList.clearFieldSearchInput(); - await unifiedFieldList.findFieldByName(column); - await unifiedFieldList.waitUntilFieldlistHasCountOfFields(expectedFieldLength[column]); - await retry.waitFor('field to appear', async function () { - return await testSubjects.exists(`field-${column}`); - }); - await unifiedFieldList.clickFieldListItemAdd(column); - await header.waitUntilLoadingHasFinished(); - // test the header now - const docHeader = await find.byCssSelector('thead > tr:nth-child(1)'); - const docHeaderText = await docHeader.getVisibleText(); - expect(docHeaderText).to.have.string(column); - } - }); - - it('should remove columns from the table', async function () { - for (const column of extraColumns) { - await unifiedFieldList.clearFieldSearchInput(); - await unifiedFieldList.findFieldByName(column); - await unifiedFieldList.waitUntilFieldlistHasCountOfFields(expectedFieldLength[column]); - await unifiedFieldList.clickFieldListItemAdd(column); - await header.waitUntilLoadingHasFinished(); - } - // remove the second column - await unifiedFieldList.clickFieldListItemRemove(extraColumns[1]); - await header.waitUntilLoadingHasFinished(); - // test that the second column is no longer there - const docHeader = await find.byCssSelector('thead > tr:nth-child(1)'); - expect(await docHeader.getVisibleText()).to.not.have.string(extraColumns[1]); - }); - }); - - it('should make the document table scrollable', async function () { - await unifiedFieldList.clearFieldSearchInput(); - const dscTableWrapper = await find.byCssSelector('.kbnDocTableWrapper'); - const fieldNames = await unifiedFieldList.getAllFieldNames(); - const clientHeight = await dscTableWrapper.getAttribute('clientHeight'); - let fieldCounter = 0; - const checkScrollable = async () => { - const scrollWidth = await dscTableWrapper.getAttribute('scrollWidth'); - const clientWidth = await dscTableWrapper.getAttribute('clientWidth'); - log.debug(`scrollWidth: ${scrollWidth}, clientWidth: ${clientWidth}`); - return Number(scrollWidth) > Number(clientWidth); - }; - const addColumn = async () => { - await unifiedFieldList.clickFieldListItemAdd(fieldNames[fieldCounter++]); - }; - - await addColumn(); - const isScrollable = await checkScrollable(); - expect(isScrollable).to.be(false); - - await retry.waitForWithTimeout('container to be scrollable', 60 * 1000, async () => { - await addColumn(); - return await checkScrollable(); - }); - // so now we need to check if the horizontal scrollbar is displayed - const newClientHeight = await dscTableWrapper.getAttribute('clientHeight'); - expect(Number(clientHeight)).to.be.above(Number(newClientHeight)); - }); - }); - }); -} diff --git a/test/functional/apps/discover/classic/_doc_table_newline.ts b/test/functional/apps/discover/classic/_doc_table_newline.ts deleted file mode 100644 index 3c2b426a2dbe4..0000000000000 --- a/test/functional/apps/discover/classic/_doc_table_newline.ts +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the "Elastic License - * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side - * Public License v 1"; you may not use this file except in compliance with, at - * your election, the "Elastic License 2.0", the "GNU Affero General Public - * License v3.0 only", or the "Server Side Public License, v 1". - */ - -import { FtrProviderContext } from '../ftr_provider_context'; - -export default function ({ getService, getPageObjects }: FtrProviderContext) { - const esArchiver = getService('esArchiver'); - const kibanaServer = getService('kibanaServer'); - const { common, unifiedFieldList } = getPageObjects(['common', 'unifiedFieldList']); - const find = getService('find'); - const log = getService('log'); - const retry = getService('retry'); - const security = getService('security'); - - describe('discover doc table newline handling', function describeIndexTests() { - before(async function () { - await security.testUser.setRoles(['kibana_admin', 'kibana_message_with_newline']); - await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/message_with_newline'); - await kibanaServer.importExport.load( - 'test/functional/fixtures/kbn_archiver/message_with_newline.json' - ); - await kibanaServer.uiSettings.replace({ - defaultIndex: 'newline-test', - 'doc_table:legacy': true, - }); - await common.navigateToApp('discover'); - }); - - after(async () => { - await security.testUser.restoreDefaults(); - await esArchiver.unload('test/functional/fixtures/es_archiver/message_with_newline'); - await kibanaServer.savedObjects.cleanStandardList(); - await kibanaServer.uiSettings.replace({}); - }); - - it('should break text on newlines', async function () { - await unifiedFieldList.clickFieldListItemToggle('message'); - const dscTableRows = await find.allByCssSelector('.kbnDocTable__row'); - - await retry.waitFor('height of multi-line content > single-line content', async () => { - const heightWithoutNewline = await dscTableRows[0].getAttribute('clientHeight'); - const heightWithNewline = await dscTableRows[1].getAttribute('clientHeight'); - log.debug(`Without newlines: ${heightWithoutNewline}, With newlines: ${heightWithNewline}`); - - await common.sleep(10000); - return Number(heightWithNewline) > Number(heightWithoutNewline); - }); - }); - }); -} diff --git a/test/functional/apps/discover/classic/_esql_grid.ts b/test/functional/apps/discover/classic/_esql_grid.ts deleted file mode 100644 index 94dcabdba4efc..0000000000000 --- a/test/functional/apps/discover/classic/_esql_grid.ts +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the "Elastic License - * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side - * Public License v 1"; you may not use this file except in compliance with, at - * your election, the "Elastic License 2.0", the "GNU Affero General Public - * License v3.0 only", or the "Server Side Public License, v 1". - */ - -import { FtrProviderContext } from '../ftr_provider_context'; - -export default function ({ getService, getPageObjects }: FtrProviderContext) { - const esArchiver = getService('esArchiver'); - const kibanaServer = getService('kibanaServer'); - const testSubjects = getService('testSubjects'); - const security = getService('security'); - const dataGrid = getService('dataGrid'); - const dashboardAddPanel = getService('dashboardAddPanel'); - const dashboardPanelActions = getService('dashboardPanelActions'); - const { common, discover, dashboard, header, timePicker } = getPageObjects([ - 'common', - 'discover', - 'dashboard', - 'header', - 'timePicker', - ]); - - const defaultSettings = { - defaultIndex: 'logstash-*', - 'doc_table:legacy': true, - }; - - describe('discover esql grid with legacy setting', function () { - before(async () => { - await security.testUser.setRoles(['kibana_admin', 'test_logstash_reader']); - await kibanaServer.importExport.load('test/functional/fixtures/kbn_archiver/discover'); - await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/logstash_functional'); - await kibanaServer.uiSettings.replace(defaultSettings); - await common.navigateToApp('discover'); - await timePicker.setDefaultAbsoluteRange(); - }); - - after(async () => { - await kibanaServer.savedObjects.cleanStandardList(); - await kibanaServer.importExport.unload('test/functional/fixtures/kbn_archiver/discover'); - await esArchiver.unload('test/functional/fixtures/es_archiver/logstash_functional'); - await kibanaServer.uiSettings.replace({}); - }); - - it('should render esql view correctly', async function () { - const savedSearchESQL = 'testESQLWithLegacySetting'; - await header.waitUntilLoadingHasFinished(); - await discover.waitUntilSearchingHasFinished(); - - await testSubjects.existOrFail('docTableHeader'); - await testSubjects.missingOrFail('euiDataGridBody'); - - await discover.selectTextBaseLang(); - - await header.waitUntilLoadingHasFinished(); - await discover.waitUntilSearchingHasFinished(); - - await testSubjects.missingOrFail('docTableHeader'); - await testSubjects.existOrFail('euiDataGridBody'); - - await dataGrid.clickRowToggle({ rowIndex: 0 }); - - await testSubjects.existOrFail('docViewerFlyout'); - - await discover.saveSearch(savedSearchESQL); - - await common.navigateToApp('dashboard'); - await dashboard.clickNewDashboard(); - await timePicker.setDefaultAbsoluteRange(); - await dashboardAddPanel.clickOpenAddPanel(); - await dashboardAddPanel.addSavedSearch(savedSearchESQL); - await header.waitUntilLoadingHasFinished(); - - await testSubjects.missingOrFail('docTableHeader'); - await testSubjects.existOrFail('euiDataGridBody'); - - await dataGrid.clickRowToggle({ rowIndex: 0 }); - - await testSubjects.existOrFail('docViewerFlyout'); - - await dashboardPanelActions.removePanelByTitle(savedSearchESQL); - - await dashboardAddPanel.addSavedSearch('A Saved Search'); - - await header.waitUntilLoadingHasFinished(); - await testSubjects.existOrFail('docTableHeader'); - await testSubjects.missingOrFail('euiDataGridBody'); - }); - }); -} diff --git a/test/functional/apps/discover/classic/_field_data.ts b/test/functional/apps/discover/classic/_field_data.ts deleted file mode 100644 index 2ebd49bb24ae2..0000000000000 --- a/test/functional/apps/discover/classic/_field_data.ts +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the "Elastic License - * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side - * Public License v 1"; you may not use this file except in compliance with, at - * your election, the "Elastic License 2.0", the "GNU Affero General Public - * License v3.0 only", or the "Server Side Public License, v 1". - */ - -import expect from '@kbn/expect'; - -import { FtrProviderContext } from '../ftr_provider_context'; - -export default function ({ getService, getPageObjects }: FtrProviderContext) { - const retry = getService('retry'); - const esArchiver = getService('esArchiver'); - const kibanaServer = getService('kibanaServer'); - const { common, timePicker } = getPageObjects(['common', 'timePicker']); - const find = getService('find'); - const testSubjects = getService('testSubjects'); - - describe('discover tab', function describeIndexTests() { - this.tags('includeFirefox'); - before(async function () { - await kibanaServer.savedObjects.clean({ types: ['search', 'index-pattern'] }); - await kibanaServer.importExport.load('test/functional/fixtures/kbn_archiver/discover.json'); - await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/logstash_functional'); - await kibanaServer.uiSettings.replace({ - defaultIndex: 'logstash-*', - 'discover:searchFieldsFromSource': true, - 'doc_table:legacy': true, - }); - await timePicker.setDefaultAbsoluteRangeViaUiSettings(); - await common.navigateToApp('discover'); - }); - - after(async function () { - await kibanaServer.uiSettings.replace({}); - }); - - it('doc view should show @timestamp and _source columns', async function () { - const expectedHeader = '@timestamp\n_source'; - const docHeader = await find.byCssSelector('thead > tr:nth-child(1)'); - const docHeaderText = await docHeader.getVisibleText(); - expect(docHeaderText).to.be(expectedHeader); - }); - - it('doc view should sort ascending', async function () { - const expectedTimeStamp = 'Sep 20, 2015 @ 00:00:00.000'; - await testSubjects.click('docTableHeaderFieldSort_@timestamp'); - - // we don't technically need this sleep here because the tryForTime will retry and the - // results will match on the 2nd or 3rd attempt, but that debug output is huge in this - // case and it can be avoided with just a few seconds sleep. - await common.sleep(2000); - await retry.try(async function tryingForTime() { - const row = await find.byCssSelector(`tr.kbnDocTable__row:nth-child(1)`); - const rowData = await row.getVisibleText(); - expect(rowData.startsWith(expectedTimeStamp)).to.be.ok(); - }); - }); - }); -} diff --git a/test/functional/apps/discover/classic/_field_data_with_fields_api.ts b/test/functional/apps/discover/classic/_field_data_with_fields_api.ts deleted file mode 100644 index 4932ba3e24348..0000000000000 --- a/test/functional/apps/discover/classic/_field_data_with_fields_api.ts +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the "Elastic License - * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side - * Public License v 1"; you may not use this file except in compliance with, at - * your election, the "Elastic License 2.0", the "GNU Affero General Public - * License v3.0 only", or the "Server Side Public License, v 1". - */ - -import expect from '@kbn/expect'; - -import { FtrProviderContext } from '../ftr_provider_context'; - -export default function ({ getService, getPageObjects }: FtrProviderContext) { - const retry = getService('retry'); - const kibanaServer = getService('kibanaServer'); - const { common, timePicker } = getPageObjects(['common', 'timePicker']); - const find = getService('find'); - const esArchiver = getService('esArchiver'); - const testSubjects = getService('testSubjects'); - - describe('discover tab with new fields API', function describeIndexTests() { - before(async function () { - await kibanaServer.savedObjects.clean({ types: ['search', 'index-pattern'] }); - await kibanaServer.importExport.load('test/functional/fixtures/kbn_archiver/discover.json'); - await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/logstash_functional'); - await kibanaServer.uiSettings.replace({ - defaultIndex: 'logstash-*', - 'discover:searchFieldsFromSource': false, - 'doc_table:legacy': true, - }); - await timePicker.setDefaultAbsoluteRangeViaUiSettings(); - await common.navigateToApp('discover'); - }); - - after(async function () { - await kibanaServer.uiSettings.replace({}); - }); - - it('doc view should sort ascending', async function () { - const expectedTimeStamp = 'Sep 20, 2015 @ 00:00:00.000'; - await testSubjects.click('docTableHeaderFieldSort_@timestamp'); - - // we don't technically need this sleep here because the tryForTime will retry and the - // results will match on the 2nd or 3rd attempt, but that debug output is huge in this - // case and it can be avoided with just a few seconds sleep. - await common.sleep(2000); - await retry.try(async function tryingForTime() { - const row = await find.byCssSelector(`tr.kbnDocTable__row:nth-child(1)`); - const rowData = await row.getVisibleText(); - - expect(rowData.startsWith(expectedTimeStamp)).to.be.ok(); - }); - }); - }); -} diff --git a/test/functional/apps/discover/classic/_hide_announcements.ts b/test/functional/apps/discover/classic/_hide_announcements.ts deleted file mode 100644 index df7fcbb628136..0000000000000 --- a/test/functional/apps/discover/classic/_hide_announcements.ts +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the "Elastic License - * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side - * Public License v 1"; you may not use this file except in compliance with, at - * your election, the "Elastic License 2.0", the "GNU Affero General Public - * License v3.0 only", or the "Server Side Public License, v 1". - */ - -import expect from '@kbn/expect'; -import { FtrProviderContext } from '../ftr_provider_context'; - -export default function ({ getService, getPageObjects }: FtrProviderContext) { - const esArchiver = getService('esArchiver'); - const { common, discover, timePicker } = getPageObjects(['common', 'discover', 'timePicker']); - const kibanaServer = getService('kibanaServer'); - const testSubjects = getService('testSubjects'); - const browser = getService('browser'); - - describe('test hide announcements', function () { - before(async function () { - await kibanaServer.importExport.load('test/functional/fixtures/kbn_archiver/discover.json'); - await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/logstash_functional'); - await kibanaServer.uiSettings.replace({ - defaultIndex: 'logstash-*', - 'doc_table:legacy': true, - }); - await common.navigateToApp('discover'); - await timePicker.setDefaultAbsoluteRange(); - }); - - after(async () => { - await kibanaServer.uiSettings.replace({}); - }); - - it('should display try document explorer button', async function () { - await discover.selectIndexPattern('logstash-*'); - const tourButtonExists = await testSubjects.exists('tryDocumentExplorerButton'); - expect(tourButtonExists).to.be(true); - }); - - it('should not display try document explorer button', async function () { - await kibanaServer.uiSettings.update({ hideAnnouncements: true }); - await browser.refresh(); - const tourButtonExists = await testSubjects.exists('tryDocumentExplorerButton'); - expect(tourButtonExists).to.be(false); - }); - }); -} diff --git a/test/functional/apps/discover/classic/index.ts b/test/functional/apps/discover/classic/index.ts deleted file mode 100644 index fce8963d19082..0000000000000 --- a/test/functional/apps/discover/classic/index.ts +++ /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", the "GNU Affero General Public License v3.0 only", and the "Server Side - * Public License v 1"; you may not use this file except in compliance with, at - * your election, the "Elastic License 2.0", the "GNU Affero General Public - * License v3.0 only", or the "Server Side Public License, v 1". - */ - -import { FtrProviderContext } from '../ftr_provider_context'; - -export default function ({ getService, loadTestFile }: FtrProviderContext) { - const esArchiver = getService('esArchiver'); - const browser = getService('browser'); - - describe('discover/classic', function () { - before(async function () { - await browser.setWindowSize(1300, 800); - }); - - after(async function unloadMakelogs() { - await esArchiver.unload('test/functional/fixtures/es_archiver/logstash_functional'); - }); - - loadTestFile(require.resolve('./_discover_fields_api')); - loadTestFile(require.resolve('./_doc_table')); - loadTestFile(require.resolve('./_doc_table_newline')); - loadTestFile(require.resolve('./_field_data')); - loadTestFile(require.resolve('./_field_data_with_fields_api')); - loadTestFile(require.resolve('./_classic_table_doc_navigation')); - loadTestFile(require.resolve('./_hide_announcements')); - loadTestFile(require.resolve('./_esql_grid')); - }); -} diff --git a/test/functional/apps/discover/group1/_date_nanos_mixed.ts b/test/functional/apps/discover/group1/_date_nanos_mixed.ts index 7162d01bb96cc..a30c4a316351c 100644 --- a/test/functional/apps/discover/group1/_date_nanos_mixed.ts +++ b/test/functional/apps/discover/group1/_date_nanos_mixed.ts @@ -45,14 +45,13 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); it('shows a list of records of indices with date & date_nanos fields in the right order', async function () { - const isLegacy = await discover.useLegacyTable(); const rowData1 = await discover.getDocTableIndex(1); expect(rowData1).to.contain('Jan 1, 2019 @ 12:10:30.124000000'); - const rowData2 = await discover.getDocTableIndex(isLegacy ? 3 : 2); + const rowData2 = await discover.getDocTableIndex(2); expect(rowData2).to.contain('Jan 1, 2019 @ 12:10:30.123498765'); - const rowData3 = await discover.getDocTableIndex(isLegacy ? 5 : 3); + const rowData3 = await discover.getDocTableIndex(3); expect(rowData3).to.contain('Jan 1, 2019 @ 12:10:30.123456789'); - const rowData4 = await discover.getDocTableIndex(isLegacy ? 7 : 4); + const rowData4 = await discover.getDocTableIndex(4); expect(rowData4).to.contain('Jan 1, 2019 @ 12:10:30.123000000'); }); }); diff --git a/test/functional/apps/discover/group2_data_grid3/_data_grid_density.ts b/test/functional/apps/discover/group2_data_grid3/_data_grid_density.ts index b50cd7e16cf01..e801b40a80036 100644 --- a/test/functional/apps/discover/group2_data_grid3/_data_grid_density.ts +++ b/test/functional/apps/discover/group2_data_grid3/_data_grid_density.ts @@ -52,9 +52,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await dataGrid.changeDensityValue('Normal'); // toggle the popover - // Right now changing the density closes the popover (see packages/kbn-unified-data-table/src/components/data_table.tsx:1144) - // When that workaround is removed we will need to uncomment this next line - // await dataGrid.clickGridSettings(); + await dataGrid.clickGridSettings(); await dataGrid.clickGridSettings(); expect(await dataGrid.getCurrentDensityValue()).to.be('Normal'); }); @@ -62,7 +60,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { it('should persist the density selection after reloading the page', async () => { await dataGrid.clickGridSettings(); await dataGrid.changeDensityValue('Expanded'); - await dataGrid.clickGridSettings(); expect(await dataGrid.getCurrentDensityValue()).to.be('Expanded'); await browser.refresh(); diff --git a/test/functional/apps/discover/group6/_sidebar.ts b/test/functional/apps/discover/group6/_sidebar.ts index a88623bb58d12..01adcb7a0a907 100644 --- a/test/functional/apps/discover/group6/_sidebar.ts +++ b/test/functional/apps/discover/group6/_sidebar.ts @@ -28,10 +28,27 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const filterBar = getService('filterBar'); const fieldEditor = getService('fieldEditor'); const dataViews = getService('dataViews'); + const queryBar = getService('queryBar'); const retry = getService('retry'); const dataGrid = getService('dataGrid'); + const log = getService('log'); const INITIAL_FIELD_LIST_SUMMARY = '48 available fields. 5 empty fields. 4 meta fields.'; + const expectFieldListDescription = async (expectedNumber: string) => { + return await retry.try(async () => { + await discover.waitUntilSearchingHasFinished(); + await unifiedFieldList.waitUntilSidebarHasLoaded(); + const ariaDescription = await unifiedFieldList.getSidebarAriaDescription(); + if (ariaDescription !== expectedNumber) { + log.warning( + `Expected Sidebar Aria Description: ${expectedNumber}, got: ${ariaDescription}` + ); + await queryBar.submitQuery(); + } + expect(ariaDescription).to.be(expectedNumber); + }); + }; + describe('discover sidebar', function describeIndexTests() { before(async function () { await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/logstash_functional'); @@ -65,35 +82,21 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await unifiedFieldList.waitUntilSidebarHasLoaded(); await unifiedFieldList.openSidebarFieldFilter(); - expect(await unifiedFieldList.getSidebarAriaDescription()).to.be( - INITIAL_FIELD_LIST_SUMMARY - ); + await expectFieldListDescription(INITIAL_FIELD_LIST_SUMMARY); await testSubjects.click('typeFilter-keyword'); - - await retry.waitFor('first updates', async () => { - return ( - (await unifiedFieldList.getSidebarAriaDescription()) === - '6 available fields. 1 empty field. 3 meta fields.' - ); - }); + // first update + await expectFieldListDescription('6 available fields. 1 empty field. 3 meta fields.'); await testSubjects.click('typeFilter-number'); - await retry.waitFor('second updates', async () => { - return ( - (await unifiedFieldList.getSidebarAriaDescription()) === - '10 available fields. 3 empty fields. 4 meta fields.' - ); - }); + // second update + await expectFieldListDescription('10 available fields. 3 empty fields. 4 meta fields.'); await testSubjects.click('fieldListFiltersFieldTypeFilterClearAll'); - await retry.waitFor('reset', async () => { - return ( - (await unifiedFieldList.getSidebarAriaDescription()) === INITIAL_FIELD_LIST_SUMMARY - ); - }); + // reset + await expectFieldListDescription(INITIAL_FIELD_LIST_SUMMARY); }); it('should show filters by type in ES|QL view', async function () { @@ -114,18 +117,9 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { options = await find.allByCssSelector('[data-test-subj*="typeFilter"]'); expect(options).to.have.length(6); - expect(await unifiedFieldList.getSidebarAriaDescription()).to.be( - '76 available fields. 6 empty fields.' - ); - + await expectFieldListDescription('76 available fields. 6 empty fields.'); await testSubjects.click('typeFilter-number'); - - await retry.waitFor('updates', async () => { - return ( - (await unifiedFieldList.getSidebarAriaDescription()) === - '4 available fields. 2 empty fields.' - ); - }); + await expectFieldListDescription('4 available fields. 2 empty fields.'); }); it('should show empty fields in ES|QL view', async function () { @@ -138,52 +132,29 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await header.waitUntilLoadingHasFinished(); await unifiedFieldList.waitUntilSidebarHasLoaded(); await unifiedFieldList.openSidebarFieldFilter(); - - expect(await unifiedFieldList.getSidebarAriaDescription()).to.be( - '2 selected fields. 1 available field. 1 empty field.' - ); + await expectFieldListDescription('2 selected fields. 1 available field. 1 empty field.'); }); }); describe('search', function () { beforeEach(async () => { - await header.waitUntilLoadingHasFinished(); - await unifiedFieldList.waitUntilSidebarHasLoaded(); - - expect(await unifiedFieldList.getSidebarAriaDescription()).to.be( - INITIAL_FIELD_LIST_SUMMARY - ); + await expectFieldListDescription(INITIAL_FIELD_LIST_SUMMARY); }); afterEach(async () => { const fieldSearch = await testSubjects.find('clearSearchButton'); await fieldSearch.click(); - await retry.waitFor('reset', async () => { - return ( - (await unifiedFieldList.getSidebarAriaDescription()) === INITIAL_FIELD_LIST_SUMMARY - ); - }); + // reset + await expectFieldListDescription(INITIAL_FIELD_LIST_SUMMARY); }); it('should be able to search by string', async function () { await unifiedFieldList.findFieldByName('i'); - await retry.waitFor('first updates', async () => { - return ( - (await unifiedFieldList.getSidebarAriaDescription()) === - '28 available fields. 2 empty fields. 3 meta fields.' - ); - }); - + await expectFieldListDescription('28 available fields. 2 empty fields. 3 meta fields.'); await unifiedFieldList.findFieldByName('p'); - - await retry.waitFor('second updates', async () => { - return ( - (await unifiedFieldList.getSidebarAriaDescription()) === - '4 available fields. 0 meta fields.' - ); - }); + await expectFieldListDescription('4 available fields. 0 meta fields.'); expect((await unifiedFieldList.getSidebarSectionFieldNames('available')).join(', ')).to.be( 'clientip, ip, relatedContent.og:description, relatedContent.twitter:description' @@ -192,13 +163,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { it('should be able to search by wildcard', async function () { await unifiedFieldList.findFieldByName('relatedContent*image'); - - await retry.waitFor('updates', async () => { - return ( - (await unifiedFieldList.getSidebarAriaDescription()) === - '2 available fields. 0 meta fields.' - ); - }); + await expectFieldListDescription('2 available fields. 0 meta fields.'); expect((await unifiedFieldList.getSidebarSectionFieldNames('available')).join(', ')).to.be( 'relatedContent.og:image, relatedContent.twitter:image' @@ -208,12 +173,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { it('should be able to search with spaces as wildcard', async function () { await unifiedFieldList.findFieldByName('relatedContent image'); - await retry.waitFor('updates', async () => { - return ( - (await unifiedFieldList.getSidebarAriaDescription()) === - '4 available fields. 0 meta fields.' - ); - }); + await expectFieldListDescription('4 available fields. 0 meta fields.'); expect((await unifiedFieldList.getSidebarSectionFieldNames('available')).join(', ')).to.be( 'relatedContent.og:image, relatedContent.og:image:height, relatedContent.og:image:width, relatedContent.twitter:image' @@ -222,13 +182,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { it('should be able to search with fuzzy search (1 typo)', async function () { await unifiedFieldList.findFieldByName('rel4tedContent.art'); - - await retry.waitFor('updates', async () => { - return ( - (await unifiedFieldList.getSidebarAriaDescription()) === - '4 available fields. 0 meta fields.' - ); - }); + await expectFieldListDescription('4 available fields. 0 meta fields.'); expect((await unifiedFieldList.getSidebarSectionFieldNames('available')).join(', ')).to.be( 'relatedContent.article:modified_time, relatedContent.article:published_time, relatedContent.article:section, relatedContent.article:tag' @@ -243,9 +197,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); // expect no changes in the list - expect(await unifiedFieldList.getSidebarAriaDescription()).to.be( - INITIAL_FIELD_LIST_SUMMARY - ); + await expectFieldListDescription(INITIAL_FIELD_LIST_SUMMARY); }); }); @@ -345,10 +297,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { expect((await unifiedFieldList.getSidebarSectionFieldNames('meta')).join(', ')).to.be( '_id, _ignored, _index, _score' ); - - expect(await unifiedFieldList.getSidebarAriaDescription()).to.be( - INITIAL_FIELD_LIST_SUMMARY - ); + await expectFieldListDescription(INITIAL_FIELD_LIST_SUMMARY); }); it('should show field list groups excluding subfields when searched from source', async function () { @@ -387,7 +336,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { 'relatedContent' ); - expect(await unifiedFieldList.getSidebarAriaDescription()).to.be( + await expectFieldListDescription( '48 available fields. 1 unmapped field. 5 empty fields. 4 meta fields.' ); }); @@ -406,7 +355,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { expect(availableFields.includes('extension')).to.be(true); expect(availableFields.includes('@message')).to.be(true); - expect(await unifiedFieldList.getSidebarAriaDescription()).to.be( + await expectFieldListDescription( '2 selected fields. 2 popular fields. 48 available fields. 5 empty fields. 4 meta fields.' ); @@ -426,52 +375,35 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { '@message, _id, extension' ); - expect(await unifiedFieldList.getSidebarAriaDescription()).to.be( + await expectFieldListDescription( '3 selected fields. 3 popular fields. 48 available fields. 5 empty fields. 4 meta fields.' ); // verify popular fields were persisted await browser.refresh(); - await unifiedFieldList.waitUntilSidebarHasLoaded(); - expect(await unifiedFieldList.getSidebarAriaDescription()).to.be( + await expectFieldListDescription( '3 selected fields. 3 popular fields. 48 available fields. 5 empty fields. 4 meta fields.' ); }); it('should show selected and available fields in ES|QL mode', async function () { - await unifiedFieldList.waitUntilSidebarHasLoaded(); - - expect(await unifiedFieldList.getSidebarAriaDescription()).to.be( - INITIAL_FIELD_LIST_SUMMARY - ); + await expectFieldListDescription(INITIAL_FIELD_LIST_SUMMARY); await discover.selectTextBaseLang(); await monacoEditor.setCodeEditorValue('from logstash-* | limit 10000'); await testSubjects.click('querySubmitButton'); - await header.waitUntilLoadingHasFinished(); - await unifiedFieldList.waitUntilSidebarHasLoaded(); - - expect(await unifiedFieldList.getSidebarAriaDescription()).to.be( - '76 available fields. 6 empty fields.' - ); + await expectFieldListDescription('76 available fields. 6 empty fields.'); await unifiedFieldList.clickFieldListItemRemove('extension'); - await unifiedFieldList.waitUntilSidebarHasLoaded(); - expect(await unifiedFieldList.getSidebarAriaDescription()).to.be( - '76 available fields. 6 empty fields.' - ); + await expectFieldListDescription('76 available fields. 6 empty fields.'); const testQuery = `from logstash-* | limit 10 | stats countB = count(bytes) by geo.dest | sort countB`; await monacoEditor.setCodeEditorValue(testQuery); await testSubjects.click('querySubmitButton'); - await header.waitUntilLoadingHasFinished(); - await unifiedFieldList.waitUntilSidebarHasLoaded(); - expect(await unifiedFieldList.getSidebarAriaDescription()).to.be( - '2 selected fields. 2 available fields.' - ); + await expectFieldListDescription('2 selected fields. 2 available fields.'); expect((await unifiedFieldList.getSidebarSectionFieldNames('selected')).join(', ')).to.be( 'countB, geo.dest' ); @@ -480,12 +412,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await unifiedSearch.switchDataView('discover-dataView-switch-link', 'logstash-*'); - await header.waitUntilLoadingHasFinished(); - await unifiedFieldList.waitUntilSidebarHasLoaded(); - - expect(await unifiedFieldList.getSidebarAriaDescription()).to.be( - '48 available fields. 5 empty fields. 4 meta fields.' - ); + await expectFieldListDescription('48 available fields. 5 empty fields. 4 meta fields.'); }); it('should work correctly for a data view for a missing index', async function () { @@ -494,20 +421,11 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { 'test/functional/fixtures/kbn_archiver/index_pattern_without_timefield' ); await browser.refresh(); - await unifiedFieldList.waitUntilSidebarHasLoaded(); - - expect(await unifiedFieldList.getSidebarAriaDescription()).to.be( - INITIAL_FIELD_LIST_SUMMARY - ); + await expectFieldListDescription(INITIAL_FIELD_LIST_SUMMARY); await dataViews.switchToAndValidate('with-timefield'); - await header.waitUntilLoadingHasFinished(); - await unifiedFieldList.waitUntilSidebarHasLoaded(); - - expect(await unifiedFieldList.getSidebarAriaDescription()).to.be( - '0 available fields. 0 meta fields.' - ); + await expectFieldListDescription('0 available fields. 0 meta fields.'); await testSubjects.missingOrFail( `${unifiedFieldList.getSidebarSectionSelector('available')}-fetchWarning` ); @@ -517,12 +435,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await dataViews.switchToAndValidate('logstash-*'); - await header.waitUntilLoadingHasFinished(); - await unifiedFieldList.waitUntilSidebarHasLoaded(); - - expect(await unifiedFieldList.getSidebarAriaDescription()).to.be( - INITIAL_FIELD_LIST_SUMMARY - ); + await expectFieldListDescription(INITIAL_FIELD_LIST_SUMMARY); await kibanaServer.importExport.unload( 'test/functional/fixtures/kbn_archiver/index_pattern_without_timefield' ); @@ -537,41 +450,22 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { ); await browser.refresh(); - await unifiedFieldList.waitUntilSidebarHasLoaded(); - - expect(await unifiedFieldList.getSidebarAriaDescription()).to.be( - INITIAL_FIELD_LIST_SUMMARY - ); + await expectFieldListDescription(INITIAL_FIELD_LIST_SUMMARY); await dataViews.switchToAndValidate('without-timefield'); - await header.waitUntilLoadingHasFinished(); - await unifiedFieldList.waitUntilSidebarHasLoaded(); - - expect(await unifiedFieldList.getSidebarAriaDescription()).to.be( - '6 available fields. 4 meta fields.' - ); + await expectFieldListDescription('6 available fields. 4 meta fields.'); await dataViews.switchToAndValidate('with-timefield'); - await header.waitUntilLoadingHasFinished(); - await unifiedFieldList.waitUntilSidebarHasLoaded(); - - expect(await unifiedFieldList.getSidebarAriaDescription()).to.be( - '0 available fields. 7 empty fields. 4 meta fields.' - ); + await expectFieldListDescription('0 available fields. 7 empty fields. 4 meta fields.'); await testSubjects.existOrFail( `${unifiedFieldList.getSidebarSectionSelector('available')}NoFieldsCallout-noFieldsMatch` ); await dataViews.switchToAndValidate('logstash-*'); - await header.waitUntilLoadingHasFinished(); - await unifiedFieldList.waitUntilSidebarHasLoaded(); - - expect(await unifiedFieldList.getSidebarAriaDescription()).to.be( - INITIAL_FIELD_LIST_SUMMARY - ); + await expectFieldListDescription(INITIAL_FIELD_LIST_SUMMARY); await kibanaServer.importExport.unload( 'test/functional/fixtures/kbn_archiver/index_pattern_without_timefield' @@ -583,11 +477,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); it('should work when filters change', async () => { - await header.waitUntilLoadingHasFinished(); - - expect(await unifiedFieldList.getSidebarAriaDescription()).to.be( - INITIAL_FIELD_LIST_SUMMARY - ); + await expectFieldListDescription(INITIAL_FIELD_LIST_SUMMARY); await unifiedFieldList.clickFieldListItem('extension'); expect(await testSubjects.getVisibleText('dscFieldStats-topValues')).to.be( @@ -595,12 +485,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { ); await filterBar.addFilter({ field: 'extension', operation: 'is', value: 'jpg' }); - await header.waitUntilLoadingHasFinished(); - await unifiedFieldList.waitUntilSidebarHasLoaded(); - expect(await unifiedFieldList.getSidebarAriaDescription()).to.be( - INITIAL_FIELD_LIST_SUMMARY - ); + await expectFieldListDescription(INITIAL_FIELD_LIST_SUMMARY); // check that the filter was passed down to the sidebar await unifiedFieldList.clickFieldListItem('extension'); @@ -614,29 +500,15 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { ); await browser.refresh(); - await unifiedFieldList.waitUntilSidebarHasLoaded(); - - expect(await unifiedFieldList.getSidebarAriaDescription()).to.be( - INITIAL_FIELD_LIST_SUMMARY - ); + await expectFieldListDescription(INITIAL_FIELD_LIST_SUMMARY); await dataViews.switchToAndValidate('indices-stats*'); - await header.waitUntilLoadingHasFinished(); - await unifiedFieldList.waitUntilSidebarHasLoaded(); - - expect(await unifiedFieldList.getSidebarAriaDescription()).to.be( - '6873 available fields. 4 meta fields.' - ); + await expectFieldListDescription('6873 available fields. 4 meta fields.'); await dataViews.switchToAndValidate('logstash-*'); - await header.waitUntilLoadingHasFinished(); - await unifiedFieldList.waitUntilSidebarHasLoaded(); - - expect(await unifiedFieldList.getSidebarAriaDescription()).to.be( - INITIAL_FIELD_LIST_SUMMARY - ); + await expectFieldListDescription(INITIAL_FIELD_LIST_SUMMARY); await kibanaServer.importExport.unload( 'test/functional/fixtures/kbn_archiver/many_fields_data_view' @@ -650,12 +522,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { adHoc: true, hasTimeField: true, }); - await discover.waitUntilSearchingHasFinished(); - await unifiedFieldList.waitUntilSidebarHasLoaded(); - expect(await unifiedFieldList.getSidebarAriaDescription()).to.be( - INITIAL_FIELD_LIST_SUMMARY - ); + await expectFieldListDescription(INITIAL_FIELD_LIST_SUMMARY); await discover.addRuntimeField( '_bytes-runtimefield', @@ -666,12 +534,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { return !(await testSubjects.exists('fieldEditor')); }); - await header.waitUntilLoadingHasFinished(); - await unifiedFieldList.waitUntilSidebarHasLoaded(); - - expect(await unifiedFieldList.getSidebarAriaDescription()).to.be( - '49 available fields. 5 empty fields. 4 meta fields.' - ); + await expectFieldListDescription('49 available fields. 5 empty fields. 4 meta fields.'); let allFields = await unifiedFieldList.getAllFieldNames(); expect(allFields.includes('_bytes-runtimefield')).to.be(true); @@ -685,23 +548,13 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { return !(await testSubjects.exists('fieldEditor')); }); - await header.waitUntilLoadingHasFinished(); - await unifiedFieldList.waitUntilSidebarHasLoaded(); - - expect(await unifiedFieldList.getSidebarAriaDescription()).to.be( - '49 available fields. 5 empty fields. 4 meta fields.' - ); + await expectFieldListDescription('49 available fields. 5 empty fields. 4 meta fields.'); allFields = await unifiedFieldList.getAllFieldNames(); expect(allFields.includes('_bytes-runtimefield2')).to.be(true); expect(allFields.includes('_bytes-runtimefield')).to.be(false); await discover.removeField('_bytes-runtimefield'); - await header.waitUntilLoadingHasFinished(); - await unifiedFieldList.waitUntilSidebarHasLoaded(); - - expect(await unifiedFieldList.getSidebarAriaDescription()).to.be( - INITIAL_FIELD_LIST_SUMMARY - ); + await expectFieldListDescription(INITIAL_FIELD_LIST_SUMMARY); allFields = await unifiedFieldList.getAllFieldNames(); expect(allFields.includes('_bytes-runtimefield2')).to.be(false); @@ -709,11 +562,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); it('should render even when retrieving documents failed with an error', async () => { - await header.waitUntilLoadingHasFinished(); - - expect(await unifiedFieldList.getSidebarAriaDescription()).to.be( - INITIAL_FIELD_LIST_SUMMARY - ); + await expectFieldListDescription(INITIAL_FIELD_LIST_SUMMARY); await discover.addRuntimeField('_invalid-runtimefield', `emit(‘’);`); @@ -725,9 +574,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await unifiedFieldList.waitUntilSidebarHasLoaded(); // check that the sidebar is rendered - expect(await unifiedFieldList.getSidebarAriaDescription()).to.be( - '49 available fields. 5 empty fields. 4 meta fields.' - ); + await expectFieldListDescription('49 available fields. 5 empty fields. 4 meta fields.'); let allFields = await unifiedFieldList.getAllFieldNames(); expect(allFields.includes('_invalid-runtimefield')).to.be(true); @@ -754,20 +601,11 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { ); await browser.refresh(); - await unifiedFieldList.waitUntilSidebarHasLoaded(); - - expect(await unifiedFieldList.getSidebarAriaDescription()).to.be( - INITIAL_FIELD_LIST_SUMMARY - ); + await expectFieldListDescription(INITIAL_FIELD_LIST_SUMMARY); await dataViews.switchToAndValidate('with-timefield'); - await header.waitUntilLoadingHasFinished(); - await unifiedFieldList.waitUntilSidebarHasLoaded(); - - expect(await unifiedFieldList.getSidebarAriaDescription()).to.be( - '0 available fields. 7 empty fields. 4 meta fields.' - ); + await expectFieldListDescription('0 available fields. 7 empty fields. 4 meta fields.'); await testSubjects.existOrFail( `${unifiedFieldList.getSidebarSectionSelector('available')}NoFieldsCallout-noFieldsMatch` ); @@ -777,12 +615,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { 'Sep 23, 2019 @ 00:00:00.000' ); - await header.waitUntilLoadingHasFinished(); - await unifiedFieldList.waitUntilSidebarHasLoaded(); - - expect(await unifiedFieldList.getSidebarAriaDescription()).to.be( - '7 available fields. 4 meta fields.' - ); + await expectFieldListDescription('7 available fields. 4 meta fields.'); await kibanaServer.importExport.unload( 'test/functional/fixtures/kbn_archiver/index_pattern_without_timefield' diff --git a/test/functional/apps/discover/group6/_time_field_column.ts b/test/functional/apps/discover/group6/_time_field_column.ts index 5965b7765e182..9e5ce3f94a459 100644 --- a/test/functional/apps/discover/group6/_time_field_column.ts +++ b/test/functional/apps/discover/group6/_time_field_column.ts @@ -34,7 +34,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const dataViews = getService('dataViews'); const testSubjects = getService('testSubjects'); const security = getService('security'); - const docTable = getService('docTable'); const defaultSettings = { defaultIndex: 'logstash-*', hideAnnouncements: true, @@ -228,7 +227,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await timePicker.setDefaultAbsoluteRangeViaUiSettings(); await kibanaServer.uiSettings.update({ ...defaultSettings, - 'doc_table:legacy': false, 'doc_table:hideTimeColumn': hideTimeFieldColumnSetting, }); await common.navigateToApp('discover'); @@ -319,103 +317,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); }); }); - - // These tests are skipped as they take a lot of time to run. Temporary unskip them to validate current functionality if necessary. - describe.skip('legacy table', () => { - beforeEach(async () => { - await kibanaServer.uiSettings.update({ - ...defaultSettings, - 'doc_table:hideTimeColumn': hideTimeFieldColumnSetting, - 'doc_table:legacy': true, - }); - await common.navigateToApp('discover'); - await discover.waitUntilSearchingHasFinished(); - }); - - it('should render initial columns correctly', async () => { - // no columns - await discover.loadSavedSearch(`${SEARCH_NO_COLUMNS}${savedSearchSuffix}`); - await discover.waitUntilSearchingHasFinished(); - expect(await docTable.getHeaderFields()).to.eql( - hideTimeFieldColumnSetting ? ['Summary'] : ['@timestamp', 'Summary'] - ); - - await discover.loadSavedSearch(`${SEARCH_NO_COLUMNS}${savedSearchSuffix}-`); - await discover.waitUntilSearchingHasFinished(); - expect(await docTable.getHeaderFields()).to.eql(['Summary']); - - await discover.loadSavedSearch(`${SEARCH_NO_COLUMNS}${savedSearchSuffix}ESQL`); - await discover.waitUntilSearchingHasFinished(); - expect(await dataGrid.getHeaderFields()).to.eql( - hideTimeFieldColumnSetting ? ['Summary'] : ['@timestamp', 'Summary'] - ); - - await discover.loadSavedSearch(`${SEARCH_NO_COLUMNS}${savedSearchSuffix}ESQLdrop`); - await discover.waitUntilSearchingHasFinished(); - expect(await dataGrid.getHeaderFields()).to.eql(['Summary']); - - // only @timestamp is selected - await discover.loadSavedSearch(`${SEARCH_WITH_ONLY_TIMESTAMP}${savedSearchSuffix}`); - await discover.waitUntilSearchingHasFinished(); - expect(await docTable.getHeaderFields()).to.eql( - hideTimeFieldColumnSetting ? ['@timestamp'] : ['@timestamp', '@timestamp'] - ); - - await discover.loadSavedSearch(`${SEARCH_WITH_ONLY_TIMESTAMP}${savedSearchSuffix}-`); - await discover.waitUntilSearchingHasFinished(); - expect(await docTable.getHeaderFields()).to.eql(['@timestamp']); - - await discover.loadSavedSearch(`${SEARCH_WITH_ONLY_TIMESTAMP}${savedSearchSuffix}ESQL`); - await discover.waitUntilSearchingHasFinished(); - expect(await dataGrid.getHeaderFields()).to.eql( - hideTimeFieldColumnSetting ? ['@timestamp'] : ['@timestamp', 'Summary'] - ); - }); - - it('should render selected columns correctly', async () => { - // with selected columns - await discover.loadSavedSearch(`${SEARCH_WITH_SELECTED_COLUMNS}${savedSearchSuffix}`); - await discover.waitUntilSearchingHasFinished(); - expect(await docTable.getHeaderFields()).to.eql( - hideTimeFieldColumnSetting - ? ['bytes', 'extension'] - : ['@timestamp', 'bytes', 'extension'] - ); - - await discover.loadSavedSearch(`${SEARCH_WITH_SELECTED_COLUMNS}${savedSearchSuffix}-`); - await discover.waitUntilSearchingHasFinished(); - expect(await docTable.getHeaderFields()).to.eql(['bytes', 'extension']); - - await discover.loadSavedSearch( - `${SEARCH_WITH_SELECTED_COLUMNS}${savedSearchSuffix}ESQL` - ); - await discover.waitUntilSearchingHasFinished(); - expect(await dataGrid.getHeaderFields()).to.eql(['bytes', 'extension']); - - // with selected columns and @timestamp - await discover.loadSavedSearch( - `${SEARCH_WITH_SELECTED_COLUMNS_AND_TIMESTAMP}${savedSearchSuffix}` - ); - await discover.waitUntilSearchingHasFinished(); - expect(await docTable.getHeaderFields()).to.eql( - hideTimeFieldColumnSetting - ? ['bytes', 'extension', '@timestamp'] - : ['@timestamp', 'bytes', 'extension', '@timestamp'] - ); - - await discover.loadSavedSearch( - `${SEARCH_WITH_SELECTED_COLUMNS_AND_TIMESTAMP}${savedSearchSuffix}-` - ); - await discover.waitUntilSearchingHasFinished(); - expect(await docTable.getHeaderFields()).to.eql(['bytes', 'extension', '@timestamp']); - - await discover.loadSavedSearch( - `${SEARCH_WITH_SELECTED_COLUMNS_AND_TIMESTAMP}${savedSearchSuffix}ESQL` - ); - await discover.waitUntilSearchingHasFinished(); - expect(await dataGrid.getHeaderFields()).to.eql(['bytes', 'extension', '@timestamp']); - }); - }); }); }); }); diff --git a/test/functional/apps/discover/group6/_view_mode_toggle.ts b/test/functional/apps/discover/group6/_view_mode_toggle.ts index 2591716c87d00..4ff5339b80847 100644 --- a/test/functional/apps/discover/group6/_view_mode_toggle.ts +++ b/test/functional/apps/discover/group6/_view_mode_toggle.ts @@ -33,102 +33,75 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await security.testUser.setRoles(['kibana_admin', 'test_logstash_reader']); await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/logstash_functional'); await kibanaServer.importExport.load('test/functional/fixtures/kbn_archiver/discover'); + await timePicker.setDefaultAbsoluteRangeViaUiSettings(); + await kibanaServer.uiSettings.update(defaultSettings); + await common.navigateToApp('discover'); + await discover.waitUntilSearchingHasFinished(); }); after(async () => { await kibanaServer.importExport.unload('test/functional/fixtures/kbn_archiver/discover'); await esArchiver.unload('test/functional/fixtures/es_archiver/logstash_functional'); await kibanaServer.savedObjects.cleanStandardList(); + await kibanaServer.uiSettings.replace({}); }); - [true, false].forEach((useLegacyTable) => { - describe(`isLegacy: ${useLegacyTable}`, function () { - before(async function () { - await timePicker.setDefaultAbsoluteRangeViaUiSettings(); - await kibanaServer.uiSettings.update({ - ...defaultSettings, - 'doc_table:legacy': useLegacyTable, - }); - await common.navigateToApp('discover'); - await discover.waitUntilSearchingHasFinished(); - }); - - after(async () => { - await kibanaServer.uiSettings.replace({}); - }); - - it('should show Documents tab', async () => { - await testSubjects.existOrFail('dscViewModeToggle'); - - if (!useLegacyTable) { - await testSubjects.existOrFail('unifiedDataTableToolbar'); - } - - const documentsTab = await testSubjects.find('dscViewModeDocumentButton'); - expect(await documentsTab.getAttribute('aria-selected')).to.be('true'); - }); - - it('should show legacy Document Explorer info callout', async () => { - if (useLegacyTable) { - await testSubjects.existOrFail('dscDocumentExplorerLegacyCallout'); - } else { - await testSubjects.missingOrFail('dscDocumentExplorerLegacyCallout'); - } - }); - - it('should show an error callout', async () => { - await queryBar.setQuery('@message::'); // invalid - await queryBar.submitQuery(); - await header.waitUntilLoadingHasFinished(); - - await discover.showsErrorCallout(); - - await queryBar.clearQuery(); - await queryBar.submitQuery(); - await header.waitUntilLoadingHasFinished(); - - await testSubjects.missingOrFail('discoverErrorCalloutTitle'); - }); - - describe('Patterns tab (basic license)', function () { - this.tags('skipFIPS'); - - it('should not show', async function () { - await testSubjects.missingOrFail('dscViewModePatternAnalysisButton'); - }); - }); - - it('should not show Field Statistics tab', async () => { - await testSubjects.existOrFail('dscViewModeToggle'); - }); - - it('should not show view mode toggle for ES|QL searches', async () => { - await testSubjects.click('dscViewModeDocumentButton'); - - await retry.try(async () => { - const documentsTab = await testSubjects.find('dscViewModeDocumentButton'); - expect(await documentsTab.getAttribute('aria-selected')).to.be('true'); - }); - - await testSubjects.existOrFail('dscViewModeToggle'); - - await discover.selectTextBaseLang(); - - await testSubjects.missingOrFail('dscViewModeToggle'); - await testSubjects.existOrFail('discoverQueryTotalHits'); - - if (!useLegacyTable) { - await testSubjects.existOrFail('unifiedDataTableToolbar'); - } - }); - - it('should show ES|QL columns callout', async () => { - await testSubjects.missingOrFail('dscSelectedColumnsCallout'); - await unifiedFieldList.clickFieldListItemAdd('extension'); - await header.waitUntilLoadingHasFinished(); - await testSubjects.existOrFail('dscSelectedColumnsCallout'); - }); + it('should show Documents tab', async () => { + await testSubjects.existOrFail('dscViewModeToggle'); + await testSubjects.existOrFail('unifiedDataTableToolbar'); + + const documentsTab = await testSubjects.find('dscViewModeDocumentButton'); + expect(await documentsTab.getAttribute('aria-selected')).to.be('true'); + }); + + it('should show an error callout', async () => { + await queryBar.setQuery('@message::'); // invalid + await queryBar.submitQuery(); + await header.waitUntilLoadingHasFinished(); + + await discover.showsErrorCallout(); + + await queryBar.clearQuery(); + await queryBar.submitQuery(); + await header.waitUntilLoadingHasFinished(); + + await testSubjects.missingOrFail('discoverErrorCalloutTitle'); + }); + + describe('Patterns tab (basic license)', function () { + this.tags('skipFIPS'); + + it('should not show', async function () { + await testSubjects.missingOrFail('dscViewModePatternAnalysisButton'); + }); + }); + + it('should not show Field Statistics tab', async () => { + await testSubjects.existOrFail('dscViewModeToggle'); + }); + + it('should not show view mode toggle for ES|QL searches', async () => { + await testSubjects.click('dscViewModeDocumentButton'); + + await retry.try(async () => { + const documentsTab = await testSubjects.find('dscViewModeDocumentButton'); + expect(await documentsTab.getAttribute('aria-selected')).to.be('true'); }); + + await testSubjects.existOrFail('dscViewModeToggle'); + + await discover.selectTextBaseLang(); + + await testSubjects.missingOrFail('dscViewModeToggle'); + await testSubjects.existOrFail('discoverQueryTotalHits'); + await testSubjects.existOrFail('unifiedDataTableToolbar'); + }); + + it('should show ES|QL columns callout', async () => { + await testSubjects.missingOrFail('dscSelectedColumnsCallout'); + await unifiedFieldList.clickFieldListItemAdd('extension'); + await header.waitUntilLoadingHasFinished(); + await testSubjects.existOrFail('dscSelectedColumnsCallout'); }); }); } diff --git a/test/functional/apps/discover/group7/_runtime_fields_editor.ts b/test/functional/apps/discover/group7/_runtime_fields_editor.ts index ab8711c362b77..e93e73650b464 100644 --- a/test/functional/apps/discover/group7/_runtime_fields_editor.ts +++ b/test/functional/apps/discover/group7/_runtime_fields_editor.ts @@ -234,17 +234,15 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { // navigate to doc view const fieldName = '_runtimefield-doc-view'; await createRuntimeField(fieldName); - const table = await discover.getDocTable(); - const useLegacyTable = await discover.useLegacyTable(); - await table.clickRowToggle(); + await dataGrid.clickRowToggle(); // click the open action await retry.try(async () => { - const rowActions = await table.getRowActions({ rowIndex: 0 }); + const rowActions = await dataGrid.getRowActions({ rowIndex: 0 }); if (!rowActions.length) { throw new Error('row actions empty, trying again'); } - const idxToClick = useLegacyTable ? 1 : 0; + const idxToClick = 0; await rowActions[idxToClick].click(); }); diff --git a/test/functional/apps/discover/group8/_hide_announcements.ts b/test/functional/apps/discover/group8/_hide_announcements.ts deleted file mode 100644 index 9dc11f9eefcac..0000000000000 --- a/test/functional/apps/discover/group8/_hide_announcements.ts +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the "Elastic License - * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side - * Public License v 1"; you may not use this file except in compliance with, at - * your election, the "Elastic License 2.0", the "GNU Affero General Public - * License v3.0 only", or the "Server Side Public License, v 1". - */ - -import expect from '@kbn/expect'; -import { FtrProviderContext } from '../ftr_provider_context'; - -export default function ({ getService, getPageObjects }: FtrProviderContext) { - const esArchiver = getService('esArchiver'); - const { common, discover, timePicker } = getPageObjects(['common', 'discover', 'timePicker']); - const kibanaServer = getService('kibanaServer'); - const testSubjects = getService('testSubjects'); - const browser = getService('browser'); - const security = getService('security'); - - describe('test hide announcements', function () { - before(async function () { - await security.testUser.setRoles(['kibana_admin', 'test_logstash_reader']); - await kibanaServer.importExport.load('test/functional/fixtures/kbn_archiver/discover.json'); - await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/logstash_functional'); - await kibanaServer.uiSettings.replace({ - defaultIndex: 'logstash-*', - 'doc_table:legacy': true, - }); - await common.navigateToApp('discover'); - await timePicker.setDefaultAbsoluteRange(); - }); - - after(async () => { - await kibanaServer.uiSettings.replace({}); - }); - - it('should display callout', async function () { - await discover.selectIndexPattern('logstash-*'); - const calloutExists = await testSubjects.exists('dscDocumentExplorerLegacyCallout'); - expect(calloutExists).to.be(true); - }); - - it('should not display callout', async function () { - await kibanaServer.uiSettings.update({ hideAnnouncements: true }); - await browser.refresh(); - const calloutExists = await testSubjects.exists('dscDocumentExplorerLegacyCallout'); - expect(calloutExists).to.be(false); - }); - }); -} diff --git a/test/functional/apps/discover/group8/index.ts b/test/functional/apps/discover/group8/index.ts index 14b544e2c2015..46d5040fee298 100644 --- a/test/functional/apps/discover/group8/index.ts +++ b/test/functional/apps/discover/group8/index.ts @@ -23,7 +23,6 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) { }); loadTestFile(require.resolve('./_default_route')); - loadTestFile(require.resolve('./_hide_announcements')); loadTestFile(require.resolve('./_flyouts')); }); } diff --git a/test/functional/apps/management/data_views/_scripted_fields.ts b/test/functional/apps/management/data_views/_scripted_fields.ts index f86ae72aa5047..df51514425a24 100644 --- a/test/functional/apps/management/data_views/_scripted_fields.ts +++ b/test/functional/apps/management/data_views/_scripted_fields.ts @@ -387,14 +387,14 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await testSubjects.click('docTableHeaderFieldSort_@timestamp'); await PageObjects.header.waitUntilLoadingHasFinished(); await retry.try(async function () { - const rowData = await PageObjects.discover.getDocTableIndexLegacy(1); + const rowData = await PageObjects.discover.getDocTableIndex(1); expect(rowData).to.be('updateExpectedResultHere\ntrue'); }); await testSubjects.click(`docTableHeaderFieldSort_${scriptedPainlessFieldName2}`); await PageObjects.header.waitUntilLoadingHasFinished(); await retry.try(async function () { - const rowData = await PageObjects.discover.getDocTableIndexLegacy(1); + const rowData = await PageObjects.discover.getDocTableIndex(1); expect(rowData).to.be('updateExpectedResultHere\nfalse'); }); }); @@ -469,14 +469,14 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await testSubjects.click('docTableHeaderFieldSort_@timestamp'); await PageObjects.header.waitUntilLoadingHasFinished(); await retry.try(async function () { - const rowData = await PageObjects.discover.getDocTableIndexLegacy(1); + const rowData = await PageObjects.discover.getDocTableIndex(1); expect(rowData).to.be('updateExpectedResultHere\n2015-09-18 07:00'); }); await testSubjects.click(`docTableHeaderFieldSort_${scriptedPainlessFieldName2}`); await PageObjects.header.waitUntilLoadingHasFinished(); await retry.try(async function () { - const rowData = await PageObjects.discover.getDocTableIndexLegacy(1); + const rowData = await PageObjects.discover.getDocTableIndex(1); expect(rowData).to.be('updateExpectedResultHere\n2015-09-18 07:00'); }); }); diff --git a/test/functional/apps/management/data_views/_scripted_fields_classic_table.ts b/test/functional/apps/management/data_views/_scripted_fields_classic_table.ts deleted file mode 100644 index 4f3d30222e496..0000000000000 --- a/test/functional/apps/management/data_views/_scripted_fields_classic_table.ts +++ /dev/null @@ -1,463 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the "Elastic License - * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side - * Public License v 1"; you may not use this file except in compliance with, at - * your election, the "Elastic License 2.0", the "GNU Affero General Public - * License v3.0 only", or the "Server Side Public License, v 1". - */ - -// Tests for 4 scripted fields; -// 1. Painless (number type) -// 2. Painless (string type) -// 3. Painless (boolean type) -// 4. Painless (date type) -// -// Each of these scripted fields has 4 tests (12 tests total); -// 1. Create scripted field -// 2. See the expected value of the scripted field in Discover doc view -// 3. Filter in Discover by the scripted field -// 4. Visualize with aggregation on the scripted field by clicking unifiedFieldList.clickFieldListItemVisualize - -import expect from '@kbn/expect'; -import { FtrProviderContext } from '../../../ftr_provider_context'; - -export default function ({ getService, getPageObjects }: FtrProviderContext) { - const kibanaServer = getService('kibanaServer'); - const log = getService('log'); - const browser = getService('browser'); - const retry = getService('retry'); - const testSubjects = getService('testSubjects'); - const filterBar = getService('filterBar'); - const docTable = getService('docTable'); - const PageObjects = getPageObjects([ - 'common', - 'header', - 'settings', - 'visualize', - 'discover', - 'timePicker', - 'unifiedFieldList', - ]); - - describe('scripted fields', function () { - this.tags(['skipFirefox']); - - before(async function () { - await browser.setWindowSize(1200, 800); - await kibanaServer.importExport.load('test/functional/fixtures/kbn_archiver/discover'); - await kibanaServer.uiSettings.replace({}); - await kibanaServer.uiSettings.update({ - 'doc_table:legacy': true, - }); - }); - - after(async function afterAll() { - await kibanaServer.importExport.unload('test/functional/fixtures/kbn_archiver/discover'); - await kibanaServer.uiSettings.replace({}); - }); - - it('should not allow saving of invalid scripts', async function () { - await PageObjects.settings.navigateTo(); - await PageObjects.settings.clickKibanaIndexPatterns(); - await PageObjects.settings.clickIndexPatternLogstash(); - await PageObjects.settings.clickScriptedFieldsTab(); - await PageObjects.settings.clickAddScriptedField(); - await PageObjects.settings.setScriptedFieldName('doomedScriptedField'); - await PageObjects.settings.setScriptedFieldScript(`i n v a l i d s c r i p t`); - await PageObjects.settings.clickSaveScriptedField(); - await retry.try(async () => { - const invalidScriptErrorExists = await testSubjects.exists('invalidScriptError'); - expect(invalidScriptErrorExists).to.be(true); - }); - }); - - describe('testing regression for issue #33251', function describeIndexTests() { - const scriptedPainlessFieldName = 'ram_Pain_reg'; - - it('should create and edit scripted field', async function () { - await PageObjects.settings.navigateTo(); - await PageObjects.settings.clickKibanaIndexPatterns(); - await PageObjects.settings.clickIndexPatternLogstash(); - const startingCount = parseInt(await PageObjects.settings.getScriptedFieldsTabCount(), 10); - await PageObjects.settings.clickScriptedFieldsTab(); - await log.debug('add scripted field'); - const script = `1`; - await PageObjects.settings.addScriptedField( - scriptedPainlessFieldName, - 'painless', - 'number', - null, - '1', - script - ); - await retry.try(async function () { - expect(parseInt(await PageObjects.settings.getScriptedFieldsTabCount(), 10)).to.be( - startingCount + 1 - ); - }); - - for (let i = 0; i < 3; i++) { - await PageObjects.settings.editScriptedField(scriptedPainlessFieldName); - const fieldSaveButton = await testSubjects.exists('fieldSaveButton'); - expect(fieldSaveButton).to.be(true); - await PageObjects.settings.clickSaveScriptedField(); - } - }); - }); - - describe('creating and using Painless numeric scripted fields', function describeIndexTests() { - const scriptedPainlessFieldName = 'ram_Pain1'; - - it('should create scripted field', async function () { - await PageObjects.settings.navigateTo(); - await PageObjects.settings.clickKibanaIndexPatterns(); - await PageObjects.settings.clickIndexPatternLogstash(); - const startingCount = parseInt(await PageObjects.settings.getScriptedFieldsTabCount(), 10); - await PageObjects.settings.clickScriptedFieldsTab(); - await log.debug('add scripted field'); - const script = `if (doc['machine.ram'].size() == 0) return -1; - else return doc['machine.ram'].value / (1024 * 1024 * 1024); - `; - await PageObjects.settings.addScriptedField( - scriptedPainlessFieldName, - 'painless', - 'number', - null, - '100', - script - ); - await retry.try(async function () { - expect(parseInt(await PageObjects.settings.getScriptedFieldsTabCount(), 10)).to.be( - startingCount + 1 - ); - }); - }); - - it('should see scripted field value in Discover', async function () { - const fromTime = 'Sep 17, 2015 @ 06:31:44.000'; - const toTime = 'Sep 18, 2015 @ 18:31:44.000'; - await PageObjects.common.navigateToApp('discover'); - await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); - - await retry.try(async function () { - await PageObjects.unifiedFieldList.clickFieldListItemAdd(scriptedPainlessFieldName); - }); - await PageObjects.header.waitUntilLoadingHasFinished(); - - await retry.try(async function () { - const rowData = await PageObjects.discover.getDocTableIndexLegacy(1); - expect(rowData).to.be('Sep 18, 2015 @ 18:20:57.916\n18'); - }); - }); - - // add a test to sort numeric scripted field - it('should sort scripted field value in Discover', async function () { - await testSubjects.click(`docTableHeaderFieldSort_${scriptedPainlessFieldName}`); - // after the first click on the scripted field, it becomes secondary sort after time. - // click on the timestamp twice to make it be the secondary sort key. - await testSubjects.click('docTableHeaderFieldSort_@timestamp'); - await testSubjects.click('docTableHeaderFieldSort_@timestamp'); - await PageObjects.header.waitUntilLoadingHasFinished(); - await retry.try(async function () { - const rowData = await PageObjects.discover.getDocTableIndexLegacy(1); - expect(rowData).to.be('Sep 17, 2015 @ 10:53:14.181\n-1'); - }); - - await testSubjects.click(`docTableHeaderFieldSort_${scriptedPainlessFieldName}`); - await PageObjects.header.waitUntilLoadingHasFinished(); - await retry.try(async function () { - const rowData = await PageObjects.discover.getDocTableIndexLegacy(1); - expect(rowData).to.be('Sep 17, 2015 @ 06:32:29.479\n20'); - }); - }); - - it('should filter by scripted field value in Discover', async function () { - await PageObjects.unifiedFieldList.clickFieldListItem(scriptedPainlessFieldName); - await log.debug('filter by the first value (14) in the expanded scripted field list'); - await PageObjects.unifiedFieldList.clickFieldListPlusFilter( - scriptedPainlessFieldName, - '14' - ); - await PageObjects.header.waitUntilLoadingHasFinished(); - - await retry.try(async function () { - expect(await PageObjects.discover.getHitCount()).to.be('31'); - }); - }); - - it('should visualize scripted field in vertical bar chart', async function () { - await filterBar.removeAllFilters(); - await PageObjects.unifiedFieldList.clickFieldListItemVisualize(scriptedPainlessFieldName); - await PageObjects.header.waitUntilLoadingHasFinished(); - // verify Lens opens a visualization - expect(await testSubjects.getVisibleTextAll('lns-dimensionTrigger')).to.contain( - '@timestamp', - 'Median of ram_Pain1' - ); - }); - }); - - describe('creating and using Painless string scripted fields', function describeIndexTests() { - const scriptedPainlessFieldName2 = 'painString'; - - it('should create scripted field', async function () { - await PageObjects.settings.navigateTo(); - await PageObjects.settings.clickKibanaIndexPatterns(); - await PageObjects.settings.clickIndexPatternLogstash(); - const startingCount = parseInt(await PageObjects.settings.getScriptedFieldsTabCount(), 10); - await PageObjects.settings.clickScriptedFieldsTab(); - await log.debug('add scripted field'); - await PageObjects.settings.addScriptedField( - scriptedPainlessFieldName2, - 'painless', - 'string', - null, - '1', - "if (doc['response.raw'].value == '200') { return 'good'} else { return 'bad'}" - ); - await retry.try(async function () { - expect(parseInt(await PageObjects.settings.getScriptedFieldsTabCount(), 10)).to.be( - startingCount + 1 - ); - }); - }); - - it('should see scripted field value in Discover', async function () { - const fromTime = 'Sep 17, 2015 @ 06:31:44.000'; - const toTime = 'Sep 18, 2015 @ 18:31:44.000'; - await PageObjects.common.navigateToApp('discover'); - await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); - - await retry.try(async function () { - await PageObjects.unifiedFieldList.clickFieldListItemAdd(scriptedPainlessFieldName2); - }); - await PageObjects.header.waitUntilLoadingHasFinished(); - - await retry.try(async function () { - const rowData = await PageObjects.discover.getDocTableIndexLegacy(1); - expect(rowData).to.be('Sep 18, 2015 @ 18:20:57.916\ngood'); - }); - }); - - // add a test to sort string scripted field - it('should sort scripted field value in Discover', async function () { - await testSubjects.click(`docTableHeaderFieldSort_${scriptedPainlessFieldName2}`); - // after the first click on the scripted field, it becomes secondary sort after time. - // click on the timestamp twice to make it be the secondary sort key. - await testSubjects.click('docTableHeaderFieldSort_@timestamp'); - await testSubjects.click('docTableHeaderFieldSort_@timestamp'); - await PageObjects.header.waitUntilLoadingHasFinished(); - await retry.try(async function () { - const rowData = await PageObjects.discover.getDocTableIndexLegacy(1); - expect(rowData).to.be('Sep 17, 2015 @ 09:48:40.594\nbad'); - }); - - await testSubjects.click(`docTableHeaderFieldSort_${scriptedPainlessFieldName2}`); - await PageObjects.header.waitUntilLoadingHasFinished(); - await retry.try(async function () { - const rowData = await PageObjects.discover.getDocTableIndexLegacy(1); - expect(rowData).to.be('Sep 17, 2015 @ 06:32:29.479\ngood'); - }); - }); - - it('should filter by scripted field value in Discover', async function () { - await PageObjects.unifiedFieldList.clickFieldListItem(scriptedPainlessFieldName2); - await log.debug('filter by "bad" in the expanded scripted field list'); - await PageObjects.unifiedFieldList.clickFieldListPlusFilter( - scriptedPainlessFieldName2, - 'bad' - ); - await PageObjects.header.waitUntilLoadingHasFinished(); - - await retry.try(async function () { - expect(await PageObjects.discover.getHitCount()).to.be('27'); - }); - await filterBar.removeAllFilters(); - }); - - it('should visualize scripted field in vertical bar chart', async function () { - await PageObjects.unifiedFieldList.clickFieldListItemVisualize(scriptedPainlessFieldName2); - await PageObjects.header.waitUntilLoadingHasFinished(); - // verify Lens opens a visualization - expect(await testSubjects.getVisibleTextAll('lns-dimensionTrigger')).to.contain( - 'Top 5 values of painString' - ); - }); - }); - - describe('creating and using Painless boolean scripted fields', function describeIndexTests() { - const scriptedPainlessFieldName2 = 'painBool'; - - it('should create scripted field', async function () { - await PageObjects.settings.navigateTo(); - await PageObjects.settings.clickKibanaIndexPatterns(); - await PageObjects.settings.clickIndexPatternLogstash(); - const startingCount = parseInt(await PageObjects.settings.getScriptedFieldsTabCount(), 10); - await PageObjects.settings.clickScriptedFieldsTab(); - await log.debug('add scripted field'); - await PageObjects.settings.addScriptedField( - scriptedPainlessFieldName2, - 'painless', - 'boolean', - null, - '1', - "doc['response.raw'].value == '200'" - ); - await retry.try(async function () { - expect(parseInt(await PageObjects.settings.getScriptedFieldsTabCount(), 10)).to.be( - startingCount + 1 - ); - }); - }); - - it('should see scripted field value in Discover', async function () { - const fromTime = 'Sep 17, 2015 @ 06:31:44.000'; - const toTime = 'Sep 18, 2015 @ 18:31:44.000'; - await PageObjects.common.navigateToApp('discover'); - await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); - - await retry.try(async function () { - await PageObjects.unifiedFieldList.clickFieldListItemAdd(scriptedPainlessFieldName2); - }); - await PageObjects.header.waitUntilLoadingHasFinished(); - - await retry.try(async function () { - const rowData = await PageObjects.discover.getDocTableIndexLegacy(1); - expect(rowData).to.be('Sep 18, 2015 @ 18:20:57.916\ntrue'); - }); - }); - - it('should filter by scripted field value in Discover', async function () { - await PageObjects.unifiedFieldList.clickFieldListItem(scriptedPainlessFieldName2); - await log.debug('filter by "true" in the expanded scripted field list'); - await PageObjects.unifiedFieldList.clickFieldListPlusFilter( - scriptedPainlessFieldName2, - 'true' - ); - await PageObjects.header.waitUntilLoadingHasFinished(); - - await retry.try(async function () { - expect(await PageObjects.discover.getHitCount()).to.be('359'); - }); - await filterBar.removeAllFilters(); - }); - - // add a test to sort boolean - // existing bug: https://github.com/elastic/kibana/issues/75519 hence the issue is skipped. - it.skip('should sort scripted field value in Discover', async function () { - await testSubjects.click(`docTableHeaderFieldSort_${scriptedPainlessFieldName2}`); - // after the first click on the scripted field, it becomes secondary sort after time. - // click on the timestamp twice to make it be the secondary sort key. - await testSubjects.click('docTableHeaderFieldSort_@timestamp'); - await testSubjects.click('docTableHeaderFieldSort_@timestamp'); - await PageObjects.header.waitUntilLoadingHasFinished(); - await retry.try(async function () { - const rowData = await PageObjects.discover.getDocTableIndexLegacy(1); - expect(rowData).to.be('updateExpectedResultHere\ntrue'); - }); - - await testSubjects.click(`docTableHeaderFieldSort_${scriptedPainlessFieldName2}`); - await PageObjects.header.waitUntilLoadingHasFinished(); - await retry.try(async function () { - const rowData = await PageObjects.discover.getDocTableIndexLegacy(1); - expect(rowData).to.be('updateExpectedResultHere\nfalse'); - }); - }); - - it('should visualize scripted field in vertical bar chart', async function () { - await PageObjects.unifiedFieldList.clickFieldListItemVisualize(scriptedPainlessFieldName2); - await PageObjects.header.waitUntilLoadingHasFinished(); - // verify Lens opens a visualization - expect(await testSubjects.getVisibleTextAll('lns-dimensionTrigger')).to.contain( - 'Top 5 values of painBool' - ); - }); - }); - - describe('creating and using Painless date scripted fields', function describeIndexTests() { - const scriptedPainlessFieldName2 = 'painDate'; - - it('should create scripted field', async function () { - await PageObjects.settings.navigateTo(); - await PageObjects.settings.clickKibanaIndexPatterns(); - await PageObjects.settings.clickIndexPatternLogstash(); - const startingCount = parseInt(await PageObjects.settings.getScriptedFieldsTabCount(), 10); - await PageObjects.settings.clickScriptedFieldsTab(); - await log.debug('add scripted field'); - await PageObjects.settings.addScriptedField( - scriptedPainlessFieldName2, - 'painless', - 'date', - { format: 'date', datePattern: 'YYYY-MM-DD HH:00' }, - '1', - "doc['utc_time'].value.toEpochMilli() + (1000) * 60 * 60" - ); - await retry.try(async function () { - expect(parseInt(await PageObjects.settings.getScriptedFieldsTabCount(), 10)).to.be( - startingCount + 1 - ); - }); - }); - - it('should see scripted field value in Discover', async function () { - const fromTime = 'Sep 17, 2015 @ 19:22:00.000'; - const toTime = 'Sep 18, 2015 @ 07:00:00.000'; - await PageObjects.common.navigateToApp('discover'); - await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); - - await retry.try(async function () { - await PageObjects.unifiedFieldList.clickFieldListItemAdd(scriptedPainlessFieldName2); - }); - await PageObjects.header.waitUntilLoadingHasFinished(); - - await retry.try(async function () { - const rowData = await PageObjects.discover.getDocTableIndexLegacy(1); - expect(rowData).to.be('Sep 18, 2015 @ 06:52:55.953\n2015-09-18 07:00'); - }); - }); - - // add a test to sort date scripted field - // https://github.com/elastic/kibana/issues/75711 - it.skip('should sort scripted field value in Discover', async function () { - await testSubjects.click(`docTableHeaderFieldSort_${scriptedPainlessFieldName2}`); - // after the first click on the scripted field, it becomes secondary sort after time. - // click on the timestamp twice to make it be the secondary sort key. - await testSubjects.click('docTableHeaderFieldSort_@timestamp'); - await testSubjects.click('docTableHeaderFieldSort_@timestamp'); - await PageObjects.header.waitUntilLoadingHasFinished(); - await retry.try(async function () { - const rowData = await PageObjects.discover.getDocTableIndexLegacy(1); - expect(rowData).to.be('updateExpectedResultHere\n2015-09-18 07:00'); - }); - - await testSubjects.click(`docTableHeaderFieldSort_${scriptedPainlessFieldName2}`); - await PageObjects.header.waitUntilLoadingHasFinished(); - await retry.try(async function () { - const rowData = await PageObjects.discover.getDocTableIndexLegacy(1); - expect(rowData).to.be('updateExpectedResultHere\n2015-09-18 07:00'); - }); - }); - - it('should filter by scripted field value in Discover', async function () { - await PageObjects.header.waitUntilLoadingHasFinished(); - await docTable.toggleRowExpanded(); - const firstRow = await docTable.getDetailsRow(); - await docTable.addInclusiveFilter(firstRow, scriptedPainlessFieldName2); - await PageObjects.header.waitUntilLoadingHasFinished(); - - await retry.try(async function () { - expect(await PageObjects.discover.getHitCount()).to.be('1'); - }); - await filterBar.removeAllFilters(); - }); - - it('should visualize scripted field in vertical bar chart', async function () { - await PageObjects.unifiedFieldList.clickFieldListItemVisualize(scriptedPainlessFieldName2); - await PageObjects.header.waitUntilLoadingHasFinished(); - // verify Lens opens a visualization - expect(await testSubjects.getVisibleTextAll('lns-dimensionTrigger')).to.contain('painDate'); - }); - }); - }); -} diff --git a/test/functional/apps/management/index.ts b/test/functional/apps/management/index.ts index 2300543f06d51..962aa41bd8ba3 100644 --- a/test/functional/apps/management/index.ts +++ b/test/functional/apps/management/index.ts @@ -31,7 +31,6 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) { loadTestFile(require.resolve('./_mgmt_import_saved_objects')); loadTestFile(require.resolve('./data_views/_index_patterns_empty')); loadTestFile(require.resolve('./data_views/_scripted_fields')); - loadTestFile(require.resolve('./data_views/_scripted_fields_classic_table')); loadTestFile(require.resolve('./data_views/_runtime_fields')); loadTestFile(require.resolve('./data_views/_runtime_fields_composite')); loadTestFile(require.resolve('./data_views/_field_formatter')); diff --git a/test/functional/firefox/discover.config.ts b/test/functional/firefox/discover.config.ts index 7012a3bccad16..9c4c689f0e8ca 100644 --- a/test/functional/firefox/discover.config.ts +++ b/test/functional/firefox/discover.config.ts @@ -18,7 +18,6 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) { ...baseConfig.getAll(), testFiles: [ - require.resolve('../apps/discover/classic'), require.resolve('../apps/discover/esql'), require.resolve('../apps/discover/group1'), require.resolve('../apps/discover/group2_data_grid1'), diff --git a/test/functional/page_objects/console_page.ts b/test/functional/page_objects/console_page.ts index a80f3426e256e..30a4b27c3f037 100644 --- a/test/functional/page_objects/console_page.ts +++ b/test/functional/page_objects/console_page.ts @@ -52,6 +52,13 @@ export class ConsolePageObject extends FtrService { await textArea.clearValueWithKeyboard(); } + public async focusInputEditor() { + const outputEditor = await this.testSubjects.find('consoleMonacoEditor'); + // Simply clicking on the editor doesn't focus it, so we need to click + // on the margin view overlays + await (await outputEditor.findByClassName('margin-view-overlays')).click(); + } + public async focusOutputEditor() { const outputEditor = await this.testSubjects.find('consoleMonacoOutput'); // Simply clicking on the output editor doesn't focus it, so we need to click diff --git a/test/functional/page_objects/dashboard_page.ts b/test/functional/page_objects/dashboard_page.ts index 2a263e9aa8ca7..c9ba5b0c5fa88 100644 --- a/test/functional/page_objects/dashboard_page.ts +++ b/test/functional/page_objects/dashboard_page.ts @@ -49,7 +49,6 @@ export class DashboardPageObject extends FtrService { private readonly common = this.ctx.getPageObject('common'); private readonly header = this.ctx.getPageObject('header'); private readonly visualize = this.ctx.getPageObject('visualize'); - private readonly discover = this.ctx.getPageObject('discover'); private readonly appsMenu = this.ctx.getService('appsMenu'); private readonly toasts = this.ctx.getService('toasts'); @@ -271,22 +270,12 @@ export class DashboardPageObject extends FtrService { */ public async expectToolbarPaginationDisplayed() { - const isLegacyDefault = await this.discover.useLegacyTable(); - if (isLegacyDefault) { - const subjects = [ - 'pagination-button-previous', - 'pagination-button-next', - 'toolBarTotalDocsText', - ]; - await Promise.all(subjects.map(async (subj) => await this.testSubjects.existOrFail(subj))); - } else { - const subjects = ['pagination-button-previous', 'pagination-button-next']; + const subjects = ['pagination-button-previous', 'pagination-button-next']; - await Promise.all(subjects.map(async (subj) => await this.testSubjects.existOrFail(subj))); - const paginationListExists = await this.find.existsByCssSelector('.euiPagination__list'); - if (!paginationListExists) { - throw new Error(`expected discover data grid pagination list to exist`); - } + await Promise.all(subjects.map(async (subj) => await this.testSubjects.existOrFail(subj))); + const paginationListExists = await this.find.existsByCssSelector('.euiPagination__list'); + if (!paginationListExists) { + throw new Error(`expected discover data grid pagination list to exist`); } } diff --git a/test/functional/page_objects/discover_page.ts b/test/functional/page_objects/discover_page.ts index 13289ae9b8aa5..1f5945ff379f3 100644 --- a/test/functional/page_objects/discover_page.ts +++ b/test/functional/page_objects/discover_page.ts @@ -22,10 +22,8 @@ export class DiscoverPageObject extends FtrService { private readonly browser = this.ctx.getService('browser'); private readonly globalNav = this.ctx.getService('globalNav'); private readonly elasticChart = this.ctx.getService('elasticChart'); - private readonly docTable = this.ctx.getService('docTable'); private readonly config = this.ctx.getService('config'); private readonly dataGrid = this.ctx.getService('dataGrid'); - private readonly kibanaServer = this.ctx.getService('kibanaServer'); private readonly fieldEditor = this.ctx.getService('fieldEditor'); private readonly queryBar = this.ctx.getService('queryBar'); private readonly savedObjectsFinder = this.ctx.getService('savedObjectsFinder'); @@ -42,15 +40,6 @@ export class DiscoverPageObject extends FtrService { return await this.testSubjects.getAttribute('unifiedHistogramChart', 'data-time-range'); } - public async getDocTable() { - const isLegacyDefault = await this.useLegacyTable(); - if (isLegacyDefault) { - return this.docTable; - } else { - return this.dataGrid; - } - } - public async saveSearch( searchName: string, saveAsNew?: boolean, @@ -117,12 +106,7 @@ export class DiscoverPageObject extends FtrService { } public async getColumnHeaders() { - const isLegacy = await this.useLegacyTable(); - if (isLegacy) { - return await this.docTable.getHeaderFields('embeddedSavedSearchDocTable'); - } - const table = await this.getDocTable(); - return await table.getHeaderFields(); + return await this.dataGrid.getHeaderFields(); } public async openLoadSavedSearchPanel() { @@ -361,28 +345,16 @@ export class DiscoverPageObject extends FtrService { } public async getDocHeader() { - const table = await this.getDocTable(); - const docHeader = await table.getHeaders(); + const docHeader = await this.dataGrid.getHeaders(); return docHeader.join(); } public async getDocTableRows() { await this.header.waitUntilLoadingHasFinished(); - const table = await this.getDocTable(); - return await table.getBodyRows(); - } - - public async useLegacyTable() { - return (await this.kibanaServer.uiSettings.get('doc_table:legacy')) === true; + return await this.dataGrid.getBodyRows(); } public async getDocTableIndex(index: number, visibleText = false) { - const isLegacyDefault = await this.useLegacyTable(); - if (isLegacyDefault) { - const row = await this.find.byCssSelector(`tr.kbnDocTable__row:nth-child(${index})`); - return await row.getVisibleText(); - } - const row = await this.dataGrid.getRow({ rowIndex: index - 1 }); const result = await Promise.all( row.map(async (cell) => { @@ -398,21 +370,10 @@ export class DiscoverPageObject extends FtrService { return result.slice(await this.dataGrid.getControlColumnsCount()).join(' '); } - public async getDocTableIndexLegacy(index: number) { - const row = await this.find.byCssSelector(`tr.kbnDocTable__row:nth-child(${index})`); - return await row.getVisibleText(); - } - public async getDocTableField(index: number, cellIdx: number = -1) { - const isLegacyDefault = await this.useLegacyTable(); - const usedDefaultCellIdx = isLegacyDefault ? 0 : await this.dataGrid.getControlColumnsCount(); + const usedDefaultCellIdx = await this.dataGrid.getControlColumnsCount(); const usedCellIdx = cellIdx === -1 ? usedDefaultCellIdx : cellIdx; - if (isLegacyDefault) { - const fields = await this.find.allByCssSelector( - `tr.kbnDocTable__row:nth-child(${index}) [data-test-subj='docTableField']` - ); - return await fields[usedCellIdx].getVisibleText(); - } + await this.testSubjects.click('dataGridFullScreenButton'); const row = await this.dataGrid.getRow({ rowIndex: index - 1 }); const result = await Promise.all(row.map(async (cell) => (await cell.getVisibleText()).trim())); @@ -420,33 +381,6 @@ export class DiscoverPageObject extends FtrService { return result[usedCellIdx]; } - public async clickDocTableRowToggle(rowIndex: number = 0) { - const docTable = await this.getDocTable(); - await docTable.clickRowToggle({ rowIndex }); - } - - public async skipToEndOfDocTable() { - // add the focus to the button to make it appear - const skipButton = await this.testSubjects.find('discoverSkipTableButton'); - // force focus on it, to make it interactable - await skipButton.focus(); - // now click it! - return skipButton.click(); - } - - /** - * When scrolling down the legacy table there's a link to scroll up - * So this is done by this function - */ - public async backToTop() { - const skipButton = await this.testSubjects.find('discoverBackToTop'); - return skipButton.click(); - } - - public async getDocTableFooter() { - return await this.testSubjects.find('discoverDocTableFooter'); - } - public isShowingDocViewer() { return this.dataGrid.isShowingDocViewer(); } @@ -478,7 +412,7 @@ export class DiscoverPageObject extends FtrService { } public async getMarks() { - const table = await this.docTable.getTable(); + const table = await this.dataGrid.getTable(); const marks = await table.findAllByTagName('mark'); return await Promise.all(marks.map((mark) => mark.getVisibleText())); } @@ -573,10 +507,6 @@ export class DiscoverPageObject extends FtrService { } public async clickFieldSort(field: string, text = 'Sort New-Old') { - const isLegacyDefault = await this.useLegacyTable(); - if (isLegacyDefault) { - return await this.testSubjects.click(`docTableHeaderFieldSort_${field}`); - } return await this.dataGrid.clickDocSortAsc(field, text); } @@ -608,13 +538,7 @@ export class DiscoverPageObject extends FtrService { } public async removeHeaderColumn(name: string) { - const isLegacyDefault = await this.useLegacyTable(); - if (isLegacyDefault) { - await this.testSubjects.moveMouseTo(`docTableHeader-${name}`); - await this.testSubjects.click(`docTableRemoveHeader-${name}`); - } else { - await this.dataGrid.clickRemoveColumn(name); - } + await this.dataGrid.clickRemoveColumn(name); } public async waitForChartLoadingComplete(renderCount: number) { diff --git a/test/functional/services/dashboard/expectations.ts b/test/functional/services/dashboard/expectations.ts index 414a44b24df97..ec43f1ec80120 100644 --- a/test/functional/services/dashboard/expectations.ts +++ b/test/functional/services/dashboard/expectations.ts @@ -81,14 +81,6 @@ export class DashboardExpectService extends FtrService { }); } - async docTableFieldCount(expectedCount: number) { - this.log.debug(`DashboardExpect.docTableFieldCount(${expectedCount})`); - await this.retry.try(async () => { - const docTableCells = await this.testSubjects.findAll('docTableField', this.findTimeout); - expect(docTableCells.length).to.be(expectedCount); - }); - } - async fieldSuggestions(expectedFields: string[]) { this.log.debug(`DashboardExpect.fieldSuggestions(${expectedFields})`); const fields = await this.filterBar.getFilterEditorFields(); diff --git a/test/functional/services/data_grid.ts b/test/functional/services/data_grid.ts index 3b17a31d624b6..4500bc5b97154 100644 --- a/test/functional/services/data_grid.ts +++ b/test/functional/services/data_grid.ts @@ -499,14 +499,6 @@ export class DataGridService extends FtrService { return await detailsRow.findAllByTestSubject('~docTableRowAction'); } - public async getAnchorDetailsRow(): Promise { - const table = await this.getTable(); - - return await table.findByCssSelector( - '[data-test-subj~="docTableAnchorRow"] + [data-test-subj~="docTableDetailsRow"]' - ); - } - public async openColMenuByField(field: string) { await this.retry.waitFor('header cell action being displayed', async () => { // to prevent flakiness @@ -671,24 +663,6 @@ export class DataGridService extends FtrService { await sampleSizeInput.type(String(newValue)); } - public async getDetailsRow(): Promise { - const detailRows = await this.getDetailsRows(); - return detailRows[0]; - } - - public async getTableDocViewRow( - detailsRow: WebElementWrapper, - fieldName: string - ): Promise { - return await detailsRow.findByTestSubject(`~tableDocViewRow-${fieldName}`); - } - - public async getRemoveInclusiveFilterButton( - tableDocViewRow: WebElementWrapper - ): Promise { - return await tableDocViewRow.findByTestSubject(`~removeInclusiveFilterButton`); - } - public async showFieldCellActionInFlyout(fieldName: string, actionName: string): Promise { const cellSelector = ['addFilterForValueButton', 'addFilterOutValueButton'].includes(actionName) ? `tableDocViewRow-${fieldName}-value` diff --git a/test/functional/services/doc_table.ts b/test/functional/services/doc_table.ts deleted file mode 100644 index 0ca243b7b412b..0000000000000 --- a/test/functional/services/doc_table.ts +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the "Elastic License - * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side - * Public License v 1"; you may not use this file except in compliance with, at - * your election, the "Elastic License 2.0", the "GNU Affero General Public - * License v3.0 only", or the "Server Side Public License, v 1". - */ - -import { WebElementWrapper } from '@kbn/ftr-common-functional-ui-services'; -import { FtrService } from '../ftr_provider_context'; - -interface SelectOptions { - isAnchorRow?: boolean; - rowIndex?: number; -} - -export class DocTableService extends FtrService { - private readonly testSubjects = this.ctx.getService('testSubjects'); - private readonly retry = this.ctx.getService('retry'); - private readonly header = this.ctx.getPageObject('header'); - - public async getTable(selector?: string) { - return await this.testSubjects.find(selector ? selector : 'docTable'); - } - - public async getRowsText() { - const table = await this.getTable(); - const $ = await table.parseDomContent(); - return $.findTestSubjects('~docTableRow') - .toArray() - .map((row: any) => $(row).text().trim()); - } - - public async getBodyRows(): Promise { - const table = await this.getTable(); - return await table.findAllByTestSubject('~docTableRow'); - } - - public async getAnchorRow(): Promise { - const table = await this.getTable(); - return await table.findByTestSubject('~docTableAnchorRow'); - } - - public async getRow({ - isAnchorRow = false, - rowIndex = 0, - }: SelectOptions = {}): Promise { - return isAnchorRow ? await this.getAnchorRow() : (await this.getBodyRows())[rowIndex]; - } - - public async getDetailsRow(): Promise { - const table = await this.getTable(); - return await table.findByCssSelector('[data-test-subj~="docTableDetailsRow"]'); - } - - public async getAnchorDetailsRow(): Promise { - const table = await this.getTable(); - return await table.findByCssSelector( - '[data-test-subj~="docTableAnchorRow"] + [data-test-subj~="docTableDetailsRow"]' - ); - } - - public async clickRowToggle( - options: SelectOptions = { isAnchorRow: false, rowIndex: 0 } - ): Promise { - const row = await this.getRow(options); - const toggle = await row.findByTestSubject('~docTableExpandToggleColumn'); - await toggle.click(); - } - - public async getDetailsRows(): Promise { - const table = await this.getTable(); - return await table.findAllByCssSelector( - '[data-test-subj~="docTableRow"] + [data-test-subj~="docTableDetailsRow"]' - ); - } - - public async getRowActions({ isAnchorRow = false, rowIndex = 0 }: SelectOptions = {}): Promise< - WebElementWrapper[] - > { - const detailsRow = isAnchorRow - ? await this.getAnchorDetailsRow() - : (await this.getDetailsRows())[rowIndex]; - return await detailsRow.findAllByTestSubject('~docTableRowAction'); - } - - public async getFields(options: { isAnchorRow: boolean } = { isAnchorRow: false }) { - const table = await this.getTable(); - const $ = await table.parseDomContent(); - const rowLocator = options.isAnchorRow ? '~docTableAnchorRow' : '~docTableRow'; - const rows = $.findTestSubjects(rowLocator).toArray(); - return rows.map((row: any) => - $(row) - .find('[data-test-subj~="docTableField"]') - .toArray() - .map((field: any) => $(field).text()) - ); - } - - public async getHeaderFields(selector?: string): Promise { - const table = await this.getTable(selector); - const $ = await table.parseDomContent(); - return $.findTestSubjects('~docTableHeaderField') - .toArray() - .map((field: any) => $(field).text().trim()); - } - - public async getHeaders(selector?: string): Promise { - return this.getHeaderFields(selector); - } - - public async getTableDocViewRow( - detailsRow: WebElementWrapper, - fieldName: string - ): Promise { - return await detailsRow.findByTestSubject(`~tableDocViewRow-${fieldName}`); - } - - public async getAddInclusiveFilterButton( - tableDocViewRow: WebElementWrapper - ): Promise { - return await tableDocViewRow.findByTestSubject(`~addInclusiveFilterButton`); - } - - public async addInclusiveFilter(detailsRow: WebElementWrapper, fieldName: string): Promise { - const tableDocViewRow = await this.getTableDocViewRow(detailsRow, fieldName); - const addInclusiveFilterButton = await this.getAddInclusiveFilterButton(tableDocViewRow); - await addInclusiveFilterButton.click(); - await this.header.awaitGlobalLoadingIndicatorHidden(); - } - - public async getRemoveInclusiveFilterButton( - tableDocViewRow: WebElementWrapper - ): Promise { - return await tableDocViewRow.findByTestSubject(`~removeInclusiveFilterButton`); - } - - public async removeInclusiveFilter( - detailsRow: WebElementWrapper, - fieldName: string - ): Promise { - const tableDocViewRow = await this.getTableDocViewRow(detailsRow, fieldName); - const addInclusiveFilterButton = await this.getRemoveInclusiveFilterButton(tableDocViewRow); - await addInclusiveFilterButton.click(); - await this.header.awaitGlobalLoadingIndicatorHidden(); - } - - public async getAddExistsFilterButton( - tableDocViewRow: WebElementWrapper - ): Promise { - return await tableDocViewRow.findByTestSubject(`~addExistsFilterButton`); - } - - public async addExistsFilter(detailsRow: WebElementWrapper, fieldName: string): Promise { - const tableDocViewRow = await this.getTableDocViewRow(detailsRow, fieldName); - const addInclusiveFilterButton = await this.getAddExistsFilterButton(tableDocViewRow); - await addInclusiveFilterButton.click(); - await this.header.awaitGlobalLoadingIndicatorHidden(); - } - - public async toggleRowExpanded({ - isAnchorRow = false, - rowIndex = 0, - }: SelectOptions = {}): Promise { - await this.clickRowToggle({ isAnchorRow, rowIndex }); - await this.header.awaitGlobalLoadingIndicatorHidden(); - return await this.retry.try(async () => { - const row = isAnchorRow ? await this.getAnchorRow() : (await this.getBodyRows())[rowIndex]; - const detailsRow = await row.findByXpath( - './following-sibling::*[@data-test-subj="docTableDetailsRow"]' - ); - return detailsRow.findByTestSubject('~docViewer'); - }); - } -} diff --git a/test/functional/services/index.ts b/test/functional/services/index.ts index 77df85ef3e565..ccdc8cfec3957 100644 --- a/test/functional/services/index.ts +++ b/test/functional/services/index.ts @@ -30,7 +30,6 @@ import { DashboardDrilldownPanelActionsProvider, DashboardDrilldownsManageProvider, } from './dashboard'; -import { DocTableService } from './doc_table'; import { EmbeddingService } from './embedding'; import { FilterBarService } from './filter_bar'; import { FlyoutService } from './flyout'; @@ -62,7 +61,6 @@ export const services = { ...commonFunctionalUIServices, filterBar: FilterBarService, queryBar: QueryBarService, - docTable: DocTableService, png: PngService, screenshots: ScreenshotsService, snapshots: SnapshotsService, diff --git a/test/plugin_functional/plugins/core_plugin_deprecations/server/plugin.ts b/test/plugin_functional/plugins/core_plugin_deprecations/server/plugin.ts index 0a7a15f0c62e2..2afd1e13d040c 100644 --- a/test/plugin_functional/plugins/core_plugin_deprecations/server/plugin.ts +++ b/test/plugin_functional/plugins/core_plugin_deprecations/server/plugin.ts @@ -18,7 +18,11 @@ async function getDeprecations({ savedObjectsClient, }: GetDeprecationsContext): Promise { const deprecations: DeprecationsDetails[] = []; - const { total } = await savedObjectsClient.find({ type: 'test-deprecations-plugin', perPage: 1 }); + const { total } = await savedObjectsClient.find({ + type: 'test-deprecations-plugin', + perPage: 1, + namespaces: ['*'], + }); deprecations.push({ title: 'CorePluginDeprecationsPlugin plugin is deprecated', diff --git a/test/plugin_functional/test_suites/core_plugins/rendering.ts b/test/plugin_functional/test_suites/core_plugins/rendering.ts index 7305824696aec..8047994039e71 100644 --- a/test/plugin_functional/test_suites/core_plugins/rendering.ts +++ b/test/plugin_functional/test_suites/core_plugins/rendering.ts @@ -354,6 +354,7 @@ export default function ({ getService }: PluginFunctionalProviderContext) { 'xpack.upgrade_assistant.featureSet.migrateSystemIndices (boolean?)', 'xpack.upgrade_assistant.featureSet.mlSnapshots (boolean?)', 'xpack.upgrade_assistant.featureSet.reindexCorrectiveActions (boolean?)', + 'xpack.upgrade_assistant.featureSet.migrateDataStreams (boolean?)', 'xpack.upgrade_assistant.ui.enabled (boolean?)', 'xpack.observability.unsafe.alertDetails.metrics.enabled (boolean?)', 'xpack.observability.unsafe.alertDetails.logs.enabled (boolean?)', diff --git a/tsconfig.base.json b/tsconfig.base.json index 9dd73f15f8d1b..c690ecf1a7f93 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -96,6 +96,8 @@ "@kbn/app-link-test-plugin/*": ["test/plugin_functional/plugins/app_link_test/*"], "@kbn/application-usage-test-plugin": ["x-pack/test/usage_collection/plugins/application_usage_test"], "@kbn/application-usage-test-plugin/*": ["x-pack/test/usage_collection/plugins/application_usage_test/*"], + "@kbn/asset-inventory-plugin": ["x-pack/plugins/asset_inventory"], + "@kbn/asset-inventory-plugin/*": ["x-pack/plugins/asset_inventory/*"], "@kbn/audit-log-plugin": ["x-pack/test/security_api_integration/plugins/audit_log"], "@kbn/audit-log-plugin/*": ["x-pack/test/security_api_integration/plugins/audit_log/*"], "@kbn/avc-banner": ["packages/kbn-avc-banner"], @@ -756,6 +758,8 @@ "@kbn/default-nav-management/*": ["packages/default-nav/management/*"], "@kbn/default-nav-ml": ["packages/default-nav/ml"], "@kbn/default-nav-ml/*": ["packages/default-nav/ml/*"], + "@kbn/dependency-ownership": ["packages/kbn-dependency-ownership"], + "@kbn/dependency-ownership/*": ["packages/kbn-dependency-ownership/*"], "@kbn/dependency-usage": ["packages/kbn-dependency-usage"], "@kbn/dependency-usage/*": ["packages/kbn-dependency-usage/*"], "@kbn/dev-cli-errors": ["packages/kbn-dev-cli-errors"], @@ -1532,6 +1536,8 @@ "@kbn/saved-objects-tagging-oss-plugin/*": ["src/plugins/saved_objects_tagging_oss/*"], "@kbn/saved-objects-tagging-plugin": ["x-pack/plugins/saved_objects_tagging"], "@kbn/saved-objects-tagging-plugin/*": ["x-pack/plugins/saved_objects_tagging/*"], + "@kbn/saved-search-component": ["packages/kbn-saved-search-component"], + "@kbn/saved-search-component/*": ["packages/kbn-saved-search-component/*"], "@kbn/saved-search-plugin": ["src/plugins/saved_search"], "@kbn/saved-search-plugin/*": ["src/plugins/saved_search/*"], "@kbn/scout": ["packages/kbn-scout"], diff --git a/x-pack/examples/alerting_example/server/plugin.ts b/x-pack/examples/alerting_example/server/plugin.ts index 43b3bc82c4416..bf79d564222db 100644 --- a/x-pack/examples/alerting_example/server/plugin.ts +++ b/x-pack/examples/alerting_example/server/plugin.ts @@ -9,9 +9,10 @@ import { Plugin, CoreSetup } from '@kbn/core/server'; import { i18n } from '@kbn/i18n'; // import directly to support examples functional tests (@kbn-test/src/functional_tests/lib/babel_register_for_test_plugins.js) import { DEFAULT_APP_CATEGORIES } from '@kbn/core-application-common'; -import { PluginSetupContract as AlertingSetup } from '@kbn/alerting-plugin/server'; +import { AlertingServerSetup } from '@kbn/alerting-plugin/server'; import { FeaturesPluginSetup } from '@kbn/features-plugin/server'; +import { ALERTING_FEATURE_ID } from '@kbn/alerting-plugin/common'; import { KibanaFeatureScope } from '@kbn/features-plugin/common'; import { ruleType as alwaysFiringRule } from './rule_types/always_firing'; import { ruleType as peopleInSpaceRule } from './rule_types/astros'; @@ -22,7 +23,7 @@ import { ALERTING_EXAMPLE_APP_ID } from '../common/constants'; // this plugin's dependencies export interface AlertingExampleDeps { - alerting: AlertingSetup; + alerting: AlertingServerSetup; features: FeaturesPluginSetup; } @@ -43,15 +44,54 @@ export class AlertingExamplePlugin implements Plugin { id: 'observabilityCases', configurationId: 'observabilityCases', alertsTableConfigurationRegistry, - featureIds: [ - AlertConsumers.INFRASTRUCTURE, - AlertConsumers.APM, - AlertConsumers.OBSERVABILITY, - AlertConsumers.LOGS, - ], + ruleTypeIds: ['.es-query'], query: { bool: { filter: [], diff --git a/x-pack/examples/triggers_actions_ui_example/server/plugin.ts b/x-pack/examples/triggers_actions_ui_example/server/plugin.ts index 6d55bbb2cb55d..6bf6c1fd1442e 100644 --- a/x-pack/examples/triggers_actions_ui_example/server/plugin.ts +++ b/x-pack/examples/triggers_actions_ui_example/server/plugin.ts @@ -8,7 +8,7 @@ import { Plugin, CoreSetup } from '@kbn/core/server'; import { PluginSetupContract as ActionsSetup } from '@kbn/actions-plugin/server'; -import { PluginSetupContract as AlertingSetup } from '@kbn/alerting-plugin/server'; +import { AlertingServerSetup } from '@kbn/alerting-plugin/server'; import { getConnectorType as getSystemLogExampleConnectorType, @@ -17,7 +17,7 @@ import { // this plugin's dependencies export interface TriggersActionsUiExampleDeps { - alerting: AlertingSetup; + alerting: AlertingServerSetup; actions: ActionsSetup; } export class TriggersActionsUiExamplePlugin diff --git a/x-pack/examples/triggers_actions_ui_example/tsconfig.json b/x-pack/examples/triggers_actions_ui_example/tsconfig.json index 601f23edd2647..458a4a99d589b 100644 --- a/x-pack/examples/triggers_actions_ui_example/tsconfig.json +++ b/x-pack/examples/triggers_actions_ui_example/tsconfig.json @@ -19,7 +19,6 @@ "@kbn/alerting-plugin", "@kbn/triggers-actions-ui-plugin", "@kbn/developer-examples-plugin", - "@kbn/rule-data-utils", "@kbn/data-plugin", "@kbn/i18n-react", "@kbn/shared-ux-router", diff --git a/x-pack/packages/ai-infra/product-doc-common/src/indices.ts b/x-pack/packages/ai-infra/product-doc-common/src/indices.ts index b48cacf79fd23..90e416ff48c46 100644 --- a/x-pack/packages/ai-infra/product-doc-common/src/indices.ts +++ b/x-pack/packages/ai-infra/product-doc-common/src/indices.ts @@ -7,9 +7,9 @@ import type { ProductName } from './product'; -export const productDocIndexPrefix = '.kibana-ai-product-doc'; -export const productDocIndexPattern = `${productDocIndexPrefix}-*`; +export const productDocIndexPrefix = '.kibana_ai_product_doc'; +export const productDocIndexPattern = `${productDocIndexPrefix}_*`; export const getProductDocIndexName = (productName: ProductName): string => { - return `${productDocIndexPrefix}-${productName.toLowerCase()}`; + return `${productDocIndexPrefix}_${productName.toLowerCase()}`; }; diff --git a/x-pack/packages/kbn-ai-assistant/src/chat/chat_body.tsx b/x-pack/packages/kbn-ai-assistant/src/chat/chat_body.tsx index b8ea673483372..00879b38932aa 100644 --- a/x-pack/packages/kbn-ai-assistant/src/chat/chat_body.tsx +++ b/x-pack/packages/kbn-ai-assistant/src/chat/chat_body.tsx @@ -509,7 +509,9 @@ export function ChatBody({ saveTitle(newTitle); }} onToggleFlyoutPositionMode={onToggleFlyoutPositionMode} - navigateToConversation={navigateToConversation} + navigateToConversation={ + initialMessages?.length && !initialConversationId ? undefined : navigateToConversation + } /> diff --git a/x-pack/packages/kbn-cloud-security-posture/common/constants.ts b/x-pack/packages/kbn-cloud-security-posture/common/constants.ts index a24d676dc6f88..9112dba4b9a4f 100644 --- a/x-pack/packages/kbn-cloud-security-posture/common/constants.ts +++ b/x-pack/packages/kbn-cloud-security-posture/common/constants.ts @@ -47,3 +47,8 @@ export const VULNERABILITIES_SEVERITY: Record = { CRITICAL: 'CRITICAL', UNKNOWN: 'UNKNOWN', }; + +export const MISCONFIGURATION_STATUS: Record = { + PASSED: 'passed', + FAILED: 'failed', +}; diff --git a/x-pack/packages/kbn-cloud-security-posture/common/index.ts b/x-pack/packages/kbn-cloud-security-posture/common/index.ts index d5ee781c39b20..4065f7ca331a9 100644 --- a/x-pack/packages/kbn-cloud-security-posture/common/index.ts +++ b/x-pack/packages/kbn-cloud-security-posture/common/index.ts @@ -28,7 +28,9 @@ export * from './constants'; export { extractErrorMessage, buildMutedRulesFilter, - buildEntityFlyoutPreviewQuery, + buildGenericEntityFlyoutPreviewQuery, + buildMisconfigurationEntityFlyoutPreviewQuery, + buildVulnerabilityEntityFlyoutPreviewQuery, } from './utils/helpers'; export { getAbbreviatedNumber } from './utils/get_abbreviated_number'; export { UiMetricService } from './utils/ui_metrics'; diff --git a/x-pack/packages/kbn-cloud-security-posture/common/utils/helpers.test.ts b/x-pack/packages/kbn-cloud-security-posture/common/utils/helpers.test.ts index 04cb76f4441c5..6b85d2ead28fe 100644 --- a/x-pack/packages/kbn-cloud-security-posture/common/utils/helpers.test.ts +++ b/x-pack/packages/kbn-cloud-security-posture/common/utils/helpers.test.ts @@ -9,8 +9,10 @@ import { extractErrorMessage, defaultErrorMessage, buildMutedRulesFilter, - buildEntityFlyoutPreviewQuery, buildEntityAlertsQuery, + buildGenericEntityFlyoutPreviewQuery, + buildMisconfigurationEntityFlyoutPreviewQuery, + buildVulnerabilityEntityFlyoutPreviewQuery, } from './helpers'; const fallbackMessage = 'thisIsAFallBackMessage'; @@ -145,7 +147,7 @@ describe('test helper methods', () => { }); }); - describe('buildEntityFlyoutPreviewQueryTest', () => { + describe('buildGenericEntityFlyoutPreviewQuery', () => { it('should return the correct query when given field and query', () => { const field = 'host.name'; const query = 'exampleHost'; @@ -162,10 +164,10 @@ describe('test helper methods', () => { }, }; - expect(buildEntityFlyoutPreviewQuery(field, query)).toEqual(expectedQuery); + expect(buildGenericEntityFlyoutPreviewQuery(field, query)).toEqual(expectedQuery); }); - it('should return the correct query when given field and empty query', () => { + it('should return the correct query when given field and empty query and empty status', () => { const field = 'host.name'; const expectedQuery = { bool: { @@ -180,12 +182,143 @@ describe('test helper methods', () => { }, }; - expect(buildEntityFlyoutPreviewQuery(field)).toEqual(expectedQuery); + expect(buildGenericEntityFlyoutPreviewQuery(field)).toEqual(expectedQuery); + }); + + it('should return the correct query when given field and queryValue and status but empty queryField', () => { + const field = 'host.name'; + const query = 'exampleHost'; + const status = 'pass'; + const expectedQuery = { + bool: { + filter: [ + { + bool: { + should: [{ term: { 'host.name': 'exampleHost' } }], + minimum_should_match: 1, + }, + }, + ], + }, + }; + + expect(buildGenericEntityFlyoutPreviewQuery(field, query, status)).toEqual(expectedQuery); + }); + + it('should return the correct query when given field and queryValue and queryField but empty status', () => { + const field = 'host.name'; + const query = 'exampleHost'; + const emptyStatus = undefined; + const queryField = 'some.field'; + const expectedQuery = { + bool: { + filter: [ + { + bool: { + should: [{ term: { 'host.name': 'exampleHost' } }], + minimum_should_match: 1, + }, + }, + ], + }, + }; + + expect(buildGenericEntityFlyoutPreviewQuery(field, query, emptyStatus, queryField)).toEqual( + expectedQuery + ); + }); + + it('should return the correct query when given all the parameters', () => { + const field = 'host.name'; + const query = 'exampleHost'; + const emptyStatus = 'some.status'; + const queryField = 'some.field'; + const expectedQuery = { + bool: { + filter: [ + { + bool: { + should: [{ term: { 'host.name': 'exampleHost' } }], + minimum_should_match: 1, + }, + }, + { + bool: { + should: [{ term: { 'some.field': 'some.status' } }], + minimum_should_match: 1, + }, + }, + ], + }, + }; + + expect(buildGenericEntityFlyoutPreviewQuery(field, query, emptyStatus, queryField)).toEqual( + expectedQuery + ); + }); + }); + + describe('buildMisconfigurationEntityFlyoutPreviewQuery', () => { + it('should return the correct query when given field, queryValue, status and queryType Misconfiguration', () => { + const field = 'host.name'; + const queryValue = 'exampleHost'; + const status = 'pass'; + const expectedQuery = { + bool: { + filter: [ + { + bool: { + should: [{ term: { 'host.name': 'exampleHost' } }], + minimum_should_match: 1, + }, + }, + { + bool: { + should: [{ term: { 'result.evaluation': 'pass' } }], + minimum_should_match: 1, + }, + }, + ], + }, + }; + + expect(buildMisconfigurationEntityFlyoutPreviewQuery(field, queryValue, status)).toEqual( + expectedQuery + ); + }); + }); + describe('buildVulnerabilityEntityFlyoutPreviewQuery', () => { + it('should return the correct query when given field, queryValue, status and queryType Vulnerability', () => { + const field = 'host.name'; + const queryValue = 'exampleHost'; + const status = 'low'; + const expectedQuery = { + bool: { + filter: [ + { + bool: { + should: [{ term: { 'host.name': 'exampleHost' } }], + minimum_should_match: 1, + }, + }, + { + bool: { + should: [{ term: { 'vulnerability.severity': 'low' } }], + minimum_should_match: 1, + }, + }, + ], + }, + }; + + expect(buildVulnerabilityEntityFlyoutPreviewQuery(field, queryValue, status)).toEqual( + expectedQuery + ); }); }); describe('buildEntityAlertsQuery', () => { - const getExpectedAlertsQuery = (size?: number) => { + const getExpectedAlertsQuery = (size?: number, severity?: string) => { return { size: size || 0, _source: false, @@ -202,20 +335,30 @@ describe('test helper methods', () => { filter: [ { bool: { - must: [], - filter: [ + should: [ { - match_phrase: { - 'host.name': { - query: 'exampleHost', - }, + term: { + 'host.name': 'exampleHost', }, }, ], - should: [], - must_not: [], + minimum_should_match: 1, }, }, + severity + ? { + bool: { + should: [ + { + term: { + 'kibana.alert.severity': 'low', + }, + }, + ], + minimum_should_match: 1, + }, + } + : undefined, { range: { '@timestamp': { @@ -229,7 +372,7 @@ describe('test helper methods', () => { 'kibana.alert.workflow_status': ['open', 'acknowledged'], }, }, - ], + ].filter(Boolean), }, }, }; @@ -256,5 +399,18 @@ describe('test helper methods', () => { expect(buildEntityAlertsQuery(field, to, from, query)).toEqual(getExpectedAlertsQuery(size)); }); + + it('should return the correct query when given severity query', () => { + const field = 'host.name'; + const query = 'exampleHost'; + const to = 'Tomorrow'; + const from = 'Today'; + const size = undefined; + const severity = 'low'; + + expect(buildEntityAlertsQuery(field, to, from, query, size, severity)).toEqual( + getExpectedAlertsQuery(size, 'low') + ); + }); }); }); diff --git a/x-pack/packages/kbn-cloud-security-posture/common/utils/helpers.ts b/x-pack/packages/kbn-cloud-security-posture/common/utils/helpers.ts index bd531fa63804f..ac2e27b70878f 100644 --- a/x-pack/packages/kbn-cloud-security-posture/common/utils/helpers.ts +++ b/x-pack/packages/kbn-cloud-security-posture/common/utils/helpers.ts @@ -43,7 +43,12 @@ export const buildMutedRulesFilter = ( return mutedRulesFilterQuery; }; -export const buildEntityFlyoutPreviewQuery = (field: string, queryValue?: string) => { +export const buildGenericEntityFlyoutPreviewQuery = ( + field: string, + queryValue?: string, + status?: string, + queryField?: string +) => { return { bool: { filter: [ @@ -59,17 +64,52 @@ export const buildEntityFlyoutPreviewQuery = (field: string, queryValue?: string minimum_should_match: 1, }, }, - ], + status && queryField + ? { + bool: { + should: [ + { + term: { + [queryField]: status, + }, + }, + ], + minimum_should_match: 1, + }, + } + : undefined, + ].filter(Boolean), }, }; }; +// Higher-order function for Misconfiguration +export const buildMisconfigurationEntityFlyoutPreviewQuery = ( + field: string, + queryValue?: string, + status?: string +) => { + const queryField = 'result.evaluation'; + return buildGenericEntityFlyoutPreviewQuery(field, queryValue, status, queryField); +}; + +// Higher-order function for Vulnerability +export const buildVulnerabilityEntityFlyoutPreviewQuery = ( + field: string, + queryValue?: string, + status?: string +) => { + const queryField = 'vulnerability.severity'; + return buildGenericEntityFlyoutPreviewQuery(field, queryValue, status, queryField); +}; + export const buildEntityAlertsQuery = ( field: string, to: string, from: string, queryValue?: string, - size?: number + size?: number, + severity?: string ) => { return { size: size || 0, @@ -87,20 +127,30 @@ export const buildEntityAlertsQuery = ( filter: [ { bool: { - must: [], - filter: [ + should: [ { - match_phrase: { - [field]: { - query: queryValue, - }, + term: { + [field]: `${queryValue || ''}`, }, }, ], - should: [], - must_not: [], + minimum_should_match: 1, }, }, + severity + ? { + bool: { + should: [ + { + term: { + 'kibana.alert.severity': severity, + }, + }, + ], + minimum_should_match: 1, + }, + } + : undefined, { range: { '@timestamp': { @@ -114,7 +164,7 @@ export const buildEntityAlertsQuery = ( 'kibana.alert.workflow_status': ['open', 'acknowledged'], }, }, - ], + ].filter(Boolean), }, }, }; diff --git a/x-pack/packages/kbn-cloud-security-posture/graph/src/components/edge/default_edge.tsx b/x-pack/packages/kbn-cloud-security-posture/graph/src/components/edge/default_edge.tsx index 898e12b5b4c01..6826c47b270ce 100644 --- a/x-pack/packages/kbn-cloud-security-posture/graph/src/components/edge/default_edge.tsx +++ b/x-pack/packages/kbn-cloud-security-posture/graph/src/components/edge/default_edge.tsx @@ -49,6 +49,8 @@ export function DefaultEdge({ path={edgePath} style={{ stroke: euiTheme.colors[color], + }} + css={{ strokeDasharray: '2,2', }} markerEnd={ diff --git a/x-pack/packages/kbn-cloud-security-posture/graph/src/components/edge/styles.tsx b/x-pack/packages/kbn-cloud-security-posture/graph/src/components/edge/styles.tsx index 58ecea3bc3bea..5a3e2f8b72b21 100644 --- a/x-pack/packages/kbn-cloud-security-posture/graph/src/components/edge/styles.tsx +++ b/x-pack/packages/kbn-cloud-security-posture/graph/src/components/edge/styles.tsx @@ -128,7 +128,7 @@ export const SvgDefsMarker = () => { const { euiTheme } = useEuiTheme(); return ( - + diff --git a/x-pack/packages/kbn-cloud-security-posture/graph/src/components/node/edge_group_node.tsx b/x-pack/packages/kbn-cloud-security-posture/graph/src/components/node/edge_group_node.tsx index 97b8928c421e1..a3dd064d16ab7 100644 --- a/x-pack/packages/kbn-cloud-security-posture/graph/src/components/node/edge_group_node.tsx +++ b/x-pack/packages/kbn-cloud-security-posture/graph/src/components/node/edge_group_node.tsx @@ -16,7 +16,7 @@ export const EdgeGroupNode: React.FC = memo((props: NodeProps) => { <> { return (
        diff --git a/x-pack/packages/kbn-cloud-security-posture/public/src/constants/component_constants.ts b/x-pack/packages/kbn-cloud-security-posture/public/src/constants/component_constants.ts index d4d436e981cc4..3e22fdea80666 100644 --- a/x-pack/packages/kbn-cloud-security-posture/public/src/constants/component_constants.ts +++ b/x-pack/packages/kbn-cloud-security-posture/public/src/constants/component_constants.ts @@ -11,3 +11,6 @@ export const statusColors = { failed: euiThemeVars.euiColorVis9, unknown: euiThemeVars.euiColorLightShade, }; + +export const HOST_NAME = 'host.name'; +export const USER_NAME = 'user.name'; diff --git a/x-pack/packages/kbn-cloud-security-posture/public/src/hooks/use_has_misconfigurations.ts b/x-pack/packages/kbn-cloud-security-posture/public/src/hooks/use_has_misconfigurations.ts index 9b126332b567b..c8e36898fed16 100644 --- a/x-pack/packages/kbn-cloud-security-posture/public/src/hooks/use_has_misconfigurations.ts +++ b/x-pack/packages/kbn-cloud-security-posture/public/src/hooks/use_has_misconfigurations.ts @@ -5,12 +5,12 @@ * 2.0. */ -import { buildEntityFlyoutPreviewQuery } from '@kbn/cloud-security-posture-common'; +import { buildGenericEntityFlyoutPreviewQuery } from '@kbn/cloud-security-posture-common'; import { useMisconfigurationPreview } from './use_misconfiguration_preview'; export const useHasMisconfigurations = (field: 'host.name' | 'user.name', value: string) => { const { data } = useMisconfigurationPreview({ - query: buildEntityFlyoutPreviewQuery(field, value), + query: buildGenericEntityFlyoutPreviewQuery(field, value), sort: [], enabled: true, pageSize: 1, diff --git a/x-pack/packages/kbn-cloud-security-posture/public/src/hooks/use_has_vulnerabilities.ts b/x-pack/packages/kbn-cloud-security-posture/public/src/hooks/use_has_vulnerabilities.ts index 336892ee888af..ae7e951ce9313 100644 --- a/x-pack/packages/kbn-cloud-security-posture/public/src/hooks/use_has_vulnerabilities.ts +++ b/x-pack/packages/kbn-cloud-security-posture/public/src/hooks/use_has_vulnerabilities.ts @@ -5,13 +5,13 @@ * 2.0. */ -import { buildEntityFlyoutPreviewQuery } from '@kbn/cloud-security-posture-common'; +import { buildGenericEntityFlyoutPreviewQuery } from '@kbn/cloud-security-posture-common'; import { useVulnerabilitiesPreview } from './use_vulnerabilities_preview'; import { hasVulnerabilitiesData } from '../utils/vulnerability_helpers'; export const useHasVulnerabilities = (field: 'host.name' | 'user.name', value: string) => { const { data: vulnerabilitiesData } = useVulnerabilitiesPreview({ - query: buildEntityFlyoutPreviewQuery(field, value), + query: buildGenericEntityFlyoutPreviewQuery(field, value), sort: [], enabled: true, pageSize: 1, diff --git a/x-pack/packages/kbn-cloud-security-posture/public/src/types.ts b/x-pack/packages/kbn-cloud-security-posture/public/src/types.ts index 493e58519bd91..2c7be37de50dd 100644 --- a/x-pack/packages/kbn-cloud-security-posture/public/src/types.ts +++ b/x-pack/packages/kbn-cloud-security-posture/public/src/types.ts @@ -58,7 +58,7 @@ export interface CspClientPluginStartDeps { export interface CspBaseEsQuery { query?: { bool: { - filter: estypes.QueryDslQueryContainer[]; + filter: Array | undefined; }; }; } diff --git a/x-pack/packages/kbn-cloud-security-posture/public/src/utils/vulnerability_helpers.test.ts b/x-pack/packages/kbn-cloud-security-posture/public/src/utils/vulnerability_helpers.test.ts index 898f9990a1a96..e2503b7a38a2c 100644 --- a/x-pack/packages/kbn-cloud-security-posture/public/src/utils/vulnerability_helpers.test.ts +++ b/x-pack/packages/kbn-cloud-security-posture/public/src/utils/vulnerability_helpers.test.ts @@ -10,6 +10,7 @@ import { getVulnerabilityStats } from './vulnerability_helpers'; import { i18n } from '@kbn/i18n'; describe('getVulnerabilitiesAggregationCount', () => { + const mockFilterFunction = jest.fn(); it('should return empty array when all severity count is 0', () => { const result = getVulnerabilityStats({ critical: 0, high: 0, medium: 0, low: 0, none: 0 }); expect(result).toEqual([]); @@ -17,8 +18,12 @@ describe('getVulnerabilitiesAggregationCount', () => { it('should return stats for low, medium, high, and critical vulnerabilities', () => { const result = getVulnerabilityStats({ critical: 1, high: 2, medium: 3, low: 4, none: 5 }); + const resultWithoutFunctions = result.map((item) => { + const { filter, reset, ...rest } = item; + return rest; + }); - expect(result).toEqual([ + expect(resultWithoutFunctions).toEqual([ { key: i18n.translate( 'xpack.securitySolution.flyout.right.insights.vulnerabilities.noneVulnerabilitiesText', @@ -28,6 +33,7 @@ describe('getVulnerabilitiesAggregationCount', () => { ), count: 5, color: '#aaa', + isCurrentFilter: false, }, { key: i18n.translate( @@ -38,6 +44,7 @@ describe('getVulnerabilitiesAggregationCount', () => { ), count: 4, color: euiThemeVars.euiColorVis0, + isCurrentFilter: false, }, { key: i18n.translate( @@ -48,6 +55,7 @@ describe('getVulnerabilitiesAggregationCount', () => { ), count: 3, color: euiThemeVars.euiColorVis5_behindText, + isCurrentFilter: false, }, { key: i18n.translate( @@ -58,6 +66,7 @@ describe('getVulnerabilitiesAggregationCount', () => { ), count: 2, color: euiThemeVars.euiColorVis9_behindText, + isCurrentFilter: false, }, { key: i18n.translate( @@ -68,7 +77,43 @@ describe('getVulnerabilitiesAggregationCount', () => { ), count: 1, color: euiThemeVars.euiColorDanger, + isCurrentFilter: false, }, ]); }); + + it('should return correct stats with correct onClick functions', () => { + const result = getVulnerabilityStats( + { critical: 1, high: 2, medium: 3, low: 4, none: 5 }, + mockFilterFunction + ); + const event = { stopPropagation: jest.fn() } as unknown as React.MouseEvent< + SVGElement, + MouseEvent + >; + result[1].filter?.(); + expect(mockFilterFunction).toHaveBeenCalledWith('LOW'); + result[1].reset?.(event); + expect(mockFilterFunction).toHaveBeenCalledWith(''); + }); + + it('should identify correct currentFilter', () => { + const currentFilter = 'LOW'; + const result = getVulnerabilityStats( + { critical: 1, high: 2, medium: 3, low: 4, none: 5 }, + mockFilterFunction, + currentFilter + ); + + // Make sure that Low is set to Current Filter + expect(result[1].isCurrentFilter).toBe(true); + expect(result[1].key).toBe('Low'); + + // Make sure only Low is set as Current Filter and no other severity + result.forEach((item) => { + if (item.key !== 'Low') { + expect(item.isCurrentFilter).toBe(false); + } + }); + }); }); diff --git a/x-pack/packages/kbn-cloud-security-posture/public/src/utils/vulnerability_helpers.ts b/x-pack/packages/kbn-cloud-security-posture/public/src/utils/vulnerability_helpers.ts index c8782daf35308..e1bec795ad444 100644 --- a/x-pack/packages/kbn-cloud-security-posture/public/src/utils/vulnerability_helpers.ts +++ b/x-pack/packages/kbn-cloud-security-posture/public/src/utils/vulnerability_helpers.ts @@ -14,6 +14,9 @@ interface VulnerabilitiesDistributionBarProps { key: string; count: number; color: string; + isCurrentFilter?: boolean; + filter?: () => void; + reset?: (event: any) => void; } interface VulnerabilityCounts { @@ -30,7 +33,9 @@ export const hasVulnerabilitiesData = (counts: VulnerabilityCounts): boolean => }; export const getVulnerabilityStats = ( - counts: VulnerabilityCounts + counts: VulnerabilityCounts, + filterFunction?: (filter: string) => void, + currentFilter?: string ): VulnerabilitiesDistributionBarProps[] => { const vulnerabilityStats: VulnerabilitiesDistributionBarProps[] = []; @@ -50,6 +55,14 @@ export const getVulnerabilityStats = ( ), count: counts.none, color: getSeverityStatusColor(VULNERABILITIES_SEVERITY.UNKNOWN), + filter: () => { + filterFunction?.(VULNERABILITIES_SEVERITY.UNKNOWN); + }, + isCurrentFilter: currentFilter === VULNERABILITIES_SEVERITY.UNKNOWN, + reset: (event: React.MouseEvent) => { + filterFunction?.(''); + event?.stopPropagation(); + }, }); if (counts.low > 0) vulnerabilityStats.push({ @@ -61,6 +74,14 @@ export const getVulnerabilityStats = ( ), count: counts.low, color: getSeverityStatusColor(VULNERABILITIES_SEVERITY.LOW), + filter: () => { + filterFunction?.(VULNERABILITIES_SEVERITY.LOW); + }, + isCurrentFilter: currentFilter === VULNERABILITIES_SEVERITY.LOW, + reset: (event: React.MouseEvent) => { + filterFunction?.(''); + event?.stopPropagation(); + }, }); if (counts.medium > 0) @@ -73,6 +94,14 @@ export const getVulnerabilityStats = ( ), count: counts.medium, color: getSeverityStatusColor(VULNERABILITIES_SEVERITY.MEDIUM), + filter: () => { + filterFunction?.(VULNERABILITIES_SEVERITY.MEDIUM); + }, + isCurrentFilter: currentFilter === VULNERABILITIES_SEVERITY.MEDIUM, + reset: (event: React.MouseEvent) => { + filterFunction?.(''); + event?.stopPropagation(); + }, }); if (counts.high > 0) vulnerabilityStats.push({ @@ -84,6 +113,14 @@ export const getVulnerabilityStats = ( ), count: counts.high, color: getSeverityStatusColor(VULNERABILITIES_SEVERITY.HIGH), + filter: () => { + filterFunction?.(VULNERABILITIES_SEVERITY.HIGH); + }, + isCurrentFilter: currentFilter === VULNERABILITIES_SEVERITY.HIGH, + reset: (event: React.MouseEvent) => { + filterFunction?.(''); + event?.stopPropagation(); + }, }); if (counts.critical > 0) vulnerabilityStats.push({ @@ -95,6 +132,14 @@ export const getVulnerabilityStats = ( ), count: counts.critical, color: getSeverityStatusColor(VULNERABILITIES_SEVERITY.CRITICAL), + filter: () => { + filterFunction?.(VULNERABILITIES_SEVERITY.CRITICAL); + }, + isCurrentFilter: currentFilter === VULNERABILITIES_SEVERITY.CRITICAL, + reset: (event: React.MouseEvent) => { + filterFunction?.(''); + event?.stopPropagation(); + }, }); return vulnerabilityStats; diff --git a/x-pack/packages/kbn-entities-schema/src/schema/entity.ts b/x-pack/packages/kbn-entities-schema/src/schema/entity.ts index 5df10e11bb7ed..c24da00d7724e 100644 --- a/x-pack/packages/kbn-entities-schema/src/schema/entity.ts +++ b/x-pack/packages/kbn-entities-schema/src/schema/entity.ts @@ -25,8 +25,9 @@ export interface MetadataRecord { export interface EntityV2 { 'entity.id': string; - 'entity.last_seen_timestamp': string; 'entity.type': string; + 'entity.display_name': string; + 'entity.last_seen_timestamp'?: string; [metadata: string]: any; } diff --git a/x-pack/packages/kbn-slo-schema/src/schema/slo.ts b/x-pack/packages/kbn-slo-schema/src/schema/slo.ts index 0576f1cf328eb..c292d355b4867 100644 --- a/x-pack/packages/kbn-slo-schema/src/schema/slo.ts +++ b/x-pack/packages/kbn-slo-schema/src/schema/slo.ts @@ -27,16 +27,26 @@ const objectiveSchema = t.intersection([ t.partial({ timesliceTarget: t.number, timesliceWindow: durationType }), ]); -const settingsSchema = t.type({ +const settingsSchema = t.intersection([ + t.type({ + syncDelay: durationType, + frequency: durationType, + preventInitialBackfill: t.boolean, + }), + t.partial({ syncField: t.union([t.string, t.null]) }), +]); + +const groupBySchema = allOrAnyStringOrArray; + +const optionalSettingsSchema = t.partial({ syncDelay: durationType, frequency: durationType, preventInitialBackfill: t.boolean, + syncField: t.union([t.string, t.null]), }); -const groupBySchema = allOrAnyStringOrArray; - -const optionalSettingsSchema = t.partial({ ...settingsSchema.props }); const tagsSchema = t.array(t.string); + // id cannot contain special characters and spaces const sloIdSchema = new t.Type( 'sloIdSchema', diff --git a/x-pack/packages/ml/aiops_components/src/document_count_chart/document_count_chart.tsx b/x-pack/packages/ml/aiops_components/src/document_count_chart/document_count_chart.tsx index d9f68fe7ef890..6e44f01cbbd69 100644 --- a/x-pack/packages/ml/aiops_components/src/document_count_chart/document_count_chart.tsx +++ b/x-pack/packages/ml/aiops_components/src/document_count_chart/document_count_chart.tsx @@ -136,6 +136,8 @@ export interface DocumentCountChartProps { dataTestSubj?: string; /** Optional change point metadata */ changePoint?: DocumentCountStatsChangePoint; + /** Whether the brush should be non-interactive */ + nonInteractive?: boolean; } const SPEC_ID = 'document_count'; @@ -190,6 +192,7 @@ export const DocumentCountChart: FC = (props) => { barHighlightColorOverride, deviationBrush = {}, baselineBrush = {}, + nonInteractive, } = props; const { data, uiSettings, fieldFormats, charts } = dependencies; @@ -470,6 +473,7 @@ export const DocumentCountChart: FC = (props) => { marginLeft={mlBrushMarginLeft} snapTimestamps={snapTimestamps} width={mlBrushWidth} + nonInteractive={nonInteractive} /> diff --git a/x-pack/packages/ml/aiops_components/src/dual_brush/dual_brush.tsx b/x-pack/packages/ml/aiops_components/src/dual_brush/dual_brush.tsx index 08b9fc5628297..932f509e164de 100644 --- a/x-pack/packages/ml/aiops_components/src/dual_brush/dual_brush.tsx +++ b/x-pack/packages/ml/aiops_components/src/dual_brush/dual_brush.tsx @@ -88,6 +88,11 @@ interface DualBrushProps { * Width */ width: number; + /** + * Whether the brush should be non-interactive. When true, the brush is still visible + * but cannot be moved or resized by the user. + */ + nonInteractive?: boolean; } /** @@ -98,7 +103,16 @@ interface DualBrushProps { * @returns The DualBrush component. */ export const DualBrush: FC = (props) => { - const { windowParameters, min, max, onChange, marginLeft, snapTimestamps, width } = props; + const { + windowParameters, + min, + max, + onChange, + marginLeft, + snapTimestamps, + width, + nonInteractive, + } = props; const d3BrushContainer = useRef(null); const brushes = useRef([]); @@ -301,6 +315,10 @@ export const DualBrush: FC = (props) => { .attr('rx', BRUSH_HANDLE_ROUNDED_CORNER) .attr('ry', BRUSH_HANDLE_ROUNDED_CORNER); + if (nonInteractive) { + mlBrushSelection.merge(mlBrushSelection).attr('pointer-events', 'none'); + } + mlBrushSelection.exit().remove(); } @@ -355,6 +373,7 @@ export const DualBrush: FC = (props) => { deviationMax, snapTimestamps, onChange, + nonInteractive, ]); return ( diff --git a/x-pack/packages/ml/aiops_components/src/progress_controls/progress_controls.tsx b/x-pack/packages/ml/aiops_components/src/progress_controls/progress_controls.tsx index 173f33e08f0b4..7308185f99b65 100644 --- a/x-pack/packages/ml/aiops_components/src/progress_controls/progress_controls.tsx +++ b/x-pack/packages/ml/aiops_components/src/progress_controls/progress_controls.tsx @@ -40,6 +40,7 @@ interface ProgressControlProps { shouldRerunAnalysis: boolean; runAnalysisDisabled?: boolean; analysisInfo?: React.ReactNode; + isAnalysisControlsDisabled?: boolean; } /** @@ -63,6 +64,7 @@ export const ProgressControls: FC> = (pr shouldRerunAnalysis, runAnalysisDisabled = false, analysisInfo = null, + isAnalysisControlsDisabled = false, } = props; const progressOutput = Math.round(progress * 100); @@ -73,47 +75,55 @@ export const ProgressControls: FC> = (pr return ( - - {!isRunning && ( - - - - - - {shouldRerunAnalysis && ( - <> - - - - - )} - - - )} - {isRunning && ( - - - - )} - - {(progress === 1 || isRunning === false) && !isBrushCleared ? ( + {!isAnalysisControlsDisabled && ( + + {!isRunning && ( + + + + + + {shouldRerunAnalysis && ( + <> + + + + + )} + + + )} + {isRunning && ( + + + + )} + + )} + + {(progress === 1 || isRunning === false) && !isBrushCleared && !isAnalysisControlsDisabled ? ( ( {children} ); @@ -34,7 +38,7 @@ describe('useAlertsHistory', () => { const end = '2023-05-10T00:00:00.000Z'; const ruleId = 'cfd36e60-ef22-11ed-91eb-b7893acacfe2'; - afterEach(() => { + beforeEach(() => { jest.clearAllMocks(); }); @@ -44,7 +48,7 @@ describe('useAlertsHistory', () => { () => useAlertsHistory({ http, - featureIds: [AlertConsumers.APM], + ruleTypeIds: ['apm'], ruleId, dateRange: { from: start, to: end }, }), @@ -61,16 +65,13 @@ describe('useAlertsHistory', () => { }); it('returns no data when API error', async () => { - const http = { - post: jest.fn().mockImplementation(() => { - throw new Error('ES error'); - }), - } as unknown as HttpSetup; + mockServices.http.post.mockRejectedValueOnce(new Error('ES error')); + const { result, waitFor } = renderHook( () => useAlertsHistory({ - http, - featureIds: [AlertConsumers.APM], + ...mockServices, + ruleTypeIds: ['apm'], ruleId, dateRange: { from: start, to: end }, }), @@ -87,54 +88,53 @@ describe('useAlertsHistory', () => { }); it('returns the alert history chart data', async () => { - const http = { - post: jest.fn().mockResolvedValue({ - hits: { total: { value: 32, relation: 'eq' }, max_score: null, hits: [] }, - aggregations: { - avgTimeToRecoverUS: { doc_count: 28, recoveryTime: { value: 134959464.2857143 } }, - histogramTriggeredAlerts: { - buckets: [ - { key_as_string: '2023-04-10T00:00:00.000Z', key: 1681084800000, doc_count: 0 }, - { key_as_string: '2023-04-11T00:00:00.000Z', key: 1681171200000, doc_count: 0 }, - { key_as_string: '2023-04-12T00:00:00.000Z', key: 1681257600000, doc_count: 0 }, - { key_as_string: '2023-04-13T00:00:00.000Z', key: 1681344000000, doc_count: 0 }, - { key_as_string: '2023-04-14T00:00:00.000Z', key: 1681430400000, doc_count: 0 }, - { key_as_string: '2023-04-15T00:00:00.000Z', key: 1681516800000, doc_count: 0 }, - { key_as_string: '2023-04-16T00:00:00.000Z', key: 1681603200000, doc_count: 0 }, - { key_as_string: '2023-04-17T00:00:00.000Z', key: 1681689600000, doc_count: 0 }, - { key_as_string: '2023-04-18T00:00:00.000Z', key: 1681776000000, doc_count: 0 }, - { key_as_string: '2023-04-19T00:00:00.000Z', key: 1681862400000, doc_count: 0 }, - { key_as_string: '2023-04-20T00:00:00.000Z', key: 1681948800000, doc_count: 0 }, - { key_as_string: '2023-04-21T00:00:00.000Z', key: 1682035200000, doc_count: 0 }, - { key_as_string: '2023-04-22T00:00:00.000Z', key: 1682121600000, doc_count: 0 }, - { key_as_string: '2023-04-23T00:00:00.000Z', key: 1682208000000, doc_count: 0 }, - { key_as_string: '2023-04-24T00:00:00.000Z', key: 1682294400000, doc_count: 0 }, - { key_as_string: '2023-04-25T00:00:00.000Z', key: 1682380800000, doc_count: 0 }, - { key_as_string: '2023-04-26T00:00:00.000Z', key: 1682467200000, doc_count: 0 }, - { key_as_string: '2023-04-27T00:00:00.000Z', key: 1682553600000, doc_count: 0 }, - { key_as_string: '2023-04-28T00:00:00.000Z', key: 1682640000000, doc_count: 0 }, - { key_as_string: '2023-04-29T00:00:00.000Z', key: 1682726400000, doc_count: 0 }, - { key_as_string: '2023-04-30T00:00:00.000Z', key: 1682812800000, doc_count: 0 }, - { key_as_string: '2023-05-01T00:00:00.000Z', key: 1682899200000, doc_count: 0 }, - { key_as_string: '2023-05-02T00:00:00.000Z', key: 1682985600000, doc_count: 0 }, - { key_as_string: '2023-05-03T00:00:00.000Z', key: 1683072000000, doc_count: 0 }, - { key_as_string: '2023-05-04T00:00:00.000Z', key: 1683158400000, doc_count: 0 }, - { key_as_string: '2023-05-05T00:00:00.000Z', key: 1683244800000, doc_count: 0 }, - { key_as_string: '2023-05-06T00:00:00.000Z', key: 1683331200000, doc_count: 0 }, - { key_as_string: '2023-05-07T00:00:00.000Z', key: 1683417600000, doc_count: 0 }, - { key_as_string: '2023-05-08T00:00:00.000Z', key: 1683504000000, doc_count: 0 }, - { key_as_string: '2023-05-09T00:00:00.000Z', key: 1683590400000, doc_count: 0 }, - { key_as_string: '2023-05-10T00:00:00.000Z', key: 1683676800000, doc_count: 32 }, - ], - }, + mockServices.http.post.mockResolvedValueOnce({ + hits: { total: { value: 32, relation: 'eq' }, max_score: null, hits: [] }, + aggregations: { + avgTimeToRecoverUS: { doc_count: 28, recoveryTime: { value: 134959464.2857143 } }, + histogramTriggeredAlerts: { + buckets: [ + { key_as_string: '2023-04-10T00:00:00.000Z', key: 1681084800000, doc_count: 0 }, + { key_as_string: '2023-04-11T00:00:00.000Z', key: 1681171200000, doc_count: 0 }, + { key_as_string: '2023-04-12T00:00:00.000Z', key: 1681257600000, doc_count: 0 }, + { key_as_string: '2023-04-13T00:00:00.000Z', key: 1681344000000, doc_count: 0 }, + { key_as_string: '2023-04-14T00:00:00.000Z', key: 1681430400000, doc_count: 0 }, + { key_as_string: '2023-04-15T00:00:00.000Z', key: 1681516800000, doc_count: 0 }, + { key_as_string: '2023-04-16T00:00:00.000Z', key: 1681603200000, doc_count: 0 }, + { key_as_string: '2023-04-17T00:00:00.000Z', key: 1681689600000, doc_count: 0 }, + { key_as_string: '2023-04-18T00:00:00.000Z', key: 1681776000000, doc_count: 0 }, + { key_as_string: '2023-04-19T00:00:00.000Z', key: 1681862400000, doc_count: 0 }, + { key_as_string: '2023-04-20T00:00:00.000Z', key: 1681948800000, doc_count: 0 }, + { key_as_string: '2023-04-21T00:00:00.000Z', key: 1682035200000, doc_count: 0 }, + { key_as_string: '2023-04-22T00:00:00.000Z', key: 1682121600000, doc_count: 0 }, + { key_as_string: '2023-04-23T00:00:00.000Z', key: 1682208000000, doc_count: 0 }, + { key_as_string: '2023-04-24T00:00:00.000Z', key: 1682294400000, doc_count: 0 }, + { key_as_string: '2023-04-25T00:00:00.000Z', key: 1682380800000, doc_count: 0 }, + { key_as_string: '2023-04-26T00:00:00.000Z', key: 1682467200000, doc_count: 0 }, + { key_as_string: '2023-04-27T00:00:00.000Z', key: 1682553600000, doc_count: 0 }, + { key_as_string: '2023-04-28T00:00:00.000Z', key: 1682640000000, doc_count: 0 }, + { key_as_string: '2023-04-29T00:00:00.000Z', key: 1682726400000, doc_count: 0 }, + { key_as_string: '2023-04-30T00:00:00.000Z', key: 1682812800000, doc_count: 0 }, + { key_as_string: '2023-05-01T00:00:00.000Z', key: 1682899200000, doc_count: 0 }, + { key_as_string: '2023-05-02T00:00:00.000Z', key: 1682985600000, doc_count: 0 }, + { key_as_string: '2023-05-03T00:00:00.000Z', key: 1683072000000, doc_count: 0 }, + { key_as_string: '2023-05-04T00:00:00.000Z', key: 1683158400000, doc_count: 0 }, + { key_as_string: '2023-05-05T00:00:00.000Z', key: 1683244800000, doc_count: 0 }, + { key_as_string: '2023-05-06T00:00:00.000Z', key: 1683331200000, doc_count: 0 }, + { key_as_string: '2023-05-07T00:00:00.000Z', key: 1683417600000, doc_count: 0 }, + { key_as_string: '2023-05-08T00:00:00.000Z', key: 1683504000000, doc_count: 0 }, + { key_as_string: '2023-05-09T00:00:00.000Z', key: 1683590400000, doc_count: 0 }, + { key_as_string: '2023-05-10T00:00:00.000Z', key: 1683676800000, doc_count: 32 }, + ], }, - }), - } as unknown as HttpSetup; + }, + }); + const { result, waitFor } = renderHook( () => useAlertsHistory({ - http, - featureIds: [AlertConsumers.APM], + ...mockServices, + ruleTypeIds: ['apm'], ruleId, dateRange: { from: start, to: end }, }), @@ -155,26 +155,24 @@ describe('useAlertsHistory', () => { it('calls http post including instanceId query', async () => { const controller = new AbortController(); const signal = controller.signal; - const mockedHttpPost = jest.fn(); - const http = { - post: mockedHttpPost.mockResolvedValue({ - hits: { total: { value: 32, relation: 'eq' }, max_score: null, hits: [] }, - aggregations: { - avgTimeToRecoverUS: { doc_count: 28, recoveryTime: { value: 134959464.2857143 } }, - histogramTriggeredAlerts: { - buckets: [ - { key_as_string: '2023-04-10T00:00:00.000Z', key: 1681084800000, doc_count: 0 }, - ], - }, + mockServices.http.post.mockResolvedValueOnce({ + hits: { total: { value: 32, relation: 'eq' }, max_score: null, hits: [] }, + aggregations: { + avgTimeToRecoverUS: { doc_count: 28, recoveryTime: { value: 134959464.2857143 } }, + histogramTriggeredAlerts: { + buckets: [ + { key_as_string: '2023-04-10T00:00:00.000Z', key: 1681084800000, doc_count: 0 }, + ], }, - }), - } as unknown as HttpSetup; + }, + }); const { result, waitFor } = renderHook( () => useAlertsHistory({ - http, - featureIds: [AlertConsumers.APM], + ...mockServices, + ruleTypeIds: ['apm'], + consumers: ['foo'], ruleId, dateRange: { from: start, to: end }, instanceId: 'instance-1', @@ -187,9 +185,10 @@ describe('useAlertsHistory', () => { await act(async () => { await waitFor(() => result.current.isSuccess); }); - expect(mockedHttpPost).toBeCalledWith('/internal/rac/alerts/find', { + + expect(mockServices.http.post).toBeCalledWith('/internal/rac/alerts/find', { body: - '{"size":0,"feature_ids":["apm"],"query":{"bool":{"must":[' + + '{"size":0,"rule_type_ids":["apm"],"consumers":["foo"],"query":{"bool":{"must":[' + '{"term":{"kibana.alert.rule.uuid":"cfd36e60-ef22-11ed-91eb-b7893acacfe2"}},' + '{"term":{"kibana.alert.instance.id":"instance-1"}},' + '{"range":{"kibana.alert.time_range":{"from":"2023-04-10T00:00:00.000Z","to":"2023-05-10T00:00:00.000Z"}}}]}},' + @@ -204,26 +203,23 @@ describe('useAlertsHistory', () => { it('calls http post without * instanceId query', async () => { const controller = new AbortController(); const signal = controller.signal; - const mockedHttpPost = jest.fn(); - const http = { - post: mockedHttpPost.mockResolvedValue({ - hits: { total: { value: 32, relation: 'eq' }, max_score: null, hits: [] }, - aggregations: { - avgTimeToRecoverUS: { doc_count: 28, recoveryTime: { value: 134959464.2857143 } }, - histogramTriggeredAlerts: { - buckets: [ - { key_as_string: '2023-04-10T00:00:00.000Z', key: 1681084800000, doc_count: 0 }, - ], - }, + mockServices.http.post.mockResolvedValueOnce({ + hits: { total: { value: 32, relation: 'eq' }, max_score: null, hits: [] }, + aggregations: { + avgTimeToRecoverUS: { doc_count: 28, recoveryTime: { value: 134959464.2857143 } }, + histogramTriggeredAlerts: { + buckets: [ + { key_as_string: '2023-04-10T00:00:00.000Z', key: 1681084800000, doc_count: 0 }, + ], }, - }), - } as unknown as HttpSetup; + }, + }); const { result, waitFor } = renderHook( () => useAlertsHistory({ - http, - featureIds: [AlertConsumers.APM], + ...mockServices, + ruleTypeIds: ['apm'], ruleId, dateRange: { from: start, to: end }, instanceId: '*', @@ -236,9 +232,10 @@ describe('useAlertsHistory', () => { await act(async () => { await waitFor(() => result.current.isSuccess); }); - expect(mockedHttpPost).toBeCalledWith('/internal/rac/alerts/find', { + + expect(mockServices.http.post).toBeCalledWith('/internal/rac/alerts/find', { body: - '{"size":0,"feature_ids":["apm"],"query":{"bool":{"must":[' + + '{"size":0,"rule_type_ids":["apm"],"query":{"bool":{"must":[' + '{"term":{"kibana.alert.rule.uuid":"cfd36e60-ef22-11ed-91eb-b7893acacfe2"}},' + '{"range":{"kibana.alert.time_range":{"from":"2023-04-10T00:00:00.000Z","to":"2023-05-10T00:00:00.000Z"}}}]}},' + '"aggs":{"histogramTriggeredAlerts":{"date_histogram":{"field":"kibana.alert.start","fixed_interval":"1d",' + diff --git a/x-pack/packages/observability/alert_details/src/hooks/use_alerts_history.ts b/x-pack/packages/observability/alert_details/src/hooks/use_alerts_history.ts index 193acb63f845b..d045fab2e635b 100644 --- a/x-pack/packages/observability/alert_details/src/hooks/use_alerts_history.ts +++ b/x-pack/packages/observability/alert_details/src/hooks/use_alerts_history.ts @@ -14,14 +14,14 @@ import { ALERT_START, ALERT_STATUS, ALERT_TIME_RANGE, - ValidFeatureId, } from '@kbn/rule-data-utils'; import { BASE_RAC_ALERTS_API_PATH } from '@kbn/rule-registry-plugin/common'; import { useQuery } from '@tanstack/react-query'; export interface Props { http: HttpSetup | undefined; - featureIds: ValidFeatureId[]; + ruleTypeIds: string[]; + consumers?: string[]; ruleId: string; dateRange: { from: string; @@ -49,13 +49,15 @@ export const EMPTY_ALERTS_HISTORY = { }; export function useAlertsHistory({ - featureIds, + ruleTypeIds, + consumers, ruleId, dateRange, http, instanceId, }: Props): UseAlertsHistory { - const enabled = !!featureIds.length; + const enabled = !!ruleTypeIds.length; + const { isInitialLoading, isLoading, isError, isSuccess, isRefetching, data } = useQuery({ queryKey: ['useAlertsHistory'], queryFn: async ({ signal }) => { @@ -63,7 +65,8 @@ export function useAlertsHistory({ throw new Error('Http client is missing'); } return fetchTriggeredAlertsHistory({ - featureIds, + ruleTypeIds, + consumers, http, ruleId, dateRange, @@ -74,6 +77,7 @@ export function useAlertsHistory({ refetchOnWindowFocus: false, enabled, }); + return { data: isInitialLoading ? EMPTY_ALERTS_HISTORY : data ?? EMPTY_ALERTS_HISTORY, isLoading: enabled && (isInitialLoading || isLoading || isRefetching), @@ -101,14 +105,16 @@ interface AggsESResponse { } export async function fetchTriggeredAlertsHistory({ - featureIds, + ruleTypeIds, + consumers, http, ruleId, dateRange, signal, instanceId, }: { - featureIds: ValidFeatureId[]; + ruleTypeIds: string[]; + consumers?: string[]; http: HttpSetup; ruleId: string; dateRange: { @@ -123,7 +129,8 @@ export async function fetchTriggeredAlertsHistory({ signal, body: JSON.stringify({ size: 0, - feature_ids: featureIds, + rule_type_ids: ruleTypeIds, + consumers, query: { bool: { must: [ diff --git a/x-pack/packages/observability/alert_details/tsconfig.json b/x-pack/packages/observability/alert_details/tsconfig.json index a349651fdff7e..d1b4c3fb2ce23 100644 --- a/x-pack/packages/observability/alert_details/tsconfig.json +++ b/x-pack/packages/observability/alert_details/tsconfig.json @@ -17,9 +17,9 @@ ], "kbn_references": [ "@kbn/i18n", - "@kbn/core-http-browser", "@kbn/rule-data-utils", "@kbn/core", - "@kbn/rule-registry-plugin" + "@kbn/rule-registry-plugin", + "@kbn/core-http-browser-mocks" ] } diff --git a/x-pack/packages/observability/logs_overview/src/components/log_categories/log_categories_result_content.tsx b/x-pack/packages/observability/logs_overview/src/components/log_categories/log_categories_result_content.tsx index c2b1a0989c2ec..fdb059d971943 100644 --- a/x-pack/packages/observability/logs_overview/src/components/log_categories/log_categories_result_content.tsx +++ b/x-pack/packages/observability/logs_overview/src/components/log_categories/log_categories_result_content.tsx @@ -76,7 +76,6 @@ export const LogCategoriesResultContent: React.FC void; logCategory: LogCategory; - categoryDetailsServiceState: StateFrom; dependencies: LogCategoriesFlyoutDependencies; logsSource: ResolvedIndexNameLogsSourceConfiguration; documentFilters?: QueryDslQueryContainer[]; @@ -51,7 +55,6 @@ interface LogCategoryDetailsFlyoutProps { export const LogCategoryDetailsFlyout: React.FC = ({ onCloseFlyout, logCategory, - categoryDetailsServiceState, dependencies, logsSource, documentFilters, @@ -61,11 +64,19 @@ export const LogCategoryDetailsFlyout: React.FC = prefix: 'flyoutTitle', }); + const categoryFilter = useMemo(() => { + return createCategoryQuery(logsSource.messageField)(logCategory.terms); + }, [logCategory.terms, logsSource.messageField]); + + const documentAndCategoryFilters = useMemo(() => { + return [...(documentFilters ?? []), categoryFilter]; + }, [categoryFilter, documentFilters]); + const linkFilters = useMemo(() => { return [ ...(documentFilters ? documentFilters.map((filter) => ({ filter })) : []), { - filter: createCategoryQuery(logsSource.messageField)(logCategory.terms), + filter: categoryFilter, meta: { name: i18n.translate( 'xpack.observabilityLogsOverview.logCategoryDetailsFlyout.discoverLinkFilterName', @@ -79,7 +90,20 @@ export const LogCategoryDetailsFlyout: React.FC = }, }, ]; - }, [documentFilters, logCategory.terms, logsSource.messageField]); + }, [categoryFilter, documentFilters, logCategory.terms]); + + const filters = useMemo(() => { + return documentAndCategoryFilters.map((filter) => + buildCustomFilter( + logsSource.indexName, + filter, + false, + false, + 'Document filters', + FilterStateStore.APP_STATE + ) + ); + }, [documentAndCategoryFilters, logsSource.indexName]); return ( onCloseFlyout()} aria-labelledby={flyoutTitleId}> @@ -107,32 +131,12 @@ export const LogCategoryDetailsFlyout: React.FC = - - {categoryDetailsServiceState.matches({ hasCategory: 'fetchingDocuments' }) ? ( - - ) : categoryDetailsServiceState.matches({ hasCategory: 'error' }) ? ( - - ) : ( - - )} + + ); diff --git a/x-pack/packages/observability/logs_overview/src/components/log_category_details/log_category_document_examples_table.tsx b/x-pack/packages/observability/logs_overview/src/components/log_category_details/log_category_document_examples_table.tsx index 6b43fa86fe49e..0101a2496415f 100644 --- a/x-pack/packages/observability/logs_overview/src/components/log_category_details/log_category_document_examples_table.tsx +++ b/x-pack/packages/observability/logs_overview/src/components/log_category_details/log_category_document_examples_table.tsx @@ -5,147 +5,45 @@ * 2.0. */ -import { EuiBasicTable, EuiBasicTableColumn, EuiSpacer, EuiText } from '@elastic/eui'; -import React, { useMemo } from 'react'; -import { i18n } from '@kbn/i18n'; -import { DataGridDensity, ROWS_HEIGHT_OPTIONS } from '@kbn/unified-data-table'; -import moment from 'moment'; -import type { SettingsStart } from '@kbn/core-ui-settings-browser'; -import type { FieldFormatsStart } from '@kbn/field-formats-plugin/public'; -import type { SharePluginStart } from '@kbn/share-plugin/public'; -import { CoreStart } from '@kbn/core-lifecycle-browser'; -import { getLogLevelBadgeCell, LazySummaryColumn } from '@kbn/discover-contextual-components'; -import type { LogCategoryDocument } from '../../services/category_details_service/types'; -import { type ResolvedIndexNameLogsSourceConfiguration } from '../../utils/logs_source'; +import React from 'react'; +import { LazySavedSearchComponent } from '@kbn/saved-search-component'; +import { EmbeddableStart } from '@kbn/embeddable-plugin/public'; +import { DataViewsContract } from '@kbn/data-views-plugin/public'; +import { ISearchStartSearchSource } from '@kbn/data-plugin/common'; +import { Filter } from '@kbn/es-query'; +import { ResolvedIndexNameLogsSourceConfiguration } from '../../utils/logs_source'; export interface LogCategoryDocumentExamplesTableDependencies { - core: CoreStart; - uiSettings: SettingsStart; - fieldFormats: FieldFormatsStart; - share: SharePluginStart; + embeddable: EmbeddableStart; + dataViews: DataViewsContract; + searchSource: ISearchStartSearchSource; } export interface LogCategoryDocumentExamplesTableProps { dependencies: LogCategoryDocumentExamplesTableDependencies; - categoryDocuments: LogCategoryDocument[]; logsSource: ResolvedIndexNameLogsSourceConfiguration; + filters: Filter[]; } -const TimestampCell = ({ - dependencies, - timestamp, -}: { - dependencies: LogCategoryDocumentExamplesTableDependencies; - timestamp?: string | number; -}) => { - const dateFormat = useMemo( - () => dependencies.uiSettings.client.get('dateFormat'), - [dependencies.uiSettings.client] - ); - if (!timestamp) return null; - - if (dateFormat) { - return <>{moment(timestamp).format(dateFormat)}; - } else { - return <>{timestamp}; - } -}; - -const LogLevelBadgeCell = getLogLevelBadgeCell('log.level'); - export const LogCategoryDocumentExamplesTable: React.FC = ({ - categoryDocuments, dependencies, + filters, logsSource, }) => { - const columns: Array> = [ - { - field: 'row', - name: 'Timestamp', - width: '25%', - render: (row: any) => { - return ( - - ); - }, - }, - { - field: 'row', - name: 'Log level', - width: '10%', - render: (row: any) => { - return ( - {}} - closePopover={() => {}} - /> - ); - }, - }, - { - field: 'row', - name: 'Summary', - width: '65%', - render: (row: any) => { - return ( - {}} - closePopover={() => {}} - density={DataGridDensity.COMPACT} - rowHeight={ROWS_HEIGHT_OPTIONS.single} - shouldShowFieldHandler={() => false} - core={dependencies.core} - share={dependencies.share} - /> - ); - }, - }, - ]; return ( - <> - - {i18n.translate( - 'xpack.observabilityLogsOverview.logCategoryDocumentExamplesTable.documentCountText', - { - defaultMessage: 'Displaying the latest {documentsCount} documents.', - values: { - documentsCount: categoryDocuments.length, - }, - } - )} - - - - + ); }; diff --git a/x-pack/packages/observability/logs_overview/src/services/category_details_service/category_details_service.ts b/x-pack/packages/observability/logs_overview/src/services/category_details_service/category_details_service.ts index 958f717548600..40dc0d1eca122 100644 --- a/x-pack/packages/observability/logs_overview/src/services/category_details_service/category_details_service.ts +++ b/x-pack/packages/observability/logs_overview/src/services/category_details_service/category_details_service.ts @@ -7,40 +7,24 @@ import { MachineImplementationsFrom, assign, setup } from 'xstate5'; import { LogCategory } from '../../types'; -import { getPlaceholderFor } from '../../utils/xstate5_utils'; -import { - CategoryDetailsServiceDependencies, - LogCategoryDocument, - LogCategoryDetailsParams, -} from './types'; -import { getCategoryDocuments } from './category_documents'; +import { CategoryDetailsServiceDependencies, LogCategoryDetailsParams } from './types'; export const categoryDetailsService = setup({ types: { input: {} as LogCategoryDetailsParams, - output: {} as { - categoryDocuments: LogCategoryDocument[] | null; - }, + output: {} as {}, context: {} as { parameters: LogCategoryDetailsParams; - error?: Error; expandedRowIndex: number | null; expandedCategory: LogCategory | null; - categoryDocuments: LogCategoryDocument[]; }, - events: {} as - | { - type: 'cancel'; - } - | { - type: 'setExpandedCategory'; - rowIndex: number | null; - category: LogCategory | null; - }, - }, - actors: { - getCategoryDocuments: getPlaceholderFor(getCategoryDocuments), + events: {} as { + type: 'setExpandedCategory'; + rowIndex: number | null; + category: LogCategory | null; + }, }, + actors: {}, actions: { storeCategory: assign( ({ context, event }, params: { category: LogCategory | null; rowIndex: number | null }) => ({ @@ -48,22 +32,10 @@ export const categoryDetailsService = setup({ expandedRowIndex: params.rowIndex, }) ), - storeDocuments: assign( - ({ context, event }, params: { categoryDocuments: LogCategoryDocument[] }) => ({ - categoryDocuments: params.categoryDocuments, - }) - ), - storeError: assign((_, params: { error: unknown }) => ({ - error: params.error instanceof Error ? params.error : new Error(String(params.error)), - })), }, guards: { hasCategory: (_guardArgs, params: { expandedCategory: LogCategory | null }) => params.expandedCategory !== null, - hasDocumentExamples: ( - _guardArgs, - params: { categoryDocuments: LogCategoryDocument[] | null } - ) => params.categoryDocuments !== null && params.categoryDocuments.length > 0, }, }).createMachine({ /** @xstate-layout N4IgpgJg5mDOIC5QGMCGAXMUD2AnAlgF5gAy2UsAdMtgK4B26+9UAItsrQLZiOwDEEbPTCVmAN2wBrUWkw4CxMhWp1GzNh2690sBBI4Z8wgNoAGALrmLiUAAdssfE2G2QAD0QBmMwA5KACy+AQFmob4AjABMwQBsADQgAJ6IkYEAnJkA7FmxZlERmQGxAL4liXJYeESk5FQ0DEws7Jw8fILCogYy1BhVirUqDerNWm26+vSScsb01iYRNkggDk4u9G6eCD7+QSFhftFxiSkIvgCsWZSxEVlRsbFZ52Zm515lFX0KNcr1ak2aVo6ARCERiKbSWRfapKOqqRoaFraPiTaZGUyWExRJb2RzOWabbx+QLBULhI7FE7eWL+F45GnRPIRZkfECVb6wob-RFjYH8MC4XB4Sh2AA2GAAZnguL15DDBn8EaMgSiDDMMVZLG5VvjXMstjsSftyTFKclEOdzgFKF5zukvA8zBFnl50udWez5b94SNAcjdPw0PRkGBRdZtXj1oTtsS9mTDqaEuaEBF8udKFkIr5fK6olkzOksgEPdCBt6JWB0MgABYaADKqC4YsgAGFS-g4B0wd0oXKBg2m6LW+24OHljqo-rEMzbpQos8-K7fC9CknTrF0rEbbb0oVMoWIgF3eU2e3OVQK1XaywB82IG2+x2BAKhbgReL0FLcDLPf3G3eH36J8x1xNYCSnFNmSuecXhzdJlydTcqQQLJfHSOc0PyLJN3SMxYiPEtH3PShLxret-yHe8RwEIMQzDLVx0jcDQC2GdoIXOCENXZDsyiOcAiiKJ0iiPDLi8V1CKA4jSOvKAACUwC4VBmA0QDvk7UEughHpfxqBSlJUlg1OqUcGNA3UNggrMs347IjzdaIvGQwSvECXI8k3Z43gEiJJI5BUSMrMiWH05T6FU6j+UFYUxUlaVZSksBQsMqBjIIUycRWJi9RY6dIn8KIAjsu1zkc5CAmiG1fBiaIzB8B0QmPT4iICmSNGS8KjMi2jQxArKwJyjw8pswriocqInOTLwIi3ASD1yQpswCd5WXobAIDgNxdPPCMBss3KEAAWjXRBDvTfcLsu9Jlr8r04WGAEkXGeBGL26MBOQzIt2ut4cwmirCt8W6yzhNqbwo4dH0216LOjTMIjnBdYhK1DYgdHjihtZbUIdWIXJuYGflBoLZI6iKoZe8zJwOw9KtGt1kbuTcsmQrwi0oeCQjzZ5blwt1Cek5TKN22GIIKZbAgKC45pyLyeLwtz4Kyabs1QgWAs0kXqaGhBxdcnzpaE2XXmch0MORmaBJeLwjbKMogA */ @@ -71,7 +43,6 @@ export const categoryDetailsService = setup({ context: ({ input }) => ({ expandedCategory: null, expandedRowIndex: null, - categoryDocuments: [], parameters: input, }), initial: 'idle', @@ -79,38 +50,6 @@ export const categoryDetailsService = setup({ idle: { on: { setExpandedCategory: { - target: 'checkingCategoryState', - actions: [ - { - type: 'storeCategory', - params: ({ event }) => event, - }, - ], - }, - }, - }, - checkingCategoryState: { - always: [ - { - guard: { - type: 'hasCategory', - params: ({ event, context }) => { - return { - expandedCategory: context.expandedCategory, - }; - }, - }, - target: '#hasCategory.fetchingDocuments', - }, - { target: 'idle' }, - ], - }, - hasCategory: { - id: 'hasCategory', - initial: 'fetchingDocuments', - on: { - setExpandedCategory: { - target: 'checkingCategoryState', actions: [ { type: 'storeCategory', @@ -119,73 +58,13 @@ export const categoryDetailsService = setup({ ], }, }, - states: { - fetchingDocuments: { - invoke: { - src: 'getCategoryDocuments', - id: 'fetchCategoryDocumentExamples', - input: ({ context }) => ({ - ...context.parameters, - categoryTerms: context.expandedCategory!.terms, - }), - onDone: [ - { - guard: { - type: 'hasDocumentExamples', - params: ({ event }) => { - return event.output; - }, - }, - target: 'hasData', - actions: [ - { - type: 'storeDocuments', - params: ({ event }) => { - return event.output; - }, - }, - ], - }, - { - target: 'noData', - actions: [ - { - type: 'storeDocuments', - params: ({ event }) => { - return { categoryDocuments: [] }; - }, - }, - ], - }, - ], - onError: { - target: 'error', - actions: [ - { - type: 'storeError', - params: ({ event }) => ({ error: event.error }), - }, - ], - }, - }, - }, - hasData: {}, - noData: {}, - error: {}, - }, }, }, - output: ({ context }) => ({ - categoryDocuments: context.categoryDocuments, - }), + output: ({ context }) => ({}), }); export const createCategoryDetailsServiceImplementations = ({ search, }: CategoryDetailsServiceDependencies): MachineImplementationsFrom< typeof categoryDetailsService -> => ({ - actors: { - getCategoryDocuments: getCategoryDocuments({ search }), - }, -}); +> => ({}); diff --git a/x-pack/packages/observability/logs_overview/src/services/category_details_service/category_documents.ts b/x-pack/packages/observability/logs_overview/src/services/category_details_service/category_documents.ts deleted file mode 100644 index b513fa79fc686..0000000000000 --- a/x-pack/packages/observability/logs_overview/src/services/category_details_service/category_documents.ts +++ /dev/null @@ -1,63 +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 { ISearchGeneric } from '@kbn/search-types'; -import { fromPromise } from 'xstate5'; -import { lastValueFrom } from 'rxjs'; -import { flattenHit } from '@kbn/data-service'; -import { LogCategoryDocument, LogCategoryDocumentsParams } from './types'; -import { createGetLogCategoryDocumentsRequestParams } from './queries'; - -export const getCategoryDocuments = ({ search }: { search: ISearchGeneric }) => - fromPromise< - { - categoryDocuments: LogCategoryDocument[]; - }, - LogCategoryDocumentsParams - >( - async ({ - input: { - index, - endTimestamp, - startTimestamp, - timeField, - messageField, - categoryTerms, - additionalFilters = [], - dataView, - }, - signal, - }) => { - const requestParams = createGetLogCategoryDocumentsRequestParams({ - index, - timeField, - messageField, - startTimestamp, - endTimestamp, - additionalFilters, - categoryTerms, - }); - - const { rawResponse } = await lastValueFrom( - search({ params: requestParams }, { abortSignal: signal }) - ); - - const categoryDocuments: LogCategoryDocument[] = - rawResponse.hits?.hits.map((hit) => { - return { - row: { - raw: hit._source, - flattened: flattenHit(hit, dataView), - }, - }; - }) ?? []; - - return { - categoryDocuments, - }; - } - ); diff --git a/x-pack/packages/observability/logs_overview/src/services/category_details_service/queries.ts b/x-pack/packages/observability/logs_overview/src/services/category_details_service/queries.ts deleted file mode 100644 index cd1053077c334..0000000000000 --- a/x-pack/packages/observability/logs_overview/src/services/category_details_service/queries.ts +++ /dev/null @@ -1,58 +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 { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/types'; -import { createCategoryQuery } from '../categorize_logs_service/queries'; - -export const createGetLogCategoryDocumentsRequestParams = ({ - index, - timeField, - messageField, - startTimestamp, - endTimestamp, - additionalFilters = [], - categoryTerms = '', - documentCount = 20, -}: { - startTimestamp: string; - endTimestamp: string; - index: string; - timeField: string; - messageField: string; - additionalFilters?: QueryDslQueryContainer[]; - categoryTerms?: string; - documentCount?: number; -}) => { - return { - index, - size: documentCount, - track_total_hits: false, - sort: [{ [timeField]: { order: 'desc' } }], - query: { - bool: { - filter: [ - { - exists: { - field: messageField, - }, - }, - { - range: { - [timeField]: { - gte: startTimestamp, - lte: endTimestamp, - format: 'strict_date_time', - }, - }, - }, - createCategoryQuery(messageField)(categoryTerms), - ...additionalFilters, - ], - }, - }, - }; -}; diff --git a/x-pack/packages/observability/logs_overview/src/services/category_details_service/types.ts b/x-pack/packages/observability/logs_overview/src/services/category_details_service/types.ts index 72369275578e3..9c3327632055a 100644 --- a/x-pack/packages/observability/logs_overview/src/services/category_details_service/types.ts +++ b/x-pack/packages/observability/logs_overview/src/services/category_details_service/types.ts @@ -8,11 +8,6 @@ import { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/types'; import { ISearchGeneric } from '@kbn/search-types'; import { type DataView } from '@kbn/data-views-plugin/common'; -import type { DataTableRecord } from '@kbn/discover-utils'; - -export interface LogCategoryDocument { - row: Pick; -} export interface LogCategoryDetailsParams { additionalFilters: QueryDslQueryContainer[]; @@ -27,5 +22,3 @@ export interface LogCategoryDetailsParams { export interface CategoryDetailsServiceDependencies { search: ISearchGeneric; } - -export type LogCategoryDocumentsParams = LogCategoryDetailsParams & { categoryTerms: string }; diff --git a/x-pack/packages/observability/logs_overview/tsconfig.json b/x-pack/packages/observability/logs_overview/tsconfig.json index 29595ce0162fe..610ef8cc0126e 100644 --- a/x-pack/packages/observability/logs_overview/tsconfig.json +++ b/x-pack/packages/observability/logs_overview/tsconfig.json @@ -34,12 +34,9 @@ "@kbn/es-query", "@kbn/router-utils", "@kbn/share-plugin", - "@kbn/field-formats-plugin", - "@kbn/data-service", - "@kbn/discover-utils", "@kbn/discover-plugin", - "@kbn/unified-data-table", - "@kbn/discover-contextual-components", - "@kbn/core-lifecycle-browser", + "@kbn/embeddable-plugin", + "@kbn/data-plugin", + "@kbn/saved-search-component", ] } diff --git a/x-pack/packages/security-solution/distribution_bar/README.md b/x-pack/packages/security-solution/distribution_bar/README.md new file mode 100644 index 0000000000000..51edea2dd1846 --- /dev/null +++ b/x-pack/packages/security-solution/distribution_bar/README.md @@ -0,0 +1,10 @@ +# Security Solution's Distribution Bar + +The DistributionBar component visually represents data distribution, such as critical, high, medium, and low alerts. + +## Storybook + +General look of the component can be checked visually running the following storybook: +`yarn storybook security_solution_packages` + +Note that all the interactions are mocked. \ No newline at end of file diff --git a/x-pack/packages/security-solution/distribution_bar/src/distribution_bar.tsx b/x-pack/packages/security-solution/distribution_bar/src/distribution_bar.tsx index f2d1099d17c50..0942cace23267 100644 --- a/x-pack/packages/security-solution/distribution_bar/src/distribution_bar.tsx +++ b/x-pack/packages/security-solution/distribution_bar/src/distribution_bar.tsx @@ -12,7 +12,15 @@ import { css } from '@emotion/react'; /** DistributionBar component props */ export interface DistributionBarProps { /** distribution data points */ - stats: Array<{ key: string; count: number; color: string; label?: React.ReactNode }>; + stats: Array<{ + key: string; + count: number; + color: string; + label?: React.ReactNode; + isCurrentFilter?: boolean; + filter?: () => void; + reset?: (event: React.MouseEvent) => void; + }>; /** hide the label above the bar at first render */ hideLastTooltip?: boolean; /** data-test-subj used for querying the component in tests */ @@ -36,6 +44,7 @@ const useStyles = () => { position: relative; border-radius: 2px; height: 5px; + min-width: 10px; // prevents bar from shrinking too small `, empty: css` background-color: ${euiTheme.colors.lightShade}; @@ -155,7 +164,19 @@ export const DistributionBar: React.FC = React.memo(functi const prettyNumber = numeral(stat.count).format('0,0a'); return ( -
        +
        { + if (event.key === 'Enter' || event.key === ' ') { + stat.filter?.(); + } + }} + tabIndex={0} + role="button" + >
        = React.memo(functi {stat.label ? stat.label : stat.key} + {stat.isCurrentFilter ? ( + + + + ) : undefined} diff --git a/x-pack/packages/security-solution/features/src/security/kibana_features.ts b/x-pack/packages/security-solution/features/src/security/kibana_features.ts index 2fb6b11988797..458b8f6fd1f1f 100644 --- a/x-pack/packages/security-solution/features/src/security/kibana_features.ts +++ b/x-pack/packages/security-solution/features/src/security/kibana_features.ts @@ -41,6 +41,11 @@ const SECURITY_RULE_TYPES = [ NEW_TERMS_RULE_TYPE_ID, ]; +const alertingFeatures = SECURITY_RULE_TYPES.map((ruleTypeId) => ({ + ruleTypeId, + consumers: [SERVER_APP_ID], +})); + export const getSecurityBaseKibanaFeature = ({ savedObjects, }: SecurityFeatureParams): BaseKibanaFeatureConfig => ({ @@ -59,7 +64,7 @@ export const getSecurityBaseKibanaFeature = ({ management: { insightsAndAlerting: ['triggersActions'], }, - alerting: SECURITY_RULE_TYPES, + alerting: alertingFeatures, description: i18n.translate( 'securitySolutionPackages.features.featureRegistry.securityGroupDescription', { @@ -87,12 +92,8 @@ export const getSecurityBaseKibanaFeature = ({ read: [], }, alerting: { - rule: { - all: SECURITY_RULE_TYPES, - }, - alert: { - all: SECURITY_RULE_TYPES, - }, + rule: { all: alertingFeatures }, + alert: { all: alertingFeatures }, }, management: { insightsAndAlerting: ['triggersActions'], @@ -109,10 +110,10 @@ export const getSecurityBaseKibanaFeature = ({ }, alerting: { rule: { - read: SECURITY_RULE_TYPES, + read: alertingFeatures, }, alert: { - all: SECURITY_RULE_TYPES, + all: alertingFeatures, }, }, management: { diff --git a/x-pack/packages/security/authorization_core/src/actions/alerting.test.ts b/x-pack/packages/security/authorization_core/src/actions/alerting.test.ts index 1db1030da510a..8f3d48a91005c 100644 --- a/x-pack/packages/security/authorization_core/src/actions/alerting.test.ts +++ b/x-pack/packages/security/authorization_core/src/actions/alerting.test.ts @@ -51,21 +51,3 @@ describe('#get', () => { ); }); }); - -test('#isValid', () => { - const alertingActions = new AlertingActions(); - expect(alertingActions.isValid('alerting:foo-ruleType/consumer/alertingType/bar-operation')).toBe( - true - ); - - expect( - alertingActions.isValid('api:alerting:foo-ruleType/consumer/alertingType/bar-operation') - ).toBe(false); - expect(alertingActions.isValid('api:foo-ruleType/consumer/alertingType/bar-operation')).toBe( - false - ); - - expect(alertingActions.isValid('alerting_foo-ruleType/consumer/alertingType/bar-operation')).toBe( - false - ); -}); diff --git a/x-pack/packages/security/authorization_core/src/actions/alerting.ts b/x-pack/packages/security/authorization_core/src/actions/alerting.ts index 18abac73ef8b7..c1de9a1c65d21 100644 --- a/x-pack/packages/security/authorization_core/src/actions/alerting.ts +++ b/x-pack/packages/security/authorization_core/src/actions/alerting.ts @@ -40,12 +40,4 @@ export class AlertingActions implements AlertingActionsType { return `${this.prefix}${ruleTypeId}/${consumer}/${alertingEntity}/${operation}`; } - - /** - * Checks if the action is a valid alerting action. - * @param action The action string to check. - */ - public isValid(action: string) { - return action.startsWith(this.prefix); - } } diff --git a/x-pack/packages/security/authorization_core/src/privileges/feature_privilege_builder/alerting.test.ts b/x-pack/packages/security/authorization_core/src/privileges/feature_privilege_builder/alerting.test.ts index db4aae642a56f..c5af930cce4f5 100644 --- a/x-pack/packages/security/authorization_core/src/privileges/feature_privilege_builder/alerting.test.ts +++ b/x-pack/packages/security/authorization_core/src/privileges/feature_privilege_builder/alerting.test.ts @@ -28,7 +28,6 @@ describe(`feature_privilege_builder`, () => { read: [], }, }, - savedObject: { all: [], read: [], @@ -59,10 +58,9 @@ describe(`feature_privilege_builder`, () => { alerting: { rule: { all: [], - read: ['alert-type'], + read: [{ ruleTypeId: 'alert-type', consumers: ['my-consumer'] }], }, }, - savedObject: { all: [], read: [], @@ -83,15 +81,15 @@ describe(`feature_privilege_builder`, () => { expect(alertingFeaturePrivileges.getActions(privilege, feature)).toMatchInlineSnapshot(` Array [ - "alerting:alert-type/my-feature/rule/get", - "alerting:alert-type/my-feature/rule/getRuleState", - "alerting:alert-type/my-feature/rule/getAlertSummary", - "alerting:alert-type/my-feature/rule/getExecutionLog", - "alerting:alert-type/my-feature/rule/getActionErrorLog", - "alerting:alert-type/my-feature/rule/find", - "alerting:alert-type/my-feature/rule/getRuleExecutionKPI", - "alerting:alert-type/my-feature/rule/getBackfill", - "alerting:alert-type/my-feature/rule/findBackfill", + "alerting:alert-type/my-consumer/rule/get", + "alerting:alert-type/my-consumer/rule/getRuleState", + "alerting:alert-type/my-consumer/rule/getAlertSummary", + "alerting:alert-type/my-consumer/rule/getExecutionLog", + "alerting:alert-type/my-consumer/rule/getActionErrorLog", + "alerting:alert-type/my-consumer/rule/find", + "alerting:alert-type/my-consumer/rule/getRuleExecutionKPI", + "alerting:alert-type/my-consumer/rule/getBackfill", + "alerting:alert-type/my-consumer/rule/findBackfill", ] `); }); @@ -104,10 +102,9 @@ describe(`feature_privilege_builder`, () => { alerting: { alert: { all: [], - read: ['alert-type'], + read: [{ ruleTypeId: 'alert-type', consumers: ['my-consumer'] }], }, }, - savedObject: { all: [], read: [], @@ -128,10 +125,10 @@ describe(`feature_privilege_builder`, () => { expect(alertingFeaturePrivileges.getActions(privilege, feature)).toMatchInlineSnapshot(` Array [ - "alerting:alert-type/my-feature/alert/get", - "alerting:alert-type/my-feature/alert/find", - "alerting:alert-type/my-feature/alert/getAuthorizedAlertsIndices", - "alerting:alert-type/my-feature/alert/getAlertSummary", + "alerting:alert-type/my-consumer/alert/get", + "alerting:alert-type/my-consumer/alert/find", + "alerting:alert-type/my-consumer/alert/getAuthorizedAlertsIndices", + "alerting:alert-type/my-consumer/alert/getAlertSummary", ] `); }); @@ -144,14 +141,13 @@ describe(`feature_privilege_builder`, () => { alerting: { rule: { all: [], - read: ['alert-type'], + read: [{ ruleTypeId: 'alert-type', consumers: ['my-consumer'] }], }, alert: { all: [], - read: ['alert-type'], + read: [{ ruleTypeId: 'alert-type', consumers: ['my-consumer'] }], }, }, - savedObject: { all: [], read: [], @@ -172,19 +168,19 @@ describe(`feature_privilege_builder`, () => { expect(alertingFeaturePrivileges.getActions(privilege, feature)).toMatchInlineSnapshot(` Array [ - "alerting:alert-type/my-feature/rule/get", - "alerting:alert-type/my-feature/rule/getRuleState", - "alerting:alert-type/my-feature/rule/getAlertSummary", - "alerting:alert-type/my-feature/rule/getExecutionLog", - "alerting:alert-type/my-feature/rule/getActionErrorLog", - "alerting:alert-type/my-feature/rule/find", - "alerting:alert-type/my-feature/rule/getRuleExecutionKPI", - "alerting:alert-type/my-feature/rule/getBackfill", - "alerting:alert-type/my-feature/rule/findBackfill", - "alerting:alert-type/my-feature/alert/get", - "alerting:alert-type/my-feature/alert/find", - "alerting:alert-type/my-feature/alert/getAuthorizedAlertsIndices", - "alerting:alert-type/my-feature/alert/getAlertSummary", + "alerting:alert-type/my-consumer/rule/get", + "alerting:alert-type/my-consumer/rule/getRuleState", + "alerting:alert-type/my-consumer/rule/getAlertSummary", + "alerting:alert-type/my-consumer/rule/getExecutionLog", + "alerting:alert-type/my-consumer/rule/getActionErrorLog", + "alerting:alert-type/my-consumer/rule/find", + "alerting:alert-type/my-consumer/rule/getRuleExecutionKPI", + "alerting:alert-type/my-consumer/rule/getBackfill", + "alerting:alert-type/my-consumer/rule/findBackfill", + "alerting:alert-type/my-consumer/alert/get", + "alerting:alert-type/my-consumer/alert/find", + "alerting:alert-type/my-consumer/alert/getAuthorizedAlertsIndices", + "alerting:alert-type/my-consumer/alert/getAlertSummary", ] `); }); @@ -196,7 +192,7 @@ describe(`feature_privilege_builder`, () => { const privilege: FeatureKibanaPrivileges = { alerting: { rule: { - all: ['alert-type'], + all: [{ ruleTypeId: 'alert-type', consumers: ['my-consumer'] }], read: [], }, }, @@ -221,34 +217,34 @@ describe(`feature_privilege_builder`, () => { expect(alertingFeaturePrivileges.getActions(privilege, feature)).toMatchInlineSnapshot(` Array [ - "alerting:alert-type/my-feature/rule/get", - "alerting:alert-type/my-feature/rule/getRuleState", - "alerting:alert-type/my-feature/rule/getAlertSummary", - "alerting:alert-type/my-feature/rule/getExecutionLog", - "alerting:alert-type/my-feature/rule/getActionErrorLog", - "alerting:alert-type/my-feature/rule/find", - "alerting:alert-type/my-feature/rule/getRuleExecutionKPI", - "alerting:alert-type/my-feature/rule/getBackfill", - "alerting:alert-type/my-feature/rule/findBackfill", - "alerting:alert-type/my-feature/rule/create", - "alerting:alert-type/my-feature/rule/delete", - "alerting:alert-type/my-feature/rule/update", - "alerting:alert-type/my-feature/rule/updateApiKey", - "alerting:alert-type/my-feature/rule/enable", - "alerting:alert-type/my-feature/rule/disable", - "alerting:alert-type/my-feature/rule/muteAll", - "alerting:alert-type/my-feature/rule/unmuteAll", - "alerting:alert-type/my-feature/rule/muteAlert", - "alerting:alert-type/my-feature/rule/unmuteAlert", - "alerting:alert-type/my-feature/rule/snooze", - "alerting:alert-type/my-feature/rule/bulkEdit", - "alerting:alert-type/my-feature/rule/bulkDelete", - "alerting:alert-type/my-feature/rule/bulkEnable", - "alerting:alert-type/my-feature/rule/bulkDisable", - "alerting:alert-type/my-feature/rule/unsnooze", - "alerting:alert-type/my-feature/rule/runSoon", - "alerting:alert-type/my-feature/rule/scheduleBackfill", - "alerting:alert-type/my-feature/rule/deleteBackfill", + "alerting:alert-type/my-consumer/rule/get", + "alerting:alert-type/my-consumer/rule/getRuleState", + "alerting:alert-type/my-consumer/rule/getAlertSummary", + "alerting:alert-type/my-consumer/rule/getExecutionLog", + "alerting:alert-type/my-consumer/rule/getActionErrorLog", + "alerting:alert-type/my-consumer/rule/find", + "alerting:alert-type/my-consumer/rule/getRuleExecutionKPI", + "alerting:alert-type/my-consumer/rule/getBackfill", + "alerting:alert-type/my-consumer/rule/findBackfill", + "alerting:alert-type/my-consumer/rule/create", + "alerting:alert-type/my-consumer/rule/delete", + "alerting:alert-type/my-consumer/rule/update", + "alerting:alert-type/my-consumer/rule/updateApiKey", + "alerting:alert-type/my-consumer/rule/enable", + "alerting:alert-type/my-consumer/rule/disable", + "alerting:alert-type/my-consumer/rule/muteAll", + "alerting:alert-type/my-consumer/rule/unmuteAll", + "alerting:alert-type/my-consumer/rule/muteAlert", + "alerting:alert-type/my-consumer/rule/unmuteAlert", + "alerting:alert-type/my-consumer/rule/snooze", + "alerting:alert-type/my-consumer/rule/bulkEdit", + "alerting:alert-type/my-consumer/rule/bulkDelete", + "alerting:alert-type/my-consumer/rule/bulkEnable", + "alerting:alert-type/my-consumer/rule/bulkDisable", + "alerting:alert-type/my-consumer/rule/unsnooze", + "alerting:alert-type/my-consumer/rule/runSoon", + "alerting:alert-type/my-consumer/rule/scheduleBackfill", + "alerting:alert-type/my-consumer/rule/deleteBackfill", ] `); }); @@ -260,11 +256,10 @@ describe(`feature_privilege_builder`, () => { const privilege: FeatureKibanaPrivileges = { alerting: { alert: { - all: ['alert-type'], + all: [{ ruleTypeId: 'alert-type', consumers: ['my-consumer'] }], read: [], }, }, - savedObject: { all: [], read: [], @@ -285,11 +280,11 @@ describe(`feature_privilege_builder`, () => { expect(alertingFeaturePrivileges.getActions(privilege, feature)).toMatchInlineSnapshot(` Array [ - "alerting:alert-type/my-feature/alert/get", - "alerting:alert-type/my-feature/alert/find", - "alerting:alert-type/my-feature/alert/getAuthorizedAlertsIndices", - "alerting:alert-type/my-feature/alert/getAlertSummary", - "alerting:alert-type/my-feature/alert/update", + "alerting:alert-type/my-consumer/alert/get", + "alerting:alert-type/my-consumer/alert/find", + "alerting:alert-type/my-consumer/alert/getAuthorizedAlertsIndices", + "alerting:alert-type/my-consumer/alert/getAlertSummary", + "alerting:alert-type/my-consumer/alert/update", ] `); }); @@ -301,15 +296,14 @@ describe(`feature_privilege_builder`, () => { const privilege: FeatureKibanaPrivileges = { alerting: { rule: { - all: ['alert-type'], + all: [{ ruleTypeId: 'alert-type', consumers: ['my-consumer'] }], read: [], }, alert: { - all: ['alert-type'], + all: [{ ruleTypeId: 'alert-type', consumers: ['my-consumer'] }], read: [], }, }, - savedObject: { all: [], read: [], @@ -330,39 +324,39 @@ describe(`feature_privilege_builder`, () => { expect(alertingFeaturePrivileges.getActions(privilege, feature)).toMatchInlineSnapshot(` Array [ - "alerting:alert-type/my-feature/rule/get", - "alerting:alert-type/my-feature/rule/getRuleState", - "alerting:alert-type/my-feature/rule/getAlertSummary", - "alerting:alert-type/my-feature/rule/getExecutionLog", - "alerting:alert-type/my-feature/rule/getActionErrorLog", - "alerting:alert-type/my-feature/rule/find", - "alerting:alert-type/my-feature/rule/getRuleExecutionKPI", - "alerting:alert-type/my-feature/rule/getBackfill", - "alerting:alert-type/my-feature/rule/findBackfill", - "alerting:alert-type/my-feature/rule/create", - "alerting:alert-type/my-feature/rule/delete", - "alerting:alert-type/my-feature/rule/update", - "alerting:alert-type/my-feature/rule/updateApiKey", - "alerting:alert-type/my-feature/rule/enable", - "alerting:alert-type/my-feature/rule/disable", - "alerting:alert-type/my-feature/rule/muteAll", - "alerting:alert-type/my-feature/rule/unmuteAll", - "alerting:alert-type/my-feature/rule/muteAlert", - "alerting:alert-type/my-feature/rule/unmuteAlert", - "alerting:alert-type/my-feature/rule/snooze", - "alerting:alert-type/my-feature/rule/bulkEdit", - "alerting:alert-type/my-feature/rule/bulkDelete", - "alerting:alert-type/my-feature/rule/bulkEnable", - "alerting:alert-type/my-feature/rule/bulkDisable", - "alerting:alert-type/my-feature/rule/unsnooze", - "alerting:alert-type/my-feature/rule/runSoon", - "alerting:alert-type/my-feature/rule/scheduleBackfill", - "alerting:alert-type/my-feature/rule/deleteBackfill", - "alerting:alert-type/my-feature/alert/get", - "alerting:alert-type/my-feature/alert/find", - "alerting:alert-type/my-feature/alert/getAuthorizedAlertsIndices", - "alerting:alert-type/my-feature/alert/getAlertSummary", - "alerting:alert-type/my-feature/alert/update", + "alerting:alert-type/my-consumer/rule/get", + "alerting:alert-type/my-consumer/rule/getRuleState", + "alerting:alert-type/my-consumer/rule/getAlertSummary", + "alerting:alert-type/my-consumer/rule/getExecutionLog", + "alerting:alert-type/my-consumer/rule/getActionErrorLog", + "alerting:alert-type/my-consumer/rule/find", + "alerting:alert-type/my-consumer/rule/getRuleExecutionKPI", + "alerting:alert-type/my-consumer/rule/getBackfill", + "alerting:alert-type/my-consumer/rule/findBackfill", + "alerting:alert-type/my-consumer/rule/create", + "alerting:alert-type/my-consumer/rule/delete", + "alerting:alert-type/my-consumer/rule/update", + "alerting:alert-type/my-consumer/rule/updateApiKey", + "alerting:alert-type/my-consumer/rule/enable", + "alerting:alert-type/my-consumer/rule/disable", + "alerting:alert-type/my-consumer/rule/muteAll", + "alerting:alert-type/my-consumer/rule/unmuteAll", + "alerting:alert-type/my-consumer/rule/muteAlert", + "alerting:alert-type/my-consumer/rule/unmuteAlert", + "alerting:alert-type/my-consumer/rule/snooze", + "alerting:alert-type/my-consumer/rule/bulkEdit", + "alerting:alert-type/my-consumer/rule/bulkDelete", + "alerting:alert-type/my-consumer/rule/bulkEnable", + "alerting:alert-type/my-consumer/rule/bulkDisable", + "alerting:alert-type/my-consumer/rule/unsnooze", + "alerting:alert-type/my-consumer/rule/runSoon", + "alerting:alert-type/my-consumer/rule/scheduleBackfill", + "alerting:alert-type/my-consumer/rule/deleteBackfill", + "alerting:alert-type/my-consumer/alert/get", + "alerting:alert-type/my-consumer/alert/find", + "alerting:alert-type/my-consumer/alert/getAuthorizedAlertsIndices", + "alerting:alert-type/my-consumer/alert/getAlertSummary", + "alerting:alert-type/my-consumer/alert/update", ] `); }); @@ -374,11 +368,10 @@ describe(`feature_privilege_builder`, () => { const privilege: FeatureKibanaPrivileges = { alerting: { rule: { - all: ['alert-type'], - read: ['readonly-alert-type'], + all: [{ ruleTypeId: 'alert-type', consumers: ['my-consumer'] }], + read: [{ ruleTypeId: 'readonly-alert-type', consumers: ['my-consumer'] }], }, }, - savedObject: { all: [], read: [], @@ -399,43 +392,43 @@ describe(`feature_privilege_builder`, () => { expect(alertingFeaturePrivileges.getActions(privilege, feature)).toMatchInlineSnapshot(` Array [ - "alerting:alert-type/my-feature/rule/get", - "alerting:alert-type/my-feature/rule/getRuleState", - "alerting:alert-type/my-feature/rule/getAlertSummary", - "alerting:alert-type/my-feature/rule/getExecutionLog", - "alerting:alert-type/my-feature/rule/getActionErrorLog", - "alerting:alert-type/my-feature/rule/find", - "alerting:alert-type/my-feature/rule/getRuleExecutionKPI", - "alerting:alert-type/my-feature/rule/getBackfill", - "alerting:alert-type/my-feature/rule/findBackfill", - "alerting:alert-type/my-feature/rule/create", - "alerting:alert-type/my-feature/rule/delete", - "alerting:alert-type/my-feature/rule/update", - "alerting:alert-type/my-feature/rule/updateApiKey", - "alerting:alert-type/my-feature/rule/enable", - "alerting:alert-type/my-feature/rule/disable", - "alerting:alert-type/my-feature/rule/muteAll", - "alerting:alert-type/my-feature/rule/unmuteAll", - "alerting:alert-type/my-feature/rule/muteAlert", - "alerting:alert-type/my-feature/rule/unmuteAlert", - "alerting:alert-type/my-feature/rule/snooze", - "alerting:alert-type/my-feature/rule/bulkEdit", - "alerting:alert-type/my-feature/rule/bulkDelete", - "alerting:alert-type/my-feature/rule/bulkEnable", - "alerting:alert-type/my-feature/rule/bulkDisable", - "alerting:alert-type/my-feature/rule/unsnooze", - "alerting:alert-type/my-feature/rule/runSoon", - "alerting:alert-type/my-feature/rule/scheduleBackfill", - "alerting:alert-type/my-feature/rule/deleteBackfill", - "alerting:readonly-alert-type/my-feature/rule/get", - "alerting:readonly-alert-type/my-feature/rule/getRuleState", - "alerting:readonly-alert-type/my-feature/rule/getAlertSummary", - "alerting:readonly-alert-type/my-feature/rule/getExecutionLog", - "alerting:readonly-alert-type/my-feature/rule/getActionErrorLog", - "alerting:readonly-alert-type/my-feature/rule/find", - "alerting:readonly-alert-type/my-feature/rule/getRuleExecutionKPI", - "alerting:readonly-alert-type/my-feature/rule/getBackfill", - "alerting:readonly-alert-type/my-feature/rule/findBackfill", + "alerting:alert-type/my-consumer/rule/get", + "alerting:alert-type/my-consumer/rule/getRuleState", + "alerting:alert-type/my-consumer/rule/getAlertSummary", + "alerting:alert-type/my-consumer/rule/getExecutionLog", + "alerting:alert-type/my-consumer/rule/getActionErrorLog", + "alerting:alert-type/my-consumer/rule/find", + "alerting:alert-type/my-consumer/rule/getRuleExecutionKPI", + "alerting:alert-type/my-consumer/rule/getBackfill", + "alerting:alert-type/my-consumer/rule/findBackfill", + "alerting:alert-type/my-consumer/rule/create", + "alerting:alert-type/my-consumer/rule/delete", + "alerting:alert-type/my-consumer/rule/update", + "alerting:alert-type/my-consumer/rule/updateApiKey", + "alerting:alert-type/my-consumer/rule/enable", + "alerting:alert-type/my-consumer/rule/disable", + "alerting:alert-type/my-consumer/rule/muteAll", + "alerting:alert-type/my-consumer/rule/unmuteAll", + "alerting:alert-type/my-consumer/rule/muteAlert", + "alerting:alert-type/my-consumer/rule/unmuteAlert", + "alerting:alert-type/my-consumer/rule/snooze", + "alerting:alert-type/my-consumer/rule/bulkEdit", + "alerting:alert-type/my-consumer/rule/bulkDelete", + "alerting:alert-type/my-consumer/rule/bulkEnable", + "alerting:alert-type/my-consumer/rule/bulkDisable", + "alerting:alert-type/my-consumer/rule/unsnooze", + "alerting:alert-type/my-consumer/rule/runSoon", + "alerting:alert-type/my-consumer/rule/scheduleBackfill", + "alerting:alert-type/my-consumer/rule/deleteBackfill", + "alerting:readonly-alert-type/my-consumer/rule/get", + "alerting:readonly-alert-type/my-consumer/rule/getRuleState", + "alerting:readonly-alert-type/my-consumer/rule/getAlertSummary", + "alerting:readonly-alert-type/my-consumer/rule/getExecutionLog", + "alerting:readonly-alert-type/my-consumer/rule/getActionErrorLog", + "alerting:readonly-alert-type/my-consumer/rule/find", + "alerting:readonly-alert-type/my-consumer/rule/getRuleExecutionKPI", + "alerting:readonly-alert-type/my-consumer/rule/getBackfill", + "alerting:readonly-alert-type/my-consumer/rule/findBackfill", ] `); }); @@ -447,8 +440,8 @@ describe(`feature_privilege_builder`, () => { const privilege: FeatureKibanaPrivileges = { alerting: { alert: { - all: ['alert-type'], - read: ['readonly-alert-type'], + all: [{ ruleTypeId: 'alert-type', consumers: ['my-consumer'] }], + read: [{ ruleTypeId: 'readonly-alert-type', consumers: ['my-consumer'] }], }, }, @@ -472,15 +465,15 @@ describe(`feature_privilege_builder`, () => { expect(alertingFeaturePrivileges.getActions(privilege, feature)).toMatchInlineSnapshot(` Array [ - "alerting:alert-type/my-feature/alert/get", - "alerting:alert-type/my-feature/alert/find", - "alerting:alert-type/my-feature/alert/getAuthorizedAlertsIndices", - "alerting:alert-type/my-feature/alert/getAlertSummary", - "alerting:alert-type/my-feature/alert/update", - "alerting:readonly-alert-type/my-feature/alert/get", - "alerting:readonly-alert-type/my-feature/alert/find", - "alerting:readonly-alert-type/my-feature/alert/getAuthorizedAlertsIndices", - "alerting:readonly-alert-type/my-feature/alert/getAlertSummary", + "alerting:alert-type/my-consumer/alert/get", + "alerting:alert-type/my-consumer/alert/find", + "alerting:alert-type/my-consumer/alert/getAuthorizedAlertsIndices", + "alerting:alert-type/my-consumer/alert/getAlertSummary", + "alerting:alert-type/my-consumer/alert/update", + "alerting:readonly-alert-type/my-consumer/alert/get", + "alerting:readonly-alert-type/my-consumer/alert/find", + "alerting:readonly-alert-type/my-consumer/alert/getAuthorizedAlertsIndices", + "alerting:readonly-alert-type/my-consumer/alert/getAlertSummary", ] `); }); @@ -492,12 +485,128 @@ describe(`feature_privilege_builder`, () => { const privilege: FeatureKibanaPrivileges = { alerting: { rule: { - all: ['alert-type'], - read: ['readonly-alert-type'], + all: [{ ruleTypeId: 'alert-type', consumers: ['my-consumer'] }], + read: [{ ruleTypeId: 'readonly-alert-type', consumers: ['my-consumer'] }], + }, + alert: { + all: [{ ruleTypeId: 'another-alert-type', consumers: ['my-consumer'] }], + read: [{ ruleTypeId: 'readonly-alert-type', consumers: ['my-consumer'] }], + }, + }, + + savedObject: { + all: [], + read: [], + }, + ui: [], + }; + + const feature = new KibanaFeature({ + id: 'my-feature', + name: 'my-feature', + app: [], + category: { id: 'foo', label: 'foo' }, + privileges: { + all: privilege, + read: privilege, + }, + }); + + expect(alertingFeaturePrivileges.getActions(privilege, feature)).toMatchInlineSnapshot(` + Array [ + "alerting:alert-type/my-consumer/rule/get", + "alerting:alert-type/my-consumer/rule/getRuleState", + "alerting:alert-type/my-consumer/rule/getAlertSummary", + "alerting:alert-type/my-consumer/rule/getExecutionLog", + "alerting:alert-type/my-consumer/rule/getActionErrorLog", + "alerting:alert-type/my-consumer/rule/find", + "alerting:alert-type/my-consumer/rule/getRuleExecutionKPI", + "alerting:alert-type/my-consumer/rule/getBackfill", + "alerting:alert-type/my-consumer/rule/findBackfill", + "alerting:alert-type/my-consumer/rule/create", + "alerting:alert-type/my-consumer/rule/delete", + "alerting:alert-type/my-consumer/rule/update", + "alerting:alert-type/my-consumer/rule/updateApiKey", + "alerting:alert-type/my-consumer/rule/enable", + "alerting:alert-type/my-consumer/rule/disable", + "alerting:alert-type/my-consumer/rule/muteAll", + "alerting:alert-type/my-consumer/rule/unmuteAll", + "alerting:alert-type/my-consumer/rule/muteAlert", + "alerting:alert-type/my-consumer/rule/unmuteAlert", + "alerting:alert-type/my-consumer/rule/snooze", + "alerting:alert-type/my-consumer/rule/bulkEdit", + "alerting:alert-type/my-consumer/rule/bulkDelete", + "alerting:alert-type/my-consumer/rule/bulkEnable", + "alerting:alert-type/my-consumer/rule/bulkDisable", + "alerting:alert-type/my-consumer/rule/unsnooze", + "alerting:alert-type/my-consumer/rule/runSoon", + "alerting:alert-type/my-consumer/rule/scheduleBackfill", + "alerting:alert-type/my-consumer/rule/deleteBackfill", + "alerting:readonly-alert-type/my-consumer/rule/get", + "alerting:readonly-alert-type/my-consumer/rule/getRuleState", + "alerting:readonly-alert-type/my-consumer/rule/getAlertSummary", + "alerting:readonly-alert-type/my-consumer/rule/getExecutionLog", + "alerting:readonly-alert-type/my-consumer/rule/getActionErrorLog", + "alerting:readonly-alert-type/my-consumer/rule/find", + "alerting:readonly-alert-type/my-consumer/rule/getRuleExecutionKPI", + "alerting:readonly-alert-type/my-consumer/rule/getBackfill", + "alerting:readonly-alert-type/my-consumer/rule/findBackfill", + "alerting:another-alert-type/my-consumer/alert/get", + "alerting:another-alert-type/my-consumer/alert/find", + "alerting:another-alert-type/my-consumer/alert/getAuthorizedAlertsIndices", + "alerting:another-alert-type/my-consumer/alert/getAlertSummary", + "alerting:another-alert-type/my-consumer/alert/update", + "alerting:readonly-alert-type/my-consumer/alert/get", + "alerting:readonly-alert-type/my-consumer/alert/find", + "alerting:readonly-alert-type/my-consumer/alert/getAuthorizedAlertsIndices", + "alerting:readonly-alert-type/my-consumer/alert/getAlertSummary", + ] + `); + }); + + test('handles multiple rule types and consumers correctly', () => { + const actions = new Actions(); + const alertingFeaturePrivileges = new FeaturePrivilegeAlertingBuilder(actions); + + const privilege: FeatureKibanaPrivileges = { + alerting: { + rule: { + all: [ + { ruleTypeId: 'alert-type-1', consumers: ['my-consumer-1', 'my-consumer-2'] }, + { ruleTypeId: 'alert-type-2', consumers: ['my-consumer-3'] }, + ], + read: [ + { + ruleTypeId: 'readonly-alert-type-1', + consumers: ['my-read-consumer-1', 'my-read-consumer-2'], + }, + { + ruleTypeId: 'readonly-alert-type-2', + consumers: ['my-read-consumer-3', 'my-read-consumer-4'], + }, + ], }, alert: { - all: ['another-alert-type'], - read: ['readonly-alert-type'], + all: [ + { + ruleTypeId: 'another-alert-type-1', + consumers: ['my-consumer-another-1', 'my-consumer-another-2'], + }, + { + ruleTypeId: 'another-alert-type-2', + consumers: ['my-consumer-another-3', 'my-consumer-another-1'], + }, + ], + read: [ + { + ruleTypeId: 'readonly-another-alert-type-1', + consumers: ['my-read-other-consumer-1', 'my-read-other-consumer-2'], + }, + { + ruleTypeId: 'readonly-another-alert-type-2', + consumers: ['my-read-other-consumer-3', 'my-read-other-consumer-4'], + }, + ], }, }, @@ -521,52 +630,162 @@ describe(`feature_privilege_builder`, () => { expect(alertingFeaturePrivileges.getActions(privilege, feature)).toMatchInlineSnapshot(` Array [ - "alerting:alert-type/my-feature/rule/get", - "alerting:alert-type/my-feature/rule/getRuleState", - "alerting:alert-type/my-feature/rule/getAlertSummary", - "alerting:alert-type/my-feature/rule/getExecutionLog", - "alerting:alert-type/my-feature/rule/getActionErrorLog", - "alerting:alert-type/my-feature/rule/find", - "alerting:alert-type/my-feature/rule/getRuleExecutionKPI", - "alerting:alert-type/my-feature/rule/getBackfill", - "alerting:alert-type/my-feature/rule/findBackfill", - "alerting:alert-type/my-feature/rule/create", - "alerting:alert-type/my-feature/rule/delete", - "alerting:alert-type/my-feature/rule/update", - "alerting:alert-type/my-feature/rule/updateApiKey", - "alerting:alert-type/my-feature/rule/enable", - "alerting:alert-type/my-feature/rule/disable", - "alerting:alert-type/my-feature/rule/muteAll", - "alerting:alert-type/my-feature/rule/unmuteAll", - "alerting:alert-type/my-feature/rule/muteAlert", - "alerting:alert-type/my-feature/rule/unmuteAlert", - "alerting:alert-type/my-feature/rule/snooze", - "alerting:alert-type/my-feature/rule/bulkEdit", - "alerting:alert-type/my-feature/rule/bulkDelete", - "alerting:alert-type/my-feature/rule/bulkEnable", - "alerting:alert-type/my-feature/rule/bulkDisable", - "alerting:alert-type/my-feature/rule/unsnooze", - "alerting:alert-type/my-feature/rule/runSoon", - "alerting:alert-type/my-feature/rule/scheduleBackfill", - "alerting:alert-type/my-feature/rule/deleteBackfill", - "alerting:readonly-alert-type/my-feature/rule/get", - "alerting:readonly-alert-type/my-feature/rule/getRuleState", - "alerting:readonly-alert-type/my-feature/rule/getAlertSummary", - "alerting:readonly-alert-type/my-feature/rule/getExecutionLog", - "alerting:readonly-alert-type/my-feature/rule/getActionErrorLog", - "alerting:readonly-alert-type/my-feature/rule/find", - "alerting:readonly-alert-type/my-feature/rule/getRuleExecutionKPI", - "alerting:readonly-alert-type/my-feature/rule/getBackfill", - "alerting:readonly-alert-type/my-feature/rule/findBackfill", - "alerting:another-alert-type/my-feature/alert/get", - "alerting:another-alert-type/my-feature/alert/find", - "alerting:another-alert-type/my-feature/alert/getAuthorizedAlertsIndices", - "alerting:another-alert-type/my-feature/alert/getAlertSummary", - "alerting:another-alert-type/my-feature/alert/update", - "alerting:readonly-alert-type/my-feature/alert/get", - "alerting:readonly-alert-type/my-feature/alert/find", - "alerting:readonly-alert-type/my-feature/alert/getAuthorizedAlertsIndices", - "alerting:readonly-alert-type/my-feature/alert/getAlertSummary", + "alerting:alert-type-1/my-consumer-1/rule/get", + "alerting:alert-type-1/my-consumer-1/rule/getRuleState", + "alerting:alert-type-1/my-consumer-1/rule/getAlertSummary", + "alerting:alert-type-1/my-consumer-1/rule/getExecutionLog", + "alerting:alert-type-1/my-consumer-1/rule/getActionErrorLog", + "alerting:alert-type-1/my-consumer-1/rule/find", + "alerting:alert-type-1/my-consumer-1/rule/getRuleExecutionKPI", + "alerting:alert-type-1/my-consumer-1/rule/getBackfill", + "alerting:alert-type-1/my-consumer-1/rule/findBackfill", + "alerting:alert-type-1/my-consumer-1/rule/create", + "alerting:alert-type-1/my-consumer-1/rule/delete", + "alerting:alert-type-1/my-consumer-1/rule/update", + "alerting:alert-type-1/my-consumer-1/rule/updateApiKey", + "alerting:alert-type-1/my-consumer-1/rule/enable", + "alerting:alert-type-1/my-consumer-1/rule/disable", + "alerting:alert-type-1/my-consumer-1/rule/muteAll", + "alerting:alert-type-1/my-consumer-1/rule/unmuteAll", + "alerting:alert-type-1/my-consumer-1/rule/muteAlert", + "alerting:alert-type-1/my-consumer-1/rule/unmuteAlert", + "alerting:alert-type-1/my-consumer-1/rule/snooze", + "alerting:alert-type-1/my-consumer-1/rule/bulkEdit", + "alerting:alert-type-1/my-consumer-1/rule/bulkDelete", + "alerting:alert-type-1/my-consumer-1/rule/bulkEnable", + "alerting:alert-type-1/my-consumer-1/rule/bulkDisable", + "alerting:alert-type-1/my-consumer-1/rule/unsnooze", + "alerting:alert-type-1/my-consumer-1/rule/runSoon", + "alerting:alert-type-1/my-consumer-1/rule/scheduleBackfill", + "alerting:alert-type-1/my-consumer-1/rule/deleteBackfill", + "alerting:alert-type-1/my-consumer-2/rule/get", + "alerting:alert-type-1/my-consumer-2/rule/getRuleState", + "alerting:alert-type-1/my-consumer-2/rule/getAlertSummary", + "alerting:alert-type-1/my-consumer-2/rule/getExecutionLog", + "alerting:alert-type-1/my-consumer-2/rule/getActionErrorLog", + "alerting:alert-type-1/my-consumer-2/rule/find", + "alerting:alert-type-1/my-consumer-2/rule/getRuleExecutionKPI", + "alerting:alert-type-1/my-consumer-2/rule/getBackfill", + "alerting:alert-type-1/my-consumer-2/rule/findBackfill", + "alerting:alert-type-1/my-consumer-2/rule/create", + "alerting:alert-type-1/my-consumer-2/rule/delete", + "alerting:alert-type-1/my-consumer-2/rule/update", + "alerting:alert-type-1/my-consumer-2/rule/updateApiKey", + "alerting:alert-type-1/my-consumer-2/rule/enable", + "alerting:alert-type-1/my-consumer-2/rule/disable", + "alerting:alert-type-1/my-consumer-2/rule/muteAll", + "alerting:alert-type-1/my-consumer-2/rule/unmuteAll", + "alerting:alert-type-1/my-consumer-2/rule/muteAlert", + "alerting:alert-type-1/my-consumer-2/rule/unmuteAlert", + "alerting:alert-type-1/my-consumer-2/rule/snooze", + "alerting:alert-type-1/my-consumer-2/rule/bulkEdit", + "alerting:alert-type-1/my-consumer-2/rule/bulkDelete", + "alerting:alert-type-1/my-consumer-2/rule/bulkEnable", + "alerting:alert-type-1/my-consumer-2/rule/bulkDisable", + "alerting:alert-type-1/my-consumer-2/rule/unsnooze", + "alerting:alert-type-1/my-consumer-2/rule/runSoon", + "alerting:alert-type-1/my-consumer-2/rule/scheduleBackfill", + "alerting:alert-type-1/my-consumer-2/rule/deleteBackfill", + "alerting:alert-type-2/my-consumer-3/rule/get", + "alerting:alert-type-2/my-consumer-3/rule/getRuleState", + "alerting:alert-type-2/my-consumer-3/rule/getAlertSummary", + "alerting:alert-type-2/my-consumer-3/rule/getExecutionLog", + "alerting:alert-type-2/my-consumer-3/rule/getActionErrorLog", + "alerting:alert-type-2/my-consumer-3/rule/find", + "alerting:alert-type-2/my-consumer-3/rule/getRuleExecutionKPI", + "alerting:alert-type-2/my-consumer-3/rule/getBackfill", + "alerting:alert-type-2/my-consumer-3/rule/findBackfill", + "alerting:alert-type-2/my-consumer-3/rule/create", + "alerting:alert-type-2/my-consumer-3/rule/delete", + "alerting:alert-type-2/my-consumer-3/rule/update", + "alerting:alert-type-2/my-consumer-3/rule/updateApiKey", + "alerting:alert-type-2/my-consumer-3/rule/enable", + "alerting:alert-type-2/my-consumer-3/rule/disable", + "alerting:alert-type-2/my-consumer-3/rule/muteAll", + "alerting:alert-type-2/my-consumer-3/rule/unmuteAll", + "alerting:alert-type-2/my-consumer-3/rule/muteAlert", + "alerting:alert-type-2/my-consumer-3/rule/unmuteAlert", + "alerting:alert-type-2/my-consumer-3/rule/snooze", + "alerting:alert-type-2/my-consumer-3/rule/bulkEdit", + "alerting:alert-type-2/my-consumer-3/rule/bulkDelete", + "alerting:alert-type-2/my-consumer-3/rule/bulkEnable", + "alerting:alert-type-2/my-consumer-3/rule/bulkDisable", + "alerting:alert-type-2/my-consumer-3/rule/unsnooze", + "alerting:alert-type-2/my-consumer-3/rule/runSoon", + "alerting:alert-type-2/my-consumer-3/rule/scheduleBackfill", + "alerting:alert-type-2/my-consumer-3/rule/deleteBackfill", + "alerting:readonly-alert-type-1/my-read-consumer-1/rule/get", + "alerting:readonly-alert-type-1/my-read-consumer-1/rule/getRuleState", + "alerting:readonly-alert-type-1/my-read-consumer-1/rule/getAlertSummary", + "alerting:readonly-alert-type-1/my-read-consumer-1/rule/getExecutionLog", + "alerting:readonly-alert-type-1/my-read-consumer-1/rule/getActionErrorLog", + "alerting:readonly-alert-type-1/my-read-consumer-1/rule/find", + "alerting:readonly-alert-type-1/my-read-consumer-1/rule/getRuleExecutionKPI", + "alerting:readonly-alert-type-1/my-read-consumer-1/rule/getBackfill", + "alerting:readonly-alert-type-1/my-read-consumer-1/rule/findBackfill", + "alerting:readonly-alert-type-1/my-read-consumer-2/rule/get", + "alerting:readonly-alert-type-1/my-read-consumer-2/rule/getRuleState", + "alerting:readonly-alert-type-1/my-read-consumer-2/rule/getAlertSummary", + "alerting:readonly-alert-type-1/my-read-consumer-2/rule/getExecutionLog", + "alerting:readonly-alert-type-1/my-read-consumer-2/rule/getActionErrorLog", + "alerting:readonly-alert-type-1/my-read-consumer-2/rule/find", + "alerting:readonly-alert-type-1/my-read-consumer-2/rule/getRuleExecutionKPI", + "alerting:readonly-alert-type-1/my-read-consumer-2/rule/getBackfill", + "alerting:readonly-alert-type-1/my-read-consumer-2/rule/findBackfill", + "alerting:readonly-alert-type-2/my-read-consumer-3/rule/get", + "alerting:readonly-alert-type-2/my-read-consumer-3/rule/getRuleState", + "alerting:readonly-alert-type-2/my-read-consumer-3/rule/getAlertSummary", + "alerting:readonly-alert-type-2/my-read-consumer-3/rule/getExecutionLog", + "alerting:readonly-alert-type-2/my-read-consumer-3/rule/getActionErrorLog", + "alerting:readonly-alert-type-2/my-read-consumer-3/rule/find", + "alerting:readonly-alert-type-2/my-read-consumer-3/rule/getRuleExecutionKPI", + "alerting:readonly-alert-type-2/my-read-consumer-3/rule/getBackfill", + "alerting:readonly-alert-type-2/my-read-consumer-3/rule/findBackfill", + "alerting:readonly-alert-type-2/my-read-consumer-4/rule/get", + "alerting:readonly-alert-type-2/my-read-consumer-4/rule/getRuleState", + "alerting:readonly-alert-type-2/my-read-consumer-4/rule/getAlertSummary", + "alerting:readonly-alert-type-2/my-read-consumer-4/rule/getExecutionLog", + "alerting:readonly-alert-type-2/my-read-consumer-4/rule/getActionErrorLog", + "alerting:readonly-alert-type-2/my-read-consumer-4/rule/find", + "alerting:readonly-alert-type-2/my-read-consumer-4/rule/getRuleExecutionKPI", + "alerting:readonly-alert-type-2/my-read-consumer-4/rule/getBackfill", + "alerting:readonly-alert-type-2/my-read-consumer-4/rule/findBackfill", + "alerting:another-alert-type-1/my-consumer-another-1/alert/get", + "alerting:another-alert-type-1/my-consumer-another-1/alert/find", + "alerting:another-alert-type-1/my-consumer-another-1/alert/getAuthorizedAlertsIndices", + "alerting:another-alert-type-1/my-consumer-another-1/alert/getAlertSummary", + "alerting:another-alert-type-1/my-consumer-another-1/alert/update", + "alerting:another-alert-type-1/my-consumer-another-2/alert/get", + "alerting:another-alert-type-1/my-consumer-another-2/alert/find", + "alerting:another-alert-type-1/my-consumer-another-2/alert/getAuthorizedAlertsIndices", + "alerting:another-alert-type-1/my-consumer-another-2/alert/getAlertSummary", + "alerting:another-alert-type-1/my-consumer-another-2/alert/update", + "alerting:another-alert-type-2/my-consumer-another-3/alert/get", + "alerting:another-alert-type-2/my-consumer-another-3/alert/find", + "alerting:another-alert-type-2/my-consumer-another-3/alert/getAuthorizedAlertsIndices", + "alerting:another-alert-type-2/my-consumer-another-3/alert/getAlertSummary", + "alerting:another-alert-type-2/my-consumer-another-3/alert/update", + "alerting:another-alert-type-2/my-consumer-another-1/alert/get", + "alerting:another-alert-type-2/my-consumer-another-1/alert/find", + "alerting:another-alert-type-2/my-consumer-another-1/alert/getAuthorizedAlertsIndices", + "alerting:another-alert-type-2/my-consumer-another-1/alert/getAlertSummary", + "alerting:another-alert-type-2/my-consumer-another-1/alert/update", + "alerting:readonly-another-alert-type-1/my-read-other-consumer-1/alert/get", + "alerting:readonly-another-alert-type-1/my-read-other-consumer-1/alert/find", + "alerting:readonly-another-alert-type-1/my-read-other-consumer-1/alert/getAuthorizedAlertsIndices", + "alerting:readonly-another-alert-type-1/my-read-other-consumer-1/alert/getAlertSummary", + "alerting:readonly-another-alert-type-1/my-read-other-consumer-2/alert/get", + "alerting:readonly-another-alert-type-1/my-read-other-consumer-2/alert/find", + "alerting:readonly-another-alert-type-1/my-read-other-consumer-2/alert/getAuthorizedAlertsIndices", + "alerting:readonly-another-alert-type-1/my-read-other-consumer-2/alert/getAlertSummary", + "alerting:readonly-another-alert-type-2/my-read-other-consumer-3/alert/get", + "alerting:readonly-another-alert-type-2/my-read-other-consumer-3/alert/find", + "alerting:readonly-another-alert-type-2/my-read-other-consumer-3/alert/getAuthorizedAlertsIndices", + "alerting:readonly-another-alert-type-2/my-read-other-consumer-3/alert/getAlertSummary", + "alerting:readonly-another-alert-type-2/my-read-other-consumer-4/alert/get", + "alerting:readonly-another-alert-type-2/my-read-other-consumer-4/alert/find", + "alerting:readonly-another-alert-type-2/my-read-other-consumer-4/alert/getAuthorizedAlertsIndices", + "alerting:readonly-another-alert-type-2/my-read-other-consumer-4/alert/getAlertSummary", ] `); }); diff --git a/x-pack/packages/security/authorization_core/src/privileges/feature_privilege_builder/alerting.ts b/x-pack/packages/security/authorization_core/src/privileges/feature_privilege_builder/alerting.ts index c0b7fa2ea8ab7..65c330b94c462 100644 --- a/x-pack/packages/security/authorization_core/src/privileges/feature_privilege_builder/alerting.ts +++ b/x-pack/packages/security/authorization_core/src/privileges/feature_privilege_builder/alerting.ts @@ -7,6 +7,7 @@ import { get, uniq } from 'lodash'; +import type { AlertingKibanaPrivilege } from '@kbn/features-plugin/common/alerting_kibana_privilege'; import type { FeatureKibanaPrivileges, KibanaFeature } from '@kbn/features-plugin/server'; import { BaseFeaturePrivilegeBuilder } from './feature_privilege_builder'; @@ -67,13 +68,14 @@ export class FeaturePrivilegeAlertingBuilder extends BaseFeaturePrivilegeBuilder ): string[] { const getAlertingPrivilege = ( operations: string[], - privilegedTypes: readonly string[], - alertingEntity: string, - consumer: string + privileges: AlertingKibanaPrivilege, + alertingEntity: string ) => - privilegedTypes.flatMap((type) => - operations.map((operation) => - this.actions.alerting.get(type, consumer, alertingEntity, operation) + privileges.flatMap(({ ruleTypeId, consumers }) => + consumers.flatMap((consumer) => + operations.map((operation) => + this.actions.alerting.get(ruleTypeId, consumer, alertingEntity, operation) + ) ) ); @@ -82,8 +84,8 @@ export class FeaturePrivilegeAlertingBuilder extends BaseFeaturePrivilegeBuilder const read = get(privilegeDefinition.alerting, `${entity}.read`) ?? []; return uniq([ - ...getAlertingPrivilege(allOperations[entity], all, entity, feature.id), - ...getAlertingPrivilege(readOperations[entity], read, entity, feature.id), + ...getAlertingPrivilege(allOperations[entity], all, entity), + ...getAlertingPrivilege(readOperations[entity], read, entity), ]); }; diff --git a/x-pack/packages/security/authorization_core/src/privileges/privileges.test.ts b/x-pack/packages/security/authorization_core/src/privileges/privileges.test.ts index 6af21d5357a72..22fb86f601b3a 100644 --- a/x-pack/packages/security/authorization_core/src/privileges/privileges.test.ts +++ b/x-pack/packages/security/authorization_core/src/privileges/privileges.test.ts @@ -481,7 +481,7 @@ describe('features', () => { name: 'Feature Alpha', app: [], category: { id: 'alpha', label: 'alpha' }, - alerting: ['rule-type-1'], + alerting: [{ ruleTypeId: 'rule-type-1', consumers: ['alpha'] }], privileges: { all: { savedObject: { @@ -491,7 +491,7 @@ describe('features', () => { ui: ['all-alpha-ui'], app: ['all-alpha-app'], api: ['all-alpha-api'], - alerting: { rule: { all: ['rule-type-1'] } }, + alerting: { rule: { all: [{ ruleTypeId: 'rule-type-1', consumers: ['alpha'] }] } }, replacedBy: [{ feature: 'beta', privileges: ['all'] }], }, read: { @@ -514,7 +514,7 @@ describe('features', () => { name: 'Feature Beta', app: [], category: { id: 'beta', label: 'beta' }, - alerting: ['rule-type-1'], + alerting: [{ ruleTypeId: 'rule-type-1', consumers: ['beta'] }], privileges: { all: { savedObject: { @@ -524,7 +524,7 @@ describe('features', () => { ui: ['all-beta-ui'], app: ['all-beta-app'], api: ['all-beta-api'], - alerting: { rule: { all: ['rule-type-1'] } }, + alerting: { rule: { all: [{ ruleTypeId: 'rule-type-1', consumers: ['beta'] }] } }, }, read: { savedObject: { @@ -604,13 +604,8 @@ describe('features', () => { ...alertingOperations.map((operation) => actions.alerting.get('rule-type-1', 'alpha', 'rule', operation) ), - // To maintain compatibility with the new UI capabilities and new alerting entities that are - // feature specific: all.replacedBy: [{ feature: 'beta', privileges: ['all'] }] actions.ui.get('navLinks', 'all-beta-app'), actions.ui.get('beta', 'all-beta-ui'), - ...alertingOperations.map((operation) => - actions.alerting.get('rule-type-1', 'beta', 'rule', operation) - ), ]; const expectedReadPrivileges = [ diff --git a/x-pack/packages/security/authorization_core/src/privileges/privileges.ts b/x-pack/packages/security/authorization_core/src/privileges/privileges.ts index b81eaba5fa54d..f266b2b9a7085 100644 --- a/x-pack/packages/security/authorization_core/src/privileges/privileges.ts +++ b/x-pack/packages/security/authorization_core/src/privileges/privileges.ts @@ -94,17 +94,15 @@ export function privilegesFactory( // If a privilege is configured with `replacedBy`, it's part of the deprecated feature and // should be complemented with the subset of actions from the referenced privileges to // maintain backward compatibility. Namely, deprecated privileges should grant the same UI - // capabilities and alerting actions as the privileges that replace them, so that the - // client-side code can safely use only non-deprecated UI capabilities and users can still - // access previously created alerting rules and alerts. + // capabilities as the privileges that replace them, so that the client-side code can safely + // use only non-deprecated UI capabilities. const replacedBy = getReplacedByForPrivilege(privilegeId, privilege); if (replacedBy) { composablePrivileges.push({ featureId: feature.id, privilegeId, references: replacedBy, - actionsFilter: (action) => - actions.ui.isValid(action) || actions.alerting.isValid(action), + actionsFilter: (action) => actions.ui.isValid(action), }); } }; diff --git a/x-pack/plugins/actions/server/actions_client/actions_client.mock.ts b/x-pack/plugins/actions/server/actions_client/actions_client.mock.ts index 433e3850cae2a..9834765487a80 100644 --- a/x-pack/plugins/actions/server/actions_client/actions_client.mock.ts +++ b/x-pack/plugins/actions/server/actions_client/actions_client.mock.ts @@ -22,7 +22,6 @@ const createActionsClientMock = () => { getBulk: jest.fn(), getOAuthAccessToken: jest.fn(), execute: jest.fn(), - ephemeralEnqueuedExecution: jest.fn(), bulkEnqueueExecution: jest.fn(), listTypes: jest.fn(), isActionTypeEnabled: jest.fn(), diff --git a/x-pack/plugins/actions/server/actions_client/actions_client.test.ts b/x-pack/plugins/actions/server/actions_client/actions_client.test.ts index 99bcbf15ecfb9..b977f8fb97cd3 100644 --- a/x-pack/plugins/actions/server/actions_client/actions_client.test.ts +++ b/x-pack/plugins/actions/server/actions_client/actions_client.test.ts @@ -79,7 +79,6 @@ const unsecuredSavedObjectsClient = savedObjectsClientMock.create(); const scopedClusterClient = elasticsearchServiceMock.createScopedClusterClient(); const actionExecutor = actionExecutorMock.create(); const authorization = actionsAuthorizationMock.create(); -const ephemeralExecutionEnqueuer = jest.fn(); const bulkExecutionEnqueuer = jest.fn(); const request = httpServerMock.createKibanaRequest(); const auditLogger = auditLoggerMock.create(); @@ -138,7 +137,6 @@ beforeEach(() => { kibanaIndices, inMemoryConnectors: [], actionExecutor, - ephemeralExecutionEnqueuer, bulkExecutionEnqueuer, request, authorization: authorization as unknown as ActionsAuthorization, @@ -613,7 +611,6 @@ describe('create()', () => { kibanaIndices, inMemoryConnectors: [], actionExecutor, - ephemeralExecutionEnqueuer, bulkExecutionEnqueuer, request, authorization: authorization as unknown as ActionsAuthorization, @@ -739,7 +736,6 @@ describe('create()', () => { ], actionExecutor, - ephemeralExecutionEnqueuer, bulkExecutionEnqueuer, request, authorization: authorization as unknown as ActionsAuthorization, @@ -801,7 +797,6 @@ describe('create()', () => { scopedClusterClient, kibanaIndices, actionExecutor, - ephemeralExecutionEnqueuer, bulkExecutionEnqueuer, request, authorization: authorization as unknown as ActionsAuthorization, @@ -862,7 +857,6 @@ describe('get()', () => { scopedClusterClient, kibanaIndices, actionExecutor, - ephemeralExecutionEnqueuer, bulkExecutionEnqueuer, request, authorization: authorization as unknown as ActionsAuthorization, @@ -899,7 +893,6 @@ describe('get()', () => { scopedClusterClient, kibanaIndices, actionExecutor, - ephemeralExecutionEnqueuer, bulkExecutionEnqueuer, request, authorization: authorization as unknown as ActionsAuthorization, @@ -956,7 +949,6 @@ describe('get()', () => { scopedClusterClient, kibanaIndices, actionExecutor, - ephemeralExecutionEnqueuer, bulkExecutionEnqueuer, request, authorization: authorization as unknown as ActionsAuthorization, @@ -999,7 +991,6 @@ describe('get()', () => { scopedClusterClient, kibanaIndices, actionExecutor, - ephemeralExecutionEnqueuer, bulkExecutionEnqueuer, request, authorization: authorization as unknown as ActionsAuthorization, @@ -1121,7 +1112,6 @@ describe('get()', () => { scopedClusterClient, kibanaIndices, actionExecutor, - ephemeralExecutionEnqueuer, bulkExecutionEnqueuer, request, authorization: authorization as unknown as ActionsAuthorization, @@ -1165,7 +1155,6 @@ describe('get()', () => { scopedClusterClient, kibanaIndices, actionExecutor, - ephemeralExecutionEnqueuer, bulkExecutionEnqueuer, request, authorization: authorization as unknown as ActionsAuthorization, @@ -1199,7 +1188,6 @@ describe('get()', () => { scopedClusterClient, kibanaIndices, actionExecutor, - ephemeralExecutionEnqueuer, bulkExecutionEnqueuer, request, authorization: authorization as unknown as ActionsAuthorization, @@ -1270,7 +1258,6 @@ describe('getBulk()', () => { scopedClusterClient, kibanaIndices, actionExecutor, - ephemeralExecutionEnqueuer, bulkExecutionEnqueuer, request, authorization: authorization as unknown as ActionsAuthorization, @@ -1408,7 +1395,6 @@ describe('getBulk()', () => { scopedClusterClient, kibanaIndices, actionExecutor, - ephemeralExecutionEnqueuer, bulkExecutionEnqueuer, request, authorization: authorization as unknown as ActionsAuthorization, @@ -1503,7 +1489,6 @@ describe('getBulk()', () => { scopedClusterClient, kibanaIndices, actionExecutor, - ephemeralExecutionEnqueuer, bulkExecutionEnqueuer, request, authorization: authorization as unknown as ActionsAuthorization, @@ -1577,7 +1562,6 @@ describe('getBulk()', () => { scopedClusterClient, kibanaIndices, actionExecutor, - ephemeralExecutionEnqueuer, bulkExecutionEnqueuer, request, authorization: authorization as unknown as ActionsAuthorization, @@ -1662,7 +1646,6 @@ describe('getOAuthAccessToken()', () => { scopedClusterClient, kibanaIndices, actionExecutor, - ephemeralExecutionEnqueuer, bulkExecutionEnqueuer, request, authorization: authorization as unknown as ActionsAuthorization, @@ -2097,7 +2080,6 @@ describe('delete()', () => { }, ], actionExecutor, - ephemeralExecutionEnqueuer, bulkExecutionEnqueuer, request, authorization: authorization as unknown as ActionsAuthorization, @@ -2133,7 +2115,6 @@ describe('delete()', () => { }, ], actionExecutor, - ephemeralExecutionEnqueuer, bulkExecutionEnqueuer, request, authorization: authorization as unknown as ActionsAuthorization, @@ -2653,7 +2634,6 @@ describe('update()', () => { }, ], actionExecutor, - ephemeralExecutionEnqueuer, bulkExecutionEnqueuer, request, authorization: authorization as unknown as ActionsAuthorization, @@ -2696,7 +2676,6 @@ describe('update()', () => { }, ], actionExecutor, - ephemeralExecutionEnqueuer, bulkExecutionEnqueuer, request, authorization: authorization as unknown as ActionsAuthorization, @@ -2782,7 +2761,6 @@ describe('execute()', () => { scopedClusterClient, kibanaIndices, actionExecutor, - ephemeralExecutionEnqueuer, bulkExecutionEnqueuer, request, authorization: authorization as unknown as ActionsAuthorization, @@ -2845,7 +2823,6 @@ describe('execute()', () => { scopedClusterClient, kibanaIndices, actionExecutor, - ephemeralExecutionEnqueuer, bulkExecutionEnqueuer, request, authorization: authorization as unknown as ActionsAuthorization, @@ -2907,7 +2884,6 @@ describe('execute()', () => { scopedClusterClient, kibanaIndices, actionExecutor, - ephemeralExecutionEnqueuer, bulkExecutionEnqueuer, request, authorization: authorization as unknown as ActionsAuthorization, @@ -3180,7 +3156,6 @@ describe('isPreconfigured()', () => { scopedClusterClient, kibanaIndices, actionExecutor, - ephemeralExecutionEnqueuer, bulkExecutionEnqueuer, request, authorization: authorization as unknown as ActionsAuthorization, @@ -3230,7 +3205,6 @@ describe('isPreconfigured()', () => { scopedClusterClient, kibanaIndices, actionExecutor, - ephemeralExecutionEnqueuer, bulkExecutionEnqueuer, request, authorization: authorization as unknown as ActionsAuthorization, @@ -3282,7 +3256,6 @@ describe('isSystemAction()', () => { scopedClusterClient, kibanaIndices, actionExecutor, - ephemeralExecutionEnqueuer, bulkExecutionEnqueuer, request, authorization: authorization as unknown as ActionsAuthorization, @@ -3332,7 +3305,6 @@ describe('isSystemAction()', () => { scopedClusterClient, kibanaIndices, actionExecutor, - ephemeralExecutionEnqueuer, bulkExecutionEnqueuer, request, authorization: authorization as unknown as ActionsAuthorization, diff --git a/x-pack/plugins/actions/server/actions_client/actions_client.ts b/x-pack/plugins/actions/server/actions_client/actions_client.ts index 5c563fbd6aa82..e39cf8712894f 100644 --- a/x-pack/plugins/actions/server/actions_client/actions_client.ts +++ b/x-pack/plugins/actions/server/actions_client/actions_client.ts @@ -18,7 +18,6 @@ import { Logger, } from '@kbn/core/server'; import { AuditLogger } from '@kbn/security-plugin/server'; -import { RunNowResult } from '@kbn/task-manager-plugin/server'; import { IEventLogClient } from '@kbn/event-log-plugin/server'; import { KueryNode } from '@kbn/es-query'; import { Connector, ConnectorWithExtraFindData } from '../application/connector/types'; @@ -46,7 +45,6 @@ import { } from '../types'; import { PreconfiguredActionDisabledModificationError } from '../lib/errors/preconfigured_action_disabled_modification'; import { - ExecutionEnqueuer, ExecuteOptions as EnqueueExecutionOptions, BulkExecutionEnqueuer, ExecutionResponse, @@ -92,7 +90,6 @@ export interface ConstructorOptions { unsecuredSavedObjectsClient: SavedObjectsClientContract; inMemoryConnectors: InMemoryConnector[]; actionExecutor: ActionExecutorContract; - ephemeralExecutionEnqueuer: ExecutionEnqueuer; bulkExecutionEnqueuer: BulkExecutionEnqueuer; request: KibanaRequest; authorization: ActionsAuthorization; @@ -112,7 +109,6 @@ export interface ActionsClientContext { actionExecutor: ActionExecutorContract; request: KibanaRequest; authorization: ActionsAuthorization; - ephemeralExecutionEnqueuer: ExecutionEnqueuer; bulkExecutionEnqueuer: BulkExecutionEnqueuer; auditLogger?: AuditLogger; usageCounter?: UsageCounter; @@ -131,7 +127,6 @@ export class ActionsClient { unsecuredSavedObjectsClient, inMemoryConnectors, actionExecutor, - ephemeralExecutionEnqueuer, bulkExecutionEnqueuer, request, authorization, @@ -148,7 +143,6 @@ export class ActionsClient { kibanaIndices, inMemoryConnectors, actionExecutor, - ephemeralExecutionEnqueuer, bulkExecutionEnqueuer, request, authorization, @@ -504,18 +498,6 @@ export class ActionsClient { return this.context.bulkExecutionEnqueuer(this.context.unsecuredSavedObjectsClient, options); } - public async ephemeralEnqueuedExecution(options: EnqueueExecutionOptions): Promise { - await this.context.authorization.ensureAuthorized({ - operation: 'execute', - actionTypeId: options.actionTypeId, - }); - - return this.context.ephemeralExecutionEnqueuer( - this.context.unsecuredSavedObjectsClient, - options - ); - } - public async listTypes({ featureId, includeSystemActionTypes = false, diff --git a/x-pack/plugins/actions/server/actions_client/actions_client_hooks.test.ts b/x-pack/plugins/actions/server/actions_client/actions_client_hooks.test.ts index 7a1a0fb5e3d91..303254a66ea19 100644 --- a/x-pack/plugins/actions/server/actions_client/actions_client_hooks.test.ts +++ b/x-pack/plugins/actions/server/actions_client/actions_client_hooks.test.ts @@ -38,7 +38,6 @@ const unsecuredSavedObjectsClient = savedObjectsClientMock.create(); const scopedClusterClient = elasticsearchServiceMock.createScopedClusterClient(); const actionExecutor = actionExecutorMock.create(); const authorization = actionsAuthorizationMock.create(); -const ephemeralExecutionEnqueuer = jest.fn(); const bulkExecutionEnqueuer = jest.fn(); const request = httpServerMock.createKibanaRequest(); const auditLogger = auditLoggerMock.create(); @@ -131,7 +130,6 @@ beforeEach(() => { kibanaIndices, inMemoryConnectors: [], actionExecutor, - ephemeralExecutionEnqueuer, bulkExecutionEnqueuer, request, authorization: authorization as unknown as ActionsAuthorization, diff --git a/x-pack/plugins/actions/server/application/connector/methods/get_all/get_all.test.ts b/x-pack/plugins/actions/server/application/connector/methods/get_all/get_all.test.ts index 0f86a8e582e34..5ff37776cf2dc 100644 --- a/x-pack/plugins/actions/server/application/connector/methods/get_all/get_all.test.ts +++ b/x-pack/plugins/actions/server/application/connector/methods/get_all/get_all.test.ts @@ -52,7 +52,6 @@ const unsecuredSavedObjectsClient = savedObjectsClientMock.create(); const scopedClusterClient = elasticsearchServiceMock.createScopedClusterClient(); const actionExecutor = actionExecutorMock.create(); const authorization = actionsAuthorizationMock.create(); -const ephemeralExecutionEnqueuer = jest.fn(); const bulkExecutionEnqueuer = jest.fn(); const request = httpServerMock.createKibanaRequest(); const auditLogger = auditLoggerMock.create(); @@ -78,7 +77,6 @@ describe('getAll()', () => { kibanaIndices, inMemoryConnectors: [], actionExecutor, - ephemeralExecutionEnqueuer, bulkExecutionEnqueuer, request, authorization: authorization as unknown as ActionsAuthorization, @@ -134,7 +132,6 @@ describe('getAll()', () => { scopedClusterClient, kibanaIndices, actionExecutor, - ephemeralExecutionEnqueuer, bulkExecutionEnqueuer, request, authorization: authorization as unknown as ActionsAuthorization, @@ -279,7 +276,6 @@ describe('getAll()', () => { scopedClusterClient, kibanaIndices, actionExecutor, - ephemeralExecutionEnqueuer, bulkExecutionEnqueuer, request, authorization: authorization as unknown as ActionsAuthorization, @@ -382,7 +378,6 @@ describe('getAll()', () => { scopedClusterClient, kibanaIndices, actionExecutor, - ephemeralExecutionEnqueuer, bulkExecutionEnqueuer, request, authorization: authorization as unknown as ActionsAuthorization, @@ -487,7 +482,6 @@ describe('getAll()', () => { scopedClusterClient, kibanaIndices, actionExecutor, - ephemeralExecutionEnqueuer, bulkExecutionEnqueuer, request, authorization: authorization as unknown as ActionsAuthorization, @@ -579,7 +573,6 @@ describe('getAll()', () => { scopedClusterClient, kibanaIndices, actionExecutor, - ephemeralExecutionEnqueuer, bulkExecutionEnqueuer, request, authorization: authorization as unknown as ActionsAuthorization, @@ -613,7 +606,6 @@ describe('getAll()', () => { scopedClusterClient, kibanaIndices, actionExecutor, - ephemeralExecutionEnqueuer, bulkExecutionEnqueuer, request, authorization: authorization as unknown as ActionsAuthorization, @@ -690,7 +682,6 @@ describe('getAll()', () => { scopedClusterClient, kibanaIndices, actionExecutor, - ephemeralExecutionEnqueuer, bulkExecutionEnqueuer, request, authorization: authorization as unknown as ActionsAuthorization, diff --git a/x-pack/plugins/actions/server/application/connector/methods/list_types/list_types.test.ts b/x-pack/plugins/actions/server/application/connector/methods/list_types/list_types.test.ts index 9ff5e05d45506..056d535ce438b 100644 --- a/x-pack/plugins/actions/server/application/connector/methods/list_types/list_types.test.ts +++ b/x-pack/plugins/actions/server/application/connector/methods/list_types/list_types.test.ts @@ -60,7 +60,6 @@ describe('listTypes()', () => { unsecuredSavedObjectsClient: savedObjectsClientMock.create(), inMemoryConnectors: [], actionExecutor: actionExecutorMock.create(), - ephemeralExecutionEnqueuer: jest.fn(), bulkExecutionEnqueuer: jest.fn(), request: httpServerMock.createKibanaRequest(), authorization: actionsAuthorizationMock.create() as unknown as ActionsAuthorization, diff --git a/x-pack/plugins/actions/server/create_execute_function.ts b/x-pack/plugins/actions/server/create_execute_function.ts index a92bff9719559..539ada46a094a 100644 --- a/x-pack/plugins/actions/server/create_execute_function.ts +++ b/x-pack/plugins/actions/server/create_execute_function.ts @@ -6,13 +6,8 @@ */ import { SavedObjectsBulkResponse, SavedObjectsClientContract, Logger } from '@kbn/core/server'; -import { RunNowResult, TaskManagerStartContract } from '@kbn/task-manager-plugin/server'; -import { - RawAction, - ActionTypeRegistryContract, - InMemoryConnector, - ActionTaskExecutorParams, -} from './types'; +import { TaskManagerStartContract } from '@kbn/task-manager-plugin/server'; +import { RawAction, ActionTypeRegistryContract, InMemoryConnector } from './types'; import { ACTION_TASK_PARAMS_SAVED_OBJECT_TYPE } from './constants/saved_objects'; import { ExecuteOptions as ActionExecutorOptions } from './lib/action_executor'; import { extractSavedObjectReferences, isSavedObjectExecutionSource } from './lib'; @@ -215,43 +210,6 @@ export function createBulkExecutionEnqueuerFunction({ }; } -export function createEphemeralExecutionEnqueuerFunction({ - taskManager, - actionTypeRegistry, - inMemoryConnectors, - logger, -}: CreateExecuteFunctionOptions): ExecutionEnqueuer { - return async function execute( - unsecuredSavedObjectsClient: SavedObjectsClientContract, - { id, params, spaceId, source, consumer, apiKey, executionId }: ExecuteOptions - ): Promise { - const { connector } = await getConnector(unsecuredSavedObjectsClient, inMemoryConnectors, id); - - validateConnector({ id, connector, actionTypeRegistry }); - - const taskParams: ActionTaskExecutorParams = { - spaceId, - taskParams: { - actionId: id, - consumer, - // Saved Objects won't allow us to enforce unknown rather than any - // eslint-disable-next-line @typescript-eslint/no-explicit-any - params: params as Record, - ...(apiKey ? { apiKey } : {}), - ...(executionId ? { executionId } : {}), - }, - ...executionSourceAsSavedObjectReferences(source), - }; - - return taskManager.ephemeralRunNow({ - taskType: `actions:${connector.actionTypeId}`, - params: taskParams, - state: {}, - scope: ['actions'], - }); - }; -} - function validateConnector({ id, connector, @@ -287,21 +245,6 @@ function executionSourceAsSavedObjectReferences(executionSource: ActionExecutorO : {}; } -async function getConnector( - unsecuredSavedObjectsClient: SavedObjectsClientContract, - inMemoryConnectors: InMemoryConnector[], - actionId: string -): Promise<{ connector: InMemoryConnector | RawAction; isInMemory: boolean }> { - const inMemoryAction = inMemoryConnectors.find((action) => action.id === actionId); - - if (inMemoryAction) { - return { connector: inMemoryAction, isInMemory: true }; - } - - const { attributes } = await unsecuredSavedObjectsClient.get('action', actionId); - return { connector: attributes, isInMemory: false }; -} - async function getConnectors( unsecuredSavedObjectsClient: SavedObjectsClientContract, inMemoryConnectors: InMemoryConnector[], diff --git a/x-pack/plugins/actions/server/lib/action_executor.ts b/x-pack/plugins/actions/server/lib/action_executor.ts index b0f9db0ef700c..799fdb80f39af 100644 --- a/x-pack/plugins/actions/server/lib/action_executor.ts +++ b/x-pack/plugins/actions/server/lib/action_executor.ts @@ -82,7 +82,6 @@ export interface ExecuteOptions { actionId: string; consumer?: string; executionId?: string; - isEphemeral?: boolean; params: Record; relatedSavedObjects?: RelatedSavedObjects; request: KibanaRequest; @@ -133,7 +132,6 @@ export class ActionExecutor { actionId, consumer, executionId, - isEphemeral, request, params, relatedSavedObjects, @@ -175,7 +173,6 @@ export class ActionExecutor { }, executeLabel: `execute_action`, executionId, - isEphemeral, namespace, params, relatedSavedObjects, @@ -367,7 +364,6 @@ export class ActionExecutor { checkCanExecuteFn, executeLabel, executionId, - isEphemeral, namespace, params, relatedSavedObjects, @@ -512,7 +508,6 @@ export class ActionExecutor { params: validatedParams, config: validatedConfig, secrets: validatedSecrets, - isEphemeral, taskInfo, configurationUtilities, logger, diff --git a/x-pack/plugins/actions/server/lib/task_runner_factory.test.ts b/x-pack/plugins/actions/server/lib/task_runner_factory.test.ts index 9733b56638d77..0dc2b2f3f5c9a 100644 --- a/x-pack/plugins/actions/server/lib/task_runner_factory.test.ts +++ b/x-pack/plugins/actions/server/lib/task_runner_factory.test.ts @@ -35,7 +35,6 @@ import { SavedObjectsErrorHelpers } from '@kbn/core-saved-objects-server'; const executeParamsFields = [ 'actionId', - 'isEphemeral', 'params', 'relatedSavedObjects', 'executionId', @@ -173,7 +172,6 @@ describe('Task Runner Factory', () => { const [executeParams] = mockedActionExecutor.execute.mock.calls[0]; expect(pick(executeParams, executeParamsFields)).toEqual({ actionId: '2', - isEphemeral: false, params: { baz: true }, relatedSavedObjects: [], executionId: '123abc', @@ -233,7 +231,6 @@ describe('Task Runner Factory', () => { const [executeParams] = mockedActionExecutor.execute.mock.calls[0]; expect(pick(executeParams, executeParamsFields)).toEqual({ actionId: '9', - isEphemeral: false, params: { baz: true }, executionId: '123abc', relatedSavedObjects: [], @@ -289,7 +286,6 @@ describe('Task Runner Factory', () => { expect(pick(executeParams, [...executeParamsFields, 'consumer'])).toEqual({ actionId: '2', consumer: 'test-consumer', - isEphemeral: false, params: { baz: true }, relatedSavedObjects: [], executionId: '123abc', @@ -346,7 +342,6 @@ describe('Task Runner Factory', () => { expect(pick(executeParams, [...executeParamsFields, 'consumer'])).toEqual({ actionId: '2', consumer: 'test-consumer', - isEphemeral: false, params: { baz: true }, relatedSavedObjects: [], executionId: '123abc', @@ -407,7 +402,6 @@ describe('Task Runner Factory', () => { expect(pick(executeParams, [...executeParamsFields, 'consumer'])).toEqual({ actionId: '2', consumer: 'test-consumer', - isEphemeral: false, params: { baz: true }, relatedSavedObjects: [], executionId: '123abc', @@ -569,7 +563,6 @@ describe('Task Runner Factory', () => { const [executeParams] = mockedActionExecutor.execute.mock.calls[0]; expect(pick(executeParams, executeParamsFields)).toEqual({ actionId: '2', - isEphemeral: false, params: { baz: true }, executionId: '123abc', relatedSavedObjects: [], @@ -627,7 +620,6 @@ describe('Task Runner Factory', () => { const [executeParams] = mockedActionExecutor.execute.mock.calls[0]; expect(pick(executeParams, executeParamsFields)).toEqual({ actionId: '2', - isEphemeral: false, params: { baz: true }, executionId: '123abc', relatedSavedObjects: [ @@ -680,7 +672,6 @@ describe('Task Runner Factory', () => { const [executeParams] = mockedActionExecutor.execute.mock.calls[0]; expect(pick(executeParams, executeParamsFields)).toEqual({ actionId: '2', - isEphemeral: false, params: { baz: true }, executionId: '123abc', relatedSavedObjects: [ @@ -739,7 +730,6 @@ describe('Task Runner Factory', () => { const [executeParams] = mockedActionExecutor.execute.mock.calls[0]; expect(pick(executeParams, executeParamsFields)).toEqual({ actionId: '2', - isEphemeral: false, params: { baz: true }, request: { headers: { @@ -785,7 +775,6 @@ describe('Task Runner Factory', () => { const [executeParams] = mockedActionExecutor.execute.mock.calls[0]; expect(pick(executeParams, executeParamsFields)).toEqual({ actionId: '2', - isEphemeral: false, params: { baz: true }, executionId: '123abc', relatedSavedObjects: [], diff --git a/x-pack/plugins/actions/server/lib/task_runner_factory.ts b/x-pack/plugins/actions/server/lib/task_runner_factory.ts index cf1f9eed87c32..b718a32a2e4ad 100644 --- a/x-pack/plugins/actions/server/lib/task_runner_factory.ts +++ b/x-pack/plugins/actions/server/lib/task_runner_factory.ts @@ -32,7 +32,6 @@ import { ActionTaskParams, ActionTypeExecutorResult, ActionTypeRegistryContract, - isPersistedActionTask, SpaceIdToNamespaceFunction, } from '../types'; import { ACTION_TASK_PARAMS_SAVED_OBJECT_TYPE } from '../constants/saved_objects'; @@ -128,7 +127,6 @@ export class TaskRunnerFactory { executorResult = await actionExecutor.execute({ params, actionId: actionId as string, - isEphemeral: !isPersistedActionTask(actionTaskExecutorParams), request, taskInfo, executionId, @@ -209,19 +207,17 @@ export class TaskRunnerFactory { }, cleanup: async () => { // Cleanup action_task_params object now that we're done with it - if (isPersistedActionTask(actionTaskExecutorParams)) { - try { - await savedObjectsRepository.delete( - ACTION_TASK_PARAMS_SAVED_OBJECT_TYPE, - actionTaskExecutorParams.actionTaskParamsId, - { refresh: false, namespace: spaceIdToNamespace(actionTaskExecutorParams.spaceId) } - ); - } catch (e) { - // Log error only, we shouldn't fail the task because of an error here (if ever there's retry logic) - logger.error( - `Failed to cleanup ${ACTION_TASK_PARAMS_SAVED_OBJECT_TYPE} object [id="${actionTaskExecutorParams.actionTaskParamsId}"]: ${e.message}` - ); - } + try { + await savedObjectsRepository.delete( + ACTION_TASK_PARAMS_SAVED_OBJECT_TYPE, + actionTaskExecutorParams.actionTaskParamsId, + { refresh: false, namespace: spaceIdToNamespace(actionTaskExecutorParams.spaceId) } + ); + } catch (e) { + // Log error only, we shouldn't fail the task because of an error here (if ever there's retry logic) + logger.error( + `Failed to cleanup ${ACTION_TASK_PARAMS_SAVED_OBJECT_TYPE} object [id="${actionTaskExecutorParams.actionTaskParamsId}"]: ${e.message}` + ); } }, }; @@ -252,45 +248,41 @@ async function getActionTaskParams( ): Promise { const { spaceId } = executorParams; const namespace = spaceIdToNamespace(spaceId); - if (isPersistedActionTask(executorParams)) { - try { - const actionTask = - await encryptedSavedObjectsClient.getDecryptedAsInternalUser( - ACTION_TASK_PARAMS_SAVED_OBJECT_TYPE, - executorParams.actionTaskParamsId, - { namespace } - ); - const { - attributes: { relatedSavedObjects }, - references, - } = actionTask; + try { + const actionTask = + await encryptedSavedObjectsClient.getDecryptedAsInternalUser( + ACTION_TASK_PARAMS_SAVED_OBJECT_TYPE, + executorParams.actionTaskParamsId, + { namespace } + ); + const { + attributes: { relatedSavedObjects }, + references, + } = actionTask; - const { actionId, relatedSavedObjects: injectedRelatedSavedObjects } = - injectSavedObjectReferences(references, relatedSavedObjects as RelatedSavedObjects); + const { actionId, relatedSavedObjects: injectedRelatedSavedObjects } = + injectSavedObjectReferences(references, relatedSavedObjects as RelatedSavedObjects); - return { - ...actionTask, - attributes: { - ...actionTask.attributes, - ...(actionId ? { actionId } : {}), - ...(relatedSavedObjects ? { relatedSavedObjects: injectedRelatedSavedObjects } : {}), - }, - }; - } catch (e) { - const errorSource = SavedObjectsErrorHelpers.isNotFoundError(e) - ? TaskErrorSource.USER - : TaskErrorSource.FRAMEWORK; - logger.error( - `Failed to load action task params ${executorParams.actionTaskParamsId}: ${e.message}`, - { tags: ['connector-run-failed', `${errorSource}-error`] } - ); - if (SavedObjectsErrorHelpers.isNotFoundError(e)) { - throw createRetryableError(createTaskRunError(e, errorSource), true); - } + return { + ...actionTask, + attributes: { + ...actionTask.attributes, + ...(actionId ? { actionId } : {}), + ...(relatedSavedObjects ? { relatedSavedObjects: injectedRelatedSavedObjects } : {}), + }, + }; + } catch (e) { + const errorSource = SavedObjectsErrorHelpers.isNotFoundError(e) + ? TaskErrorSource.USER + : TaskErrorSource.FRAMEWORK; + logger.error( + `Failed to load action task params ${executorParams.actionTaskParamsId}: ${e.message}`, + { tags: ['connector-run-failed', `${errorSource}-error`] } + ); + if (SavedObjectsErrorHelpers.isNotFoundError(e)) { throw createRetryableError(createTaskRunError(e, errorSource), true); } - } else { - return { attributes: executorParams.taskParams, references: executorParams.references ?? [] }; + throw createRetryableError(createTaskRunError(e, errorSource), true); } } diff --git a/x-pack/plugins/actions/server/plugin.ts b/x-pack/plugins/actions/server/plugin.ts index edfd7606950c1..012f602398e64 100644 --- a/x-pack/plugins/actions/server/plugin.ts +++ b/x-pack/plugins/actions/server/plugin.ts @@ -48,10 +48,7 @@ import { resolveCustomHosts } from './lib/custom_host_settings'; import { events } from './lib/event_based_telemetry'; import { ActionsClient } from './actions_client/actions_client'; import { ActionTypeRegistry } from './action_type_registry'; -import { - createEphemeralExecutionEnqueuerFunction, - createBulkExecutionEnqueuerFunction, -} from './create_execute_function'; +import { createBulkExecutionEnqueuerFunction } from './create_execute_function'; import { registerActionsUsageCollector } from './usage'; import { ActionExecutor, @@ -480,14 +477,6 @@ export class ActionsPlugin implements Plugin; @@ -238,27 +236,11 @@ export interface ActionTaskParams extends SavedObjectAttributes { source?: string; } -interface PersistedActionTaskExecutorParams { +export interface ActionTaskExecutorParams { spaceId: string; actionTaskParamsId: string; } -interface EphemeralActionTaskExecutorParams { - spaceId: string; - taskParams: ActionTaskParams; - references?: SavedObjectReference[]; -} - -export type ActionTaskExecutorParams = - | PersistedActionTaskExecutorParams - | EphemeralActionTaskExecutorParams; - -export function isPersistedActionTask( - actionTask: ActionTaskExecutorParams -): actionTask is PersistedActionTaskExecutorParams { - return typeof (actionTask as PersistedActionTaskExecutorParams).actionTaskParamsId === 'string'; -} - export interface ProxySettings { proxyUrl: string; proxyBypassHosts: Set | undefined; diff --git a/x-pack/plugins/ai_infra/product_doc_base/server/services/inference_endpoint/utils/install_elser.ts b/x-pack/plugins/ai_infra/product_doc_base/server/services/inference_endpoint/utils/install_elser.ts index 0e92d765a3d17..c4ad3c43ce071 100644 --- a/x-pack/plugins/ai_infra/product_doc_base/server/services/inference_endpoint/utils/install_elser.ts +++ b/x-pack/plugins/ai_infra/product_doc_base/server/services/inference_endpoint/utils/install_elser.ts @@ -23,7 +23,7 @@ export const installElser = async ({ inference_config: { service: 'elasticsearch', service_settings: { - num_allocations: 1, + adaptive_allocations: { enabled: true }, num_threads: 1, model_id: '.elser_model_2', }, diff --git a/x-pack/plugins/aiops/public/cases/log_rate_analysis_attachment.tsx b/x-pack/plugins/aiops/public/cases/log_rate_analysis_attachment.tsx new file mode 100644 index 0000000000000..d3d74d3913084 --- /dev/null +++ b/x-pack/plugins/aiops/public/cases/log_rate_analysis_attachment.tsx @@ -0,0 +1,52 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { memoize } from 'lodash'; +import type { FieldFormatsStart } from '@kbn/field-formats-plugin/public'; +import type { PersistableStateAttachmentViewProps } from '@kbn/cases-plugin/public/client/attachment_framework/types'; +import { FIELD_FORMAT_IDS } from '@kbn/field-formats-plugin/common'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { EuiDescriptionList } from '@elastic/eui'; +import type { + LogRateAnalysisEmbeddableWrapper, + LogRateAnalysisEmbeddableWrapperProps, +} from '../shared_components/log_rate_analysis_embeddable_wrapper'; + +export const initComponent = memoize( + (fieldFormats: FieldFormatsStart, LogRateAnalysisComponent: LogRateAnalysisEmbeddableWrapper) => { + return React.memo((props: PersistableStateAttachmentViewProps) => { + const { persistableStateAttachmentState } = props; + const dataFormatter = fieldFormats.deserialize({ + id: FIELD_FORMAT_IDS.DATE, + }); + const inputProps = + persistableStateAttachmentState as unknown as LogRateAnalysisEmbeddableWrapperProps; + + const listItems = [ + { + title: ( + + ), + description: `${dataFormatter.convert( + inputProps.timeRange.from + )} - ${dataFormatter.convert(inputProps.timeRange.to)}`, + }, + ]; + + return ( + <> + + + + ); + }); + } +); diff --git a/x-pack/plugins/aiops/public/cases/register_cases.tsx b/x-pack/plugins/aiops/public/cases/register_cases.tsx index b3b6efaf16d28..b98aca16fee7d 100644 --- a/x-pack/plugins/aiops/public/cases/register_cases.tsx +++ b/x-pack/plugins/aiops/public/cases/register_cases.tsx @@ -12,8 +12,10 @@ import type { CasesPublicSetup } from '@kbn/cases-plugin/public'; import type { CoreStart } from '@kbn/core/public'; import { CASES_ATTACHMENT_CHANGE_POINT_CHART } from '@kbn/aiops-change-point-detection/constants'; import { CASES_ATTACHMENT_LOG_PATTERN } from '@kbn/aiops-log-pattern-analysis/constants'; +import { CASES_ATTACHMENT_LOG_RATE_ANALYSIS } from '@kbn/aiops-log-rate-analysis/constants'; import { getChangePointDetectionComponent, + getLogRateAnalysisEmbeddableWrapperComponent, getPatternAnalysisComponent, } from '../shared_components'; import type { AiopsPluginStartDeps } from '../types'; @@ -47,6 +49,14 @@ export function registerCases( }; }), }), + getAttachmentRemovalObject: () => ({ + event: ( + + ), + }), }); const LogPatternAttachmentComponent = getPatternAnalysisComponent(coreStart, pluginStart); @@ -71,5 +81,53 @@ export function registerCases( return { default: initComponent(pluginStart.fieldFormats, LogPatternAttachmentComponent) }; }), }), + getAttachmentRemovalObject: () => ({ + event: ( + + ), + }), + }); + + const LogRateAnalysisEmbeddableWrapperComponent = getLogRateAnalysisEmbeddableWrapperComponent( + coreStart, + pluginStart + ); + + cases.attachmentFramework.registerPersistableState({ + id: CASES_ATTACHMENT_LOG_RATE_ANALYSIS, + icon: 'machineLearningApp', + displayName: i18n.translate('xpack.aiops.logRateAnalysis.cases.attachmentName', { + defaultMessage: 'Log rate analysis', + }), + getAttachmentViewObject: () => ({ + event: ( + + ), + timelineAvatar: 'machineLearningApp', + children: React.lazy(async () => { + const { initComponent } = await import('./log_rate_analysis_attachment'); + + return { + default: initComponent( + pluginStart.fieldFormats, + LogRateAnalysisEmbeddableWrapperComponent + ), + }; + }), + }), + getAttachmentRemovalObject: () => ({ + event: ( + + ), + }), }); } diff --git a/x-pack/plugins/aiops/public/components/document_count_content/document_count_content/document_count_content.tsx b/x-pack/plugins/aiops/public/components/document_count_content/document_count_content/document_count_content.tsx index 9f4f6f1deb5bd..b56493cf03bdb 100644 --- a/x-pack/plugins/aiops/public/components/document_count_content/document_count_content/document_count_content.tsx +++ b/x-pack/plugins/aiops/public/components/document_count_content/document_count_content/document_count_content.tsx @@ -45,19 +45,25 @@ export const DocumentCountContent: FC = ({ const { documentStats } = useAppSelector((s) => s.logRateAnalysis); const { sampleProbability, totalCount, documentCountStats } = documentStats; + const isCasesEmbedding = embeddingOrigin === AIOPS_EMBEDDABLE_ORIGIN.CASES; + + const isEmbeddedInDashboardOrCases = + embeddingOrigin === AIOPS_EMBEDDABLE_ORIGIN.DASHBOARD || isCasesEmbedding; + if (documentCountStats === undefined) { - return totalCount !== undefined && embeddingOrigin !== AIOPS_EMBEDDABLE_ORIGIN.DASHBOARD ? ( + return totalCount !== undefined && !isEmbeddedInDashboardOrCases ? ( ) : null; } - if (embeddingOrigin === AIOPS_EMBEDDABLE_ORIGIN.DASHBOARD) { + if (isEmbeddedInDashboardOrCases) { return ( ); diff --git a/x-pack/plugins/aiops/public/components/log_categorization/log_categorization_for_embeddable/log_categorization_for_discover.tsx b/x-pack/plugins/aiops/public/components/log_categorization/log_categorization_for_embeddable/log_categorization_for_discover.tsx index 5bf415c5ccfc9..f4c25eafa5da4 100644 --- a/x-pack/plugins/aiops/public/components/log_categorization/log_categorization_for_embeddable/log_categorization_for_discover.tsx +++ b/x-pack/plugins/aiops/public/components/log_categorization/log_categorization_for_embeddable/log_categorization_for_discover.tsx @@ -401,9 +401,6 @@ export const LogCategorizationDiscover: FC = ( ); const style = css({ overflowY: 'auto', - '.kbnDocTableWrapper': { - overflowX: 'hidden', - }, }); const actions = getActions(false); diff --git a/x-pack/plugins/aiops/public/components/log_rate_analysis/log_rate_analysis_app_state.tsx b/x-pack/plugins/aiops/public/components/log_rate_analysis/log_rate_analysis_app_state.tsx index 89a8c9aee19ae..0c0880ec3987e 100644 --- a/x-pack/plugins/aiops/public/components/log_rate_analysis/log_rate_analysis_app_state.tsx +++ b/x-pack/plugins/aiops/public/components/log_rate_analysis/log_rate_analysis_app_state.tsx @@ -25,6 +25,7 @@ import { AIOPS_STORAGE_KEYS } from '../../types/storage'; import { LogRateAnalysisPage } from './log_rate_analysis_page'; import { timeSeriesDataViewWarning } from '../../application/utils/time_series_dataview_check'; +import { FilterQueryContextProvider } from '../../hooks/use_filters_query'; const localStorage = new Storage(window.localStorage); @@ -58,6 +59,8 @@ export const LogRateAnalysisAppState: FC = ({ if (warning !== null) { return <>{warning}; } + const CasesContext = appContextValue.cases?.ui.getCasesContext() ?? React.Fragment; + const casesPermissions = appContextValue.cases?.helpers.canUseCases(); const datePickerDeps: DatePickerDependencies = { ...pick(appContextValue, ['data', 'http', 'notifications', 'theme', 'uiSettings', 'i18n']), @@ -67,17 +70,21 @@ export const LogRateAnalysisAppState: FC = ({ return ( - - - - - - - - - - - + + + + + + + + + + + + + + + ); }; diff --git a/x-pack/plugins/aiops/public/components/log_rate_analysis/log_rate_analysis_content/log_rate_analysis_attachments_menu.tsx b/x-pack/plugins/aiops/public/components/log_rate_analysis/log_rate_analysis_content/log_rate_analysis_attachments_menu.tsx index c8c9bad1568a4..d7e68ae42799c 100644 --- a/x-pack/plugins/aiops/public/components/log_rate_analysis/log_rate_analysis_content/log_rate_analysis_attachments_menu.tsx +++ b/x-pack/plugins/aiops/public/components/log_rate_analysis/log_rate_analysis_content/log_rate_analysis_attachments_menu.tsx @@ -26,15 +26,29 @@ import { EuiSpacer, EuiSwitch, } from '@elastic/eui'; +import type { WindowParameters } from '@kbn/aiops-log-rate-analysis/window_parameters'; +import type { SignificantItem } from '@kbn/ml-agg-utils'; +import { useCasesModal } from '../../../hooks/use_cases_modal'; import { useDataSource } from '../../../hooks/use_data_source'; import type { LogRateAnalysisEmbeddableState } from '../../../embeddables/log_rate_analysis/types'; import { useAiopsAppContext } from '../../../hooks/use_aiops_app_context'; const SavedObjectSaveModalDashboard = withSuspense(LazySavedObjectSaveModalDashboard); -export const LogRateAnalysisAttachmentsMenu = () => { +interface LogRateAnalysisAttachmentsMenuProps { + windowParameters?: WindowParameters; + showLogRateAnalysisResults: boolean; + significantItems: SignificantItem[]; +} + +export const LogRateAnalysisAttachmentsMenu = ({ + windowParameters, + showLogRateAnalysisResults, + significantItems, +}: LogRateAnalysisAttachmentsMenuProps) => { const { application: { capabilities }, + cases, embeddable, } = useAiopsAppContext(); const { dataView } = useDataSource(); @@ -44,9 +58,19 @@ export const LogRateAnalysisAttachmentsMenu = () => { const [dashboardAttachmentReady, setDashboardAttachmentReady] = useState(false); const timeRange = useTimeRangeUpdates(); + const absoluteTimeRange = useTimeRangeUpdates(true); + + const openCasesModalCallback = useCasesModal(EMBEDDABLE_LOG_RATE_ANALYSIS_TYPE); const canEditDashboards = capabilities.dashboard.createNew; + const { create: canCreateCase, update: canUpdateCase } = cases?.helpers?.canUseCases() ?? { + create: false, + update: false, + }; + + const isCasesAttachmentEnabled = showLogRateAnalysisResults && significantItems.length > 0; + const onSave: SaveModalDashboardProps['onSave'] = useCallback( ({ dashboardId, newTitle, newDescription }) => { const stateTransfer = embeddable!.getStateTransfer(); @@ -71,6 +95,19 @@ export const LogRateAnalysisAttachmentsMenu = () => { [dataView.id, embeddable, applyTimeRange, timeRange] ); + const caseAttachmentTooltipContent = useMemo(() => { + if (!showLogRateAnalysisResults) { + return i18n.translate('xpack.aiops.logRateAnalysis.attachToCaseTooltipNoAnalysis', { + defaultMessage: 'Run the analysis first to add results to a case.', + }); + } + if (significantItems.length === 0) { + return i18n.translate('xpack.aiops.logRateAnalysis.attachToCaseTooltipNoResults', { + defaultMessage: 'Cannot add to case because the analysis did not produce any results.', + }); + } + }, [showLogRateAnalysisResults, significantItems.length]); + const panels = useMemo>(() => { return [ { @@ -88,6 +125,31 @@ export const LogRateAnalysisAttachmentsMenu = () => { }, ] : []), + ...(canUpdateCase || canCreateCase + ? [ + { + name: i18n.translate('xpack.aiops.logRateAnalysis.attachToCaseLabel', { + defaultMessage: 'Add to case', + }), + 'data-test-subj': 'aiopsLogRateAnalysisAttachToCaseButton', + disabled: !isCasesAttachmentEnabled, + ...(!isCasesAttachmentEnabled + ? { + toolTipProps: { position: 'left' as const }, + toolTipContent: caseAttachmentTooltipContent, + } + : {}), + onClick: () => { + setIsActionMenuOpen(false); + openCasesModalCallback({ + dataViewId: dataView.id, + timeRange: absoluteTimeRange, + ...(windowParameters && { windowParameters }), + }); + }, + }, + ] + : []), ], }, { @@ -131,7 +193,18 @@ export const LogRateAnalysisAttachmentsMenu = () => { ), }, ]; - }, [canEditDashboards, applyTimeRange]); + }, [ + canEditDashboards, + canUpdateCase, + canCreateCase, + isCasesAttachmentEnabled, + caseAttachmentTooltipContent, + applyTimeRange, + openCasesModalCallback, + dataView.id, + absoluteTimeRange, + windowParameters, + ]); return ( <> diff --git a/x-pack/plugins/aiops/public/components/log_rate_analysis/log_rate_analysis_content/log_rate_analysis_content.tsx b/x-pack/plugins/aiops/public/components/log_rate_analysis/log_rate_analysis_content/log_rate_analysis_content.tsx index 29ac8d0efffc8..fb3c17634fd31 100644 --- a/x-pack/plugins/aiops/public/components/log_rate_analysis/log_rate_analysis_content/log_rate_analysis_content.tsx +++ b/x-pack/plugins/aiops/public/components/log_rate_analysis/log_rate_analysis_content/log_rate_analysis_content.tsx @@ -217,7 +217,13 @@ export const LogRateAnalysisContent: FC = ({ barColorOverride={barColorOverride} barHighlightColorOverride={barHighlightColorOverride} barStyleAccessor={barStyleAccessor} - attachmentsMenu={} + attachmentsMenu={ + + } /> )} diff --git a/x-pack/plugins/aiops/public/components/log_rate_analysis/log_rate_analysis_results.tsx b/x-pack/plugins/aiops/public/components/log_rate_analysis/log_rate_analysis_results.tsx index 1eb4f8fd0af0d..42fa509e6ce40 100644 --- a/x-pack/plugins/aiops/public/components/log_rate_analysis/log_rate_analysis_results.tsx +++ b/x-pack/plugins/aiops/public/components/log_rate_analysis/log_rate_analysis_results.tsx @@ -333,6 +333,8 @@ export const LogRateAnalysisResults: FC = ({ }, 0); const foundGroups = groupTableItems.length > 0 && groupItemCount > 0; + const isAnalysisControlsDisabled = embeddingOrigin === AIOPS_EMBEDDABLE_ORIGIN.CASES; + return (
        = ({ onReset={onReset} shouldRerunAnalysis={shouldRerunAnalysis || searchQueryUpdated} analysisInfo={} + isAnalysisControlsDisabled={isAnalysisControlsDisabled} > <> {embeddingOrigin !== AIOPS_EMBEDDABLE_ORIGIN.DASHBOARD && ( diff --git a/x-pack/plugins/aiops/public/components/log_rate_analysis_results_table/use_view_in_discover_action.tsx b/x-pack/plugins/aiops/public/components/log_rate_analysis_results_table/use_view_in_discover_action.tsx index 765f1435a93ad..a9a030ecd16b8 100644 --- a/x-pack/plugins/aiops/public/components/log_rate_analysis_results_table/use_view_in_discover_action.tsx +++ b/x-pack/plugins/aiops/public/components/log_rate_analysis_results_table/use_view_in_discover_action.tsx @@ -16,6 +16,7 @@ import { useAiopsAppContext } from '../../hooks/use_aiops_app_context'; import { TableActionButton } from './table_action_button'; import { getTableItemAsKQL } from './get_table_item_as_kql'; +import { useFilterQueryUpdates } from '../../hooks/use_filters_query'; const viewInDiscoverMessage = i18n.translate( 'xpack.aiops.logRateAnalysis.resultsTable.linksMenu.viewInDiscover', @@ -32,6 +33,10 @@ export const useViewInDiscoverAction = (dataViewId?: string): TableItemAction => [share?.url.locators] ); + // We cannot rely on the time range from AiOps App context because it is not always in sync with the time range used for analysis. + // E.g. In the case of an embeddable inside cases, the time range is fixed and not coming from the time picker. + const { timeRange } = useFilterQueryUpdates(); + const discoverUrlError = useMemo(() => { if (!application.capabilities.discover?.show) { const discoverNotEnabled = i18n.translate( @@ -69,7 +74,7 @@ export const useViewInDiscoverAction = (dataViewId?: string): TableItemAction => if (discoverLocator !== undefined) { const url = await discoverLocator.getRedirectUrl({ indexPatternId: dataViewId, - timeRange: data.query.timefilter.timefilter.getTime(), + timeRange, filters: data.query.filterManager.getFilters(), query: { language: SEARCH_QUERY_LANGUAGE.KUERY, diff --git a/x-pack/plugins/aiops/public/components/log_rate_analysis_results_table/use_view_in_log_pattern_analysis_action.tsx b/x-pack/plugins/aiops/public/components/log_rate_analysis_results_table/use_view_in_log_pattern_analysis_action.tsx index d92ce014d68fb..e96df8d140a14 100644 --- a/x-pack/plugins/aiops/public/components/log_rate_analysis_results_table/use_view_in_log_pattern_analysis_action.tsx +++ b/x-pack/plugins/aiops/public/components/log_rate_analysis_results_table/use_view_in_log_pattern_analysis_action.tsx @@ -18,6 +18,7 @@ import { useAiopsAppContext } from '../../hooks/use_aiops_app_context'; import { TableActionButton } from './table_action_button'; import { getTableItemAsKQL } from './get_table_item_as_kql'; +import { useFilterQueryUpdates } from '../../hooks/use_filters_query'; const isLogPattern = (tableItem: SignificantItem | GroupTableItem) => isSignificantItem(tableItem) && tableItem.type === SIGNIFICANT_ITEM_TYPE.LOG_PATTERN; @@ -34,6 +35,10 @@ export const useViewInLogPatternAnalysisAction = (dataViewId?: string): TableIte const mlLocator = useMemo(() => share?.url.locators.get('ML_APP_LOCATOR'), [share?.url.locators]); + // We cannot rely on the time range from AiOps App context because it is not always in sync with the time range used for analysis. + // E.g. In the case of an embeddable inside cases, the time range is fixed and not coming from the time picker. + const { timeRange } = useFilterQueryUpdates(); + const generateLogPatternAnalysisUrl = async ( groupTableItem: GroupTableItem | SignificantItem ) => { @@ -57,7 +62,9 @@ export const useViewInLogPatternAnalysisAction = (dataViewId?: string): TableIte page: 'aiops/log_categorization', pageState: { index: dataViewId, - timeRange: data.query.timefilter.timefilter.getTime(), + globalState: { + time: timeRange, + }, appState, }, }); diff --git a/x-pack/plugins/aiops/public/embeddables/log_rate_analysis/embeddable_log_rate_analysis_factory.tsx b/x-pack/plugins/aiops/public/embeddables/log_rate_analysis/embeddable_log_rate_analysis_factory.tsx index 592ec32cef120..6d1ea7d2e03c1 100644 --- a/x-pack/plugins/aiops/public/embeddables/log_rate_analysis/embeddable_log_rate_analysis_factory.tsx +++ b/x-pack/plugins/aiops/public/embeddables/log_rate_analysis/embeddable_log_rate_analysis_factory.tsx @@ -37,6 +37,8 @@ import type { LogRateAnalysisEmbeddableState, } from './types'; +export type EmbeddableLogRateAnalysisType = typeof EMBEDDABLE_LOG_RATE_ANALYSIS_TYPE; + export const getLogRateAnalysisEmbeddableFactory = ( getStartServices: StartServicesAccessor ) => { diff --git a/x-pack/plugins/aiops/public/embeddables/log_rate_analysis/initialize_log_rate_analysis_analysis_controls.ts b/x-pack/plugins/aiops/public/embeddables/log_rate_analysis/initialize_log_rate_analysis_analysis_controls.ts index 9d8a49b8f0e9c..d155546e28bf6 100644 --- a/x-pack/plugins/aiops/public/embeddables/log_rate_analysis/initialize_log_rate_analysis_analysis_controls.ts +++ b/x-pack/plugins/aiops/public/embeddables/log_rate_analysis/initialize_log_rate_analysis_analysis_controls.ts @@ -11,7 +11,7 @@ import type { LogRateAnalysisComponentApi, LogRateAnalysisEmbeddableState } from type LogRateAnalysisEmbeddableCustomState = Omit< LogRateAnalysisEmbeddableState, - 'timeRange' | 'title' | 'description' | 'hidePanelTitles' + 'timeRange' | 'title' | 'description' | 'hidePanelTitles' | 'windowParameters' >; export const initializeLogRateAnalysisControls = (rawState: LogRateAnalysisEmbeddableState) => { diff --git a/x-pack/plugins/aiops/public/embeddables/log_rate_analysis/types.ts b/x-pack/plugins/aiops/public/embeddables/log_rate_analysis/types.ts index d2255e6dacb87..28a68cecd36f3 100644 --- a/x-pack/plugins/aiops/public/embeddables/log_rate_analysis/types.ts +++ b/x-pack/plugins/aiops/public/embeddables/log_rate_analysis/types.ts @@ -5,6 +5,7 @@ * 2.0. */ +import type { WindowParameters } from '@kbn/aiops-log-rate-analysis'; import type { DefaultEmbeddableApi } from '@kbn/embeddable-plugin/public'; import type { HasEditCapabilities, @@ -28,6 +29,7 @@ export type LogRateAnalysisEmbeddableApi = DefaultEmbeddableApi; diff --git a/x-pack/plugins/aiops/public/hooks/use_cases_modal.ts b/x-pack/plugins/aiops/public/hooks/use_cases_modal.ts index 8ec73a21f9bbd..745506a0a1ae2 100644 --- a/x-pack/plugins/aiops/public/hooks/use_cases_modal.ts +++ b/x-pack/plugins/aiops/public/hooks/use_cases_modal.ts @@ -13,14 +13,21 @@ import type { EmbeddableChangePointChartType } from '../embeddables/change_point import { useAiopsAppContext } from './use_aiops_app_context'; import type { EmbeddablePatternAnalysisType } from '../embeddables/pattern_analysis/embeddable_pattern_analysis_factory'; import type { PatternAnalysisEmbeddableRuntimeState } from '../embeddables/pattern_analysis/types'; +import type { EmbeddableLogRateAnalysisType } from '../embeddables/log_rate_analysis/embeddable_log_rate_analysis_factory'; +import type { LogRateAnalysisEmbeddableRuntimeState } from '../embeddables/log_rate_analysis/types'; -type SupportedEmbeddableTypes = EmbeddableChangePointChartType | EmbeddablePatternAnalysisType; +type SupportedEmbeddableTypes = + | EmbeddableChangePointChartType + | EmbeddablePatternAnalysisType + | EmbeddableLogRateAnalysisType; type EmbeddableRuntimeState = T extends EmbeddableChangePointChartType ? ChangePointEmbeddableRuntimeState : T extends EmbeddablePatternAnalysisType ? PatternAnalysisEmbeddableRuntimeState + : T extends EmbeddableLogRateAnalysisType + ? LogRateAnalysisEmbeddableRuntimeState : never; /** diff --git a/x-pack/plugins/aiops/public/shared_components/log_rate_analysis_embeddable_wrapper.tsx b/x-pack/plugins/aiops/public/shared_components/log_rate_analysis_embeddable_wrapper.tsx index 9f2a88e73461c..f08f4f0e68bd9 100644 --- a/x-pack/plugins/aiops/public/shared_components/log_rate_analysis_embeddable_wrapper.tsx +++ b/x-pack/plugins/aiops/public/shared_components/log_rate_analysis_embeddable_wrapper.tsx @@ -10,10 +10,7 @@ import React, { useEffect, useMemo, useState, type FC } from 'react'; import usePrevious from 'react-use/lib/usePrevious'; import type { Observable } from 'rxjs'; import { BehaviorSubject, combineLatest, distinctUntilChanged, map } from 'rxjs'; -import { createBrowserHistory } from 'history'; -import { UrlStateProvider } from '@kbn/ml-url-state'; -import { Router } from '@kbn/shared-ux-router'; import { AIOPS_EMBEDDABLE_ORIGIN } from '@kbn/aiops-common/constants'; import type { CoreStart } from '@kbn/core-lifecycle-browser'; import { UI_SETTINGS } from '@kbn/data-service'; @@ -22,6 +19,7 @@ import type { TimeRange } from '@kbn/es-query'; import { DatePickerContextProvider } from '@kbn/ml-date-picker'; import type { SignificantItem } from '@kbn/ml-agg-utils'; +import type { WindowParameters } from '@kbn/aiops-log-rate-analysis'; import { AiopsAppContext, type AiopsAppContextValue } from '../hooks/use_aiops_app_context'; import { DataSourceContextProvider } from '../hooks/use_data_source'; import { ReloadContextProvider } from '../hooks/use_reload'; @@ -60,6 +58,7 @@ export interface LogRateAnalysisEmbeddableWrapperProps { onLoading: (isLoading: boolean) => void; onRenderComplete: () => void; onError: (error: Error) => void; + windowParameters?: WindowParameters; } const LogRateAnalysisEmbeddableWrapperWithDeps: FC = ({ @@ -71,6 +70,7 @@ const LogRateAnalysisEmbeddableWrapperWithDeps: FC timeRange, embeddingOrigin, lastReloadRequestTime, + windowParameters, }) => { const deps = useMemo(() => { const { lens, data, usageCollection, fieldFormats, charts, share, storage, unifiedSearch } = @@ -120,8 +120,6 @@ const LogRateAnalysisEmbeddableWrapperWithDeps: FC ); }, [manualReload$]); - const history = createBrowserHistory(); - // We use the following pattern to track changes of dataViewId, and if there's // a change, we unmount and remount the complete inner component. This makes // sure the component is reinitialized correctly when the options of the @@ -150,26 +148,22 @@ const LogRateAnalysisEmbeddableWrapperWithDeps: FC }} > {showComponent && ( - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + )}
        ); diff --git a/x-pack/plugins/aiops/server/register_cases.ts b/x-pack/plugins/aiops/server/register_cases.ts index 5649c88ca6327..ac126a74a5a21 100644 --- a/x-pack/plugins/aiops/server/register_cases.ts +++ b/x-pack/plugins/aiops/server/register_cases.ts @@ -9,6 +9,7 @@ import type { Logger } from '@kbn/core/server'; import type { CasesServerSetup } from '@kbn/cases-plugin/server'; import { CASES_ATTACHMENT_CHANGE_POINT_CHART } from '@kbn/aiops-change-point-detection/constants'; import { CASES_ATTACHMENT_LOG_PATTERN } from '@kbn/aiops-log-pattern-analysis/constants'; +import { CASES_ATTACHMENT_LOG_RATE_ANALYSIS } from '@kbn/aiops-log-rate-analysis/constants'; export function registerCasesPersistableState(cases: CasesServerSetup | undefined, logger: Logger) { if (cases) { @@ -19,6 +20,9 @@ export function registerCasesPersistableState(cases: CasesServerSetup | undefine cases.attachmentFramework.registerPersistableState({ id: CASES_ATTACHMENT_LOG_PATTERN, }); + cases.attachmentFramework.registerPersistableState({ + id: CASES_ATTACHMENT_LOG_RATE_ANALYSIS, + }); } catch (error) { logger.warn(`AIOPs failed to register cases persistable state`); } diff --git a/x-pack/plugins/aiops/tsconfig.json b/x-pack/plugins/aiops/tsconfig.json index 234420f01c52f..7b4b8493e1ab8 100644 --- a/x-pack/plugins/aiops/tsconfig.json +++ b/x-pack/plugins/aiops/tsconfig.json @@ -78,7 +78,6 @@ "@kbn/ui-theme", "@kbn/apm-utils", "@kbn/ml-field-stats-flyout", - "@kbn/shared-ux-router", ], "exclude": [ "target/**/*", diff --git a/x-pack/plugins/alerting/common/routes/rule/apis/aggregate/schemas/v1.ts b/x-pack/plugins/alerting/common/routes/rule/apis/aggregate/schemas/v1.ts index 95f07bf3f7bda..57a9499779add 100644 --- a/x-pack/plugins/alerting/common/routes/rule/apis/aggregate/schemas/v1.ts +++ b/x-pack/plugins/alerting/common/routes/rule/apis/aggregate/schemas/v1.ts @@ -24,7 +24,8 @@ export const aggregateRulesRequestBodySchema = schema.object({ ) ), filter: schema.maybe(schema.string()), - filter_consumers: schema.maybe(schema.arrayOf(schema.string())), + rule_type_ids: schema.maybe(schema.arrayOf(schema.string())), + consumers: schema.maybe(schema.arrayOf(schema.string())), }); export const aggregateRulesResponseBodySchema = schema.object({ diff --git a/x-pack/plugins/alerting/common/routes/rule/apis/bulk_untrack_by_query/schemas/v1.ts b/x-pack/plugins/alerting/common/routes/rule/apis/bulk_untrack_by_query/schemas/v1.ts index 62cc67360b162..26e5283cede13 100644 --- a/x-pack/plugins/alerting/common/routes/rule/apis/bulk_untrack_by_query/schemas/v1.ts +++ b/x-pack/plugins/alerting/common/routes/rule/apis/bulk_untrack_by_query/schemas/v1.ts @@ -9,5 +9,5 @@ import { schema } from '@kbn/config-schema'; export const bulkUntrackByQueryBodySchema = schema.object({ query: schema.arrayOf(schema.any()), - feature_ids: schema.arrayOf(schema.string()), + rule_type_ids: schema.arrayOf(schema.string()), }); diff --git a/x-pack/plugins/alerting/common/routes/rule/apis/find/index.ts b/x-pack/plugins/alerting/common/routes/rule/apis/find/index.ts index 7722521d2b707..b8ebef499e7e0 100644 --- a/x-pack/plugins/alerting/common/routes/rule/apis/find/index.ts +++ b/x-pack/plugins/alerting/common/routes/rule/apis/find/index.ts @@ -8,8 +8,13 @@ export { findRulesRequestQuerySchema } from './schemas/latest'; export type { FindRulesRequestQuery, FindRulesResponse } from './types/latest'; -export { findRulesRequestQuerySchema as findRulesRequestQuerySchemaV1 } from './schemas/v1'; +export { + findRulesRequestQuerySchema as findRulesRequestQuerySchemaV1, + findRulesInternalRequestBodySchema as findRulesInternalRequestBodySchemaV1, +} from './schemas/v1'; + export type { FindRulesRequestQuery as FindRulesRequestQueryV1, + FindRulesInternalRequestBody as FindRulesInternalRequestBodyV1, FindRulesResponse as FindRulesResponseV1, } from './types/latest'; diff --git a/x-pack/plugins/alerting/common/routes/rule/apis/find/schemas/v1.ts b/x-pack/plugins/alerting/common/routes/rule/apis/find/schemas/v1.ts index 1dece949a9556..06ebfdbacc54d 100644 --- a/x-pack/plugins/alerting/common/routes/rule/apis/find/schemas/v1.ts +++ b/x-pack/plugins/alerting/common/routes/rule/apis/find/schemas/v1.ts @@ -103,3 +103,35 @@ export const findRulesRequestQuerySchema = schema.object({ ) ), }); + +export const findRulesInternalRequestBodySchema = schema.object({ + per_page: schema.number({ + defaultValue: 10, + min: 0, + }), + page: schema.number({ + defaultValue: 1, + min: 1, + }), + search: schema.maybe(schema.string()), + default_search_operator: schema.oneOf([schema.literal('OR'), schema.literal('AND')], { + defaultValue: 'OR', + }), + search_fields: schema.maybe(schema.oneOf([schema.arrayOf(schema.string()), schema.string()])), + sort_field: schema.maybe(schema.string()), + sort_order: schema.maybe(schema.oneOf([schema.literal('asc'), schema.literal('desc')])), + has_reference: schema.maybe( + // use nullable as maybe is currently broken + // in config-schema + schema.nullable( + schema.object({ + type: schema.string(), + id: schema.string(), + }) + ) + ), + fields: schema.maybe(schema.arrayOf(schema.string())), + filter: schema.maybe(schema.string()), + rule_type_ids: schema.maybe(schema.arrayOf(schema.string())), + consumers: schema.maybe(schema.arrayOf(schema.string())), +}); diff --git a/x-pack/plugins/alerting/common/routes/rule/apis/find/types/v1.ts b/x-pack/plugins/alerting/common/routes/rule/apis/find/types/v1.ts index 271e791282f43..e09b4871eabc9 100644 --- a/x-pack/plugins/alerting/common/routes/rule/apis/find/types/v1.ts +++ b/x-pack/plugins/alerting/common/routes/rule/apis/find/types/v1.ts @@ -7,9 +7,10 @@ import type { TypeOf } from '@kbn/config-schema'; import { RuleParamsV1, RuleResponseV1 } from '../../../response'; -import { findRulesRequestQuerySchemaV1 } from '..'; +import { findRulesRequestQuerySchemaV1, findRulesInternalRequestBodySchemaV1 } from '..'; export type FindRulesRequestQuery = TypeOf; +export type FindRulesInternalRequestBody = TypeOf; export interface FindRulesResponse { body: { diff --git a/x-pack/plugins/alerting/public/pages/maintenance_windows/components/create_maintenance_windows_form.tsx b/x-pack/plugins/alerting/public/pages/maintenance_windows/components/create_maintenance_windows_form.tsx index 7f3c25eeaf55d..04bab61eb5c6f 100644 --- a/x-pack/plugins/alerting/public/pages/maintenance_windows/components/create_maintenance_windows_form.tsx +++ b/x-pack/plugins/alerting/public/pages/maintenance_windows/components/create_maintenance_windows_form.tsx @@ -31,7 +31,6 @@ import { } from '@elastic/eui'; import { TIMEZONE_OPTIONS as UI_TIMEZONE_OPTIONS } from '@kbn/core-ui-settings-common'; import { DEFAULT_APP_CATEGORIES } from '@kbn/core-application-common'; -import type { ValidFeatureId } from '@kbn/rule-data-utils'; import type { Filter } from '@kbn/es-query'; import type { IHttpFetchError } from '@kbn/core-http-browser'; import type { KibanaServerError } from '@kbn/kibana-utils-plugin/public'; @@ -73,7 +72,10 @@ const useDefaultTimezone = () => { } return { defaultTimezone: kibanaTz, isBrowser: false }; }; -const TIMEZONE_OPTIONS = UI_TIMEZONE_OPTIONS.map((n) => ({ label: n })) ?? [{ label: 'UTC' }]; + +const TIMEZONE_OPTIONS = UI_TIMEZONE_OPTIONS.map((timezoneOption) => ({ + label: timezoneOption, +})) ?? [{ label: 'UTC' }]; export const CreateMaintenanceWindowForm = React.memo((props) => { const { onCancel, onSuccess, initialValue, maintenanceWindowId } = props; @@ -203,6 +205,7 @@ export const CreateMaintenanceWindowForm = React.memo ruleType.category))]; }, [validRuleTypes]); - const featureIds = useMemo(() => { + const ruleTypeIds = useMemo(() => { if (!Array.isArray(validRuleTypes) || !Array.isArray(categoryIds) || !mounted) { return []; } - const featureIdsSet = new Set(); + const uniqueRuleTypeIds = new Set(); validRuleTypes.forEach((ruleType) => { if (categoryIds.includes(ruleType.category)) { - featureIdsSet.add(ruleType.producer as ValidFeatureId); + uniqueRuleTypeIds.add(ruleType.id); } }); - return [...featureIdsSet]; + return [...uniqueRuleTypeIds]; }, [validRuleTypes, categoryIds, mounted]); const onCategoryIdsChange = useCallback( @@ -476,7 +479,7 @@ export const CreateMaintenanceWindowForm = React.memo {() => ( { it('renders correctly', () => { appMockRenderer.render( { it('should hide the search bar if isEnabled is false', () => { appMockRenderer.render( { it('should render loading if isLoading is true', () => { appMockRenderer.render( { const { - featureIds, + ruleTypeIds, query, filters, errors = [], @@ -76,7 +75,7 @@ export const MaintenanceWindowScopedQuery = React.memo( { + const features = featuresPluginMock.createStart(); + const securityPluginStart = securityMock.createStart(); + const alertingAuthorizationClientFactoryParams: jest.Mocked = + { + ruleTypeRegistry: ruleTypeRegistryMock.create(), + getSpace: jest.fn(), + getSpaceId: jest.fn(), + features, + }; -const securityPluginSetup = securityMock.createSetup(); -const securityPluginStart = securityMock.createStart(); + beforeEach(() => { + jest.clearAllMocks(); + }); -const alertingAuthorizationClientFactoryParams: jest.Mocked = - { - ruleTypeRegistry: ruleTypeRegistryMock.create(), - getSpace: jest.fn(), - getSpaceId: jest.fn(), - features, - }; + it('creates an alerting authorization client with proper constructor arguments when security is enabled', async () => { + const factory = new AlertingAuthorizationClientFactory(); -beforeEach(() => { - jest.resetAllMocks(); -}); + factory.initialize({ + securityPluginStart, + ...alertingAuthorizationClientFactoryParams, + }); + + const request = mockRouter.createKibanaRequest(); + + await factory.create(request); -test('creates an alerting authorization client with proper constructor arguments when security is enabled', async () => { - const factory = new AlertingAuthorizationClientFactory(); - factory.initialize({ - securityPluginSetup, - securityPluginStart, - ...alertingAuthorizationClientFactoryParams, + const { AlertingAuthorization } = jest.requireMock('./authorization/alerting_authorization'); + expect(AlertingAuthorization.create).toHaveBeenCalledWith({ + request, + authorization: securityPluginStart.authz, + ruleTypeRegistry: alertingAuthorizationClientFactoryParams.ruleTypeRegistry, + features: alertingAuthorizationClientFactoryParams.features, + getSpace: expect.any(Function), + getSpaceId: expect.any(Function), + }); }); - const request = mockRouter.createKibanaRequest(); - factory.create(request); + it('creates an alerting authorization client with proper constructor arguments', async () => { + const factory = new AlertingAuthorizationClientFactory(); + factory.initialize(alertingAuthorizationClientFactoryParams); + const request = mockRouter.createKibanaRequest(); - const { AlertingAuthorization } = jest.requireMock('./authorization/alerting_authorization'); - expect(AlertingAuthorization).toHaveBeenCalledWith({ - request, - authorization: securityPluginStart.authz, - ruleTypeRegistry: alertingAuthorizationClientFactoryParams.ruleTypeRegistry, - features: alertingAuthorizationClientFactoryParams.features, - getSpace: expect.any(Function), - getSpaceId: expect.any(Function), + await factory.create(request); + + const { AlertingAuthorization } = jest.requireMock('./authorization/alerting_authorization'); + expect(AlertingAuthorization.create).toHaveBeenCalledWith({ + request, + ruleTypeRegistry: alertingAuthorizationClientFactoryParams.ruleTypeRegistry, + features: alertingAuthorizationClientFactoryParams.features, + getSpace: expect.any(Function), + getSpaceId: expect.any(Function), + }); }); -}); -test('creates an alerting authorization client with proper constructor arguments', async () => { - const factory = new AlertingAuthorizationClientFactory(); - factory.initialize(alertingAuthorizationClientFactoryParams); - const request = mockRouter.createKibanaRequest(); + it('throws when trying to initialize again and it is already initialized', async () => { + const factory = new AlertingAuthorizationClientFactory(); + factory.initialize(alertingAuthorizationClientFactoryParams); + + expect(() => + factory.initialize(alertingAuthorizationClientFactoryParams) + ).toThrowErrorMatchingInlineSnapshot( + `"AlertingAuthorizationClientFactory already initialized"` + ); + }); - factory.create(request); + it('throws when trying to create an instance and the factory is not initialized', async () => { + const request = mockRouter.createKibanaRequest(); + const factory = new AlertingAuthorizationClientFactory(); - const { AlertingAuthorization } = jest.requireMock('./authorization/alerting_authorization'); - expect(AlertingAuthorization).toHaveBeenCalledWith({ - request, - ruleTypeRegistry: alertingAuthorizationClientFactoryParams.ruleTypeRegistry, - features: alertingAuthorizationClientFactoryParams.features, - getSpace: expect.any(Function), - getSpaceId: expect.any(Function), + await expect(() => factory.create(request)).rejects.toThrowErrorMatchingInlineSnapshot( + `"AlertingAuthorizationClientFactory must be initialized before calling create"` + ); }); }); diff --git a/x-pack/plugins/alerting/server/alerting_authorization_client_factory.ts b/x-pack/plugins/alerting/server/alerting_authorization_client_factory.ts index ca366a6cee0e4..8c5a772501f2b 100644 --- a/x-pack/plugins/alerting/server/alerting_authorization_client_factory.ts +++ b/x-pack/plugins/alerting/server/alerting_authorization_client_factory.ts @@ -6,7 +6,7 @@ */ import { KibanaRequest } from '@kbn/core/server'; -import { SecurityPluginSetup, SecurityPluginStart } from '@kbn/security-plugin/server'; +import { SecurityPluginStart } from '@kbn/security-plugin/server'; import { FeaturesPluginStart } from '@kbn/features-plugin/server'; import { Space } from '@kbn/spaces-plugin/server'; import { AlertingAuthorization } from './authorization/alerting_authorization'; @@ -14,7 +14,6 @@ import { RuleTypeRegistry } from './types'; export interface AlertingAuthorizationClientFactoryOpts { ruleTypeRegistry: RuleTypeRegistry; - securityPluginSetup?: SecurityPluginSetup; securityPluginStart?: SecurityPluginStart; getSpace: (request: KibanaRequest) => Promise; getSpaceId: (request: KibanaRequest) => string; @@ -23,33 +22,39 @@ export interface AlertingAuthorizationClientFactoryOpts { export class AlertingAuthorizationClientFactory { private isInitialized = false; - private ruleTypeRegistry!: RuleTypeRegistry; - private securityPluginStart?: SecurityPluginStart; - private features!: FeaturesPluginStart; - private getSpace!: (request: KibanaRequest) => Promise; - private getSpaceId!: (request: KibanaRequest) => string; + // The reason this is protected is because we'll get type collisions otherwise because we're using a type guard assert + // to ensure the options member is instantiated before using it in various places + // See for more info: https://stackoverflow.com/questions/66206180/typescript-typeguard-attribut-with-method + protected options?: AlertingAuthorizationClientFactoryOpts; public initialize(options: AlertingAuthorizationClientFactoryOpts) { if (this.isInitialized) { throw new Error('AlertingAuthorizationClientFactory already initialized'); } this.isInitialized = true; - this.getSpace = options.getSpace; - this.ruleTypeRegistry = options.ruleTypeRegistry; - this.securityPluginStart = options.securityPluginStart; - this.features = options.features; - this.getSpaceId = options.getSpaceId; + this.options = options; } - public create(request: KibanaRequest): AlertingAuthorization { - const { securityPluginStart, features } = this; - return new AlertingAuthorization({ - authorization: securityPluginStart?.authz, + public async create(request: KibanaRequest): Promise { + this.validateInitialization(); + + return AlertingAuthorization.create({ + authorization: this.options.securityPluginStart?.authz, request, - getSpace: this.getSpace, - getSpaceId: this.getSpaceId, - ruleTypeRegistry: this.ruleTypeRegistry, - features: features!, + getSpace: this.options.getSpace, + getSpaceId: this.options.getSpaceId, + ruleTypeRegistry: this.options.ruleTypeRegistry, + features: this.options.features, }); } + + private validateInitialization(): asserts this is this & { + options: AlertingAuthorizationClientFactoryOpts; + } { + if (!this.isInitialized || this.options == null) { + throw new Error( + 'AlertingAuthorizationClientFactory must be initialized before calling create' + ); + } + } } diff --git a/x-pack/plugins/alerting/server/alerts_service/lib/set_alerts_to_untracked.test.ts b/x-pack/plugins/alerting/server/alerts_service/lib/set_alerts_to_untracked.test.ts index 54376012aa767..003673f9fdb92 100644 --- a/x-pack/plugins/alerting/server/alerts_service/lib/set_alerts_to_untracked.test.ts +++ b/x-pack/plugins/alerting/server/alerts_service/lib/set_alerts_to_untracked.test.ts @@ -15,10 +15,8 @@ import { setAlertsToUntracked } from './set_alerts_to_untracked'; let clusterClient: ElasticsearchClientMock; let logger: ReturnType<(typeof loggingSystemMock)['createLogger']>; -const getAuthorizedRuleTypesMock = jest.fn(); - +const getAllAuthorizedRuleTypesFindOperationMock = jest.fn(); const getAlertIndicesAliasMock = jest.fn(); - const ensureAuthorizedMock = jest.fn(); describe('setAlertsToUntracked()', () => { @@ -362,11 +360,16 @@ describe('setAlertsToUntracked()', () => { }); test('should untrack by query', async () => { - getAuthorizedRuleTypesMock.mockResolvedValue([ - { - id: 'test-rule-type', - }, - ]); + getAllAuthorizedRuleTypesFindOperationMock.mockResolvedValue( + new Map([ + [ + 'test-rule-type', + { + id: 'test-rule-type', + }, + ], + ]) + ); getAlertIndicesAliasMock.mockResolvedValue(['test-alert-index']); clusterClient.search.mockResponseOnce({ @@ -441,9 +444,9 @@ describe('setAlertsToUntracked()', () => { }, }, ], - featureIds: ['o11y'], + ruleTypeIds: ['my-rule-type-id'], spaceId: 'default', - getAuthorizedRuleTypes: getAuthorizedRuleTypesMock, + getAllAuthorizedRuleTypesFindOperation: getAllAuthorizedRuleTypesFindOperationMock, getAlertIndicesAlias: getAlertIndicesAliasMock, ensureAuthorized: ensureAuthorizedMock, logger, @@ -527,11 +530,16 @@ describe('setAlertsToUntracked()', () => { }); test('should return an empty array if the search returns zero results', async () => { - getAuthorizedRuleTypesMock.mockResolvedValue([ - { - id: 'test-rule-type', - }, - ]); + getAllAuthorizedRuleTypesFindOperationMock.mockResolvedValue( + new Map([ + [ + 'test-rule-type', + { + id: 'test-rule-type', + }, + ], + ]) + ); getAlertIndicesAliasMock.mockResolvedValue(['test-alert-index']); clusterClient.search.mockResponseOnce({ @@ -575,9 +583,9 @@ describe('setAlertsToUntracked()', () => { }, }, ], - featureIds: ['o11y'], + ruleTypeIds: ['my-rule-type-id'], spaceId: 'default', - getAuthorizedRuleTypes: getAuthorizedRuleTypesMock, + getAllAuthorizedRuleTypesFindOperation: getAllAuthorizedRuleTypesFindOperationMock, getAlertIndicesAlias: getAlertIndicesAliasMock, ensureAuthorized: ensureAuthorizedMock, logger, diff --git a/x-pack/plugins/alerting/server/alerts_service/lib/set_alerts_to_untracked.ts b/x-pack/plugins/alerting/server/alerts_service/lib/set_alerts_to_untracked.ts index ed0c2cb21e06b..89c8d671de6a0 100644 --- a/x-pack/plugins/alerting/server/alerts_service/lib/set_alerts_to_untracked.ts +++ b/x-pack/plugins/alerting/server/alerts_service/lib/set_alerts_to_untracked.ts @@ -21,8 +21,8 @@ import { AlertStatus, } from '@kbn/rule-data-utils'; import type { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; -import { AlertingAuthorizationEntity } from '../../authorization/alerting_authorization'; import type { RulesClientContext } from '../../rules_client'; +import { AlertingAuthorizationEntity } from '../../authorization/types'; type EnsureAuthorized = (opts: { ruleTypeId: string; consumer: string }) => Promise; @@ -32,9 +32,9 @@ export interface SetAlertsToUntrackedParams { alertUuids?: string[]; query?: QueryDslQueryContainer[]; spaceId?: RulesClientContext['spaceId']; - featureIds?: string[]; + ruleTypeIds?: string[]; isUsingQuery?: boolean; - getAuthorizedRuleTypes?: RulesClientContext['authorization']['getAuthorizedRuleTypes']; + getAllAuthorizedRuleTypesFindOperation?: RulesClientContext['authorization']['getAllAuthorizedRuleTypesFindOperation']; getAlertIndicesAlias?: RulesClientContext['getAlertIndicesAlias']; ensureAuthorized?: EnsureAuthorized; } @@ -155,21 +155,26 @@ const ensureAuthorizedToUntrack = async (params: SetAlertsToUntrackedParamsWithD }; const getAuthorizedAlertsIndices = async ({ - featureIds, - getAuthorizedRuleTypes, + ruleTypeIds, + getAllAuthorizedRuleTypesFindOperation, getAlertIndicesAlias, spaceId, logger, }: SetAlertsToUntrackedParamsWithDep) => { try { - const authorizedRuleTypes = - (await getAuthorizedRuleTypes?.(AlertingAuthorizationEntity.Alert, new Set(featureIds))) || - []; - const indices = getAlertIndicesAlias?.( - authorizedRuleTypes.map((art: { id: string }) => art.id), - spaceId - ); - return indices; + const authorizedRuleTypes = await getAllAuthorizedRuleTypesFindOperation?.({ + authorizationEntity: AlertingAuthorizationEntity.Alert, + ruleTypeIds, + }); + + if (authorizedRuleTypes) { + return getAlertIndicesAlias?.( + Array.from(authorizedRuleTypes.keys()).map((id) => id), + spaceId + ); + } + + return []; } catch (error) { const errMessage = `Failed to get authorized rule types to untrack alerts by query: ${error}`; logger.error(errMessage); diff --git a/x-pack/plugins/alerting/server/application/backfill/methods/find/find_backfill.test.ts b/x-pack/plugins/alerting/server/application/backfill/methods/find/find_backfill.test.ts index dab9d5f38f036..ade1a1f35b59e 100644 --- a/x-pack/plugins/alerting/server/application/backfill/methods/find/find_backfill.test.ts +++ b/x-pack/plugins/alerting/server/application/backfill/methods/find/find_backfill.test.ts @@ -241,12 +241,15 @@ describe('findBackfill()', () => { test('should successfully find backfill with no filter', async () => { const result = await rulesClient.findBackfill({ page: 1, perPage: 10 }); - expect(authorization.getFindAuthorizationFilter).toHaveBeenCalledWith('rule', { - fieldNames: { - consumer: 'ad_hoc_run_params.attributes.rule.consumer', - ruleTypeId: 'ad_hoc_run_params.attributes.rule.alertTypeId', + expect(authorization.getFindAuthorizationFilter).toHaveBeenCalledWith({ + authorizationEntity: 'rule', + filterOpts: { + fieldNames: { + consumer: 'ad_hoc_run_params.attributes.rule.consumer', + ruleTypeId: 'ad_hoc_run_params.attributes.rule.alertTypeId', + }, + type: 'kql', }, - type: 'kql', }); expect(unsecuredSavedObjectsClient.find).toHaveBeenCalledWith({ @@ -286,12 +289,15 @@ describe('findBackfill()', () => { test('should successfully find backfill with rule id', async () => { const result = await rulesClient.findBackfill({ page: 1, perPage: 10, ruleIds: 'abc' }); - expect(authorization.getFindAuthorizationFilter).toHaveBeenCalledWith('rule', { - fieldNames: { - consumer: 'ad_hoc_run_params.attributes.rule.consumer', - ruleTypeId: 'ad_hoc_run_params.attributes.rule.alertTypeId', + expect(authorization.getFindAuthorizationFilter).toHaveBeenCalledWith({ + authorizationEntity: 'rule', + filterOpts: { + fieldNames: { + consumer: 'ad_hoc_run_params.attributes.rule.consumer', + ruleTypeId: 'ad_hoc_run_params.attributes.rule.alertTypeId', + }, + type: 'kql', }, - type: 'kql', }); expect(unsecuredSavedObjectsClient.find).toHaveBeenCalledWith({ @@ -336,12 +342,15 @@ describe('findBackfill()', () => { start: '2024-03-29T02:07:55Z', }); - expect(authorization.getFindAuthorizationFilter).toHaveBeenCalledWith('rule', { - fieldNames: { - consumer: 'ad_hoc_run_params.attributes.rule.consumer', - ruleTypeId: 'ad_hoc_run_params.attributes.rule.alertTypeId', + expect(authorization.getFindAuthorizationFilter).toHaveBeenCalledWith({ + authorizationEntity: 'rule', + filterOpts: { + fieldNames: { + consumer: 'ad_hoc_run_params.attributes.rule.consumer', + ruleTypeId: 'ad_hoc_run_params.attributes.rule.alertTypeId', + }, + type: 'kql', }, - type: 'kql', }); expect(unsecuredSavedObjectsClient.find).toHaveBeenCalledWith({ @@ -400,12 +409,15 @@ describe('findBackfill()', () => { end: '2024-03-29T02:07:55Z', }); - expect(authorization.getFindAuthorizationFilter).toHaveBeenCalledWith('rule', { - fieldNames: { - consumer: 'ad_hoc_run_params.attributes.rule.consumer', - ruleTypeId: 'ad_hoc_run_params.attributes.rule.alertTypeId', + expect(authorization.getFindAuthorizationFilter).toHaveBeenCalledWith({ + authorizationEntity: 'rule', + filterOpts: { + fieldNames: { + consumer: 'ad_hoc_run_params.attributes.rule.consumer', + ruleTypeId: 'ad_hoc_run_params.attributes.rule.alertTypeId', + }, + type: 'kql', }, - type: 'kql', }); expect(unsecuredSavedObjectsClient.find).toHaveBeenCalledWith({ @@ -465,12 +477,15 @@ describe('findBackfill()', () => { end: '2024-03-29T02:07:55Z', }); - expect(authorization.getFindAuthorizationFilter).toHaveBeenCalledWith('rule', { - fieldNames: { - consumer: 'ad_hoc_run_params.attributes.rule.consumer', - ruleTypeId: 'ad_hoc_run_params.attributes.rule.alertTypeId', + expect(authorization.getFindAuthorizationFilter).toHaveBeenCalledWith({ + authorizationEntity: 'rule', + filterOpts: { + fieldNames: { + consumer: 'ad_hoc_run_params.attributes.rule.consumer', + ruleTypeId: 'ad_hoc_run_params.attributes.rule.alertTypeId', + }, + type: 'kql', }, - type: 'kql', }); expect(unsecuredSavedObjectsClient.find).toHaveBeenCalledWith({ @@ -546,12 +561,15 @@ describe('findBackfill()', () => { ruleIds: 'abc', }); - expect(authorization.getFindAuthorizationFilter).toHaveBeenCalledWith('rule', { - fieldNames: { - consumer: 'ad_hoc_run_params.attributes.rule.consumer', - ruleTypeId: 'ad_hoc_run_params.attributes.rule.alertTypeId', + expect(authorization.getFindAuthorizationFilter).toHaveBeenCalledWith({ + authorizationEntity: 'rule', + filterOpts: { + fieldNames: { + consumer: 'ad_hoc_run_params.attributes.rule.consumer', + ruleTypeId: 'ad_hoc_run_params.attributes.rule.alertTypeId', + }, + type: 'kql', }, - type: 'kql', }); expect(unsecuredSavedObjectsClient.find).toHaveBeenCalledWith({ @@ -627,12 +645,15 @@ describe('findBackfill()', () => { sortOrder: 'asc', }); - expect(authorization.getFindAuthorizationFilter).toHaveBeenCalledWith('rule', { - fieldNames: { - consumer: 'ad_hoc_run_params.attributes.rule.consumer', - ruleTypeId: 'ad_hoc_run_params.attributes.rule.alertTypeId', + expect(authorization.getFindAuthorizationFilter).toHaveBeenCalledWith({ + authorizationEntity: 'rule', + filterOpts: { + fieldNames: { + consumer: 'ad_hoc_run_params.attributes.rule.consumer', + ruleTypeId: 'ad_hoc_run_params.attributes.rule.alertTypeId', + }, + type: 'kql', }, - type: 'kql', }); expect(unsecuredSavedObjectsClient.find).toHaveBeenCalledWith({ diff --git a/x-pack/plugins/alerting/server/application/backfill/methods/find/find_backfill.ts b/x-pack/plugins/alerting/server/application/backfill/methods/find/find_backfill.ts index 522128d0385f8..3482d854bda1f 100644 --- a/x-pack/plugins/alerting/server/application/backfill/methods/find/find_backfill.ts +++ b/x-pack/plugins/alerting/server/application/backfill/methods/find/find_backfill.ts @@ -40,16 +40,16 @@ export async function findBackfill( let authorizationTuple; try { - authorizationTuple = await context.authorization.getFindAuthorizationFilter( - AlertingAuthorizationEntity.Rule, - { + authorizationTuple = await context.authorization.getFindAuthorizationFilter({ + authorizationEntity: AlertingAuthorizationEntity.Rule, + filterOpts: { type: AlertingAuthorizationFilterType.KQL, fieldNames: { ruleTypeId: 'ad_hoc_run_params.attributes.rule.alertTypeId', consumer: 'ad_hoc_run_params.attributes.rule.consumer', }, - } - ); + }, + }); } catch (error) { context.auditLogger?.log( adHocRunAuditEvent({ diff --git a/x-pack/plugins/alerting/server/application/backfill/methods/schedule/schedule_backfill.test.ts b/x-pack/plugins/alerting/server/application/backfill/methods/schedule/schedule_backfill.test.ts index b8f1e5af9c869..a0a79421c7358 100644 --- a/x-pack/plugins/alerting/server/application/backfill/methods/schedule/schedule_backfill.test.ts +++ b/x-pack/plugins/alerting/server/application/backfill/methods/schedule/schedule_backfill.test.ts @@ -251,12 +251,15 @@ describe('scheduleBackfill()', () => { const mockData = [getMockData(), getMockData({ ruleId: '2', end: '2023-11-17T08:00:00.000Z' })]; const result = await rulesClient.scheduleBackfill(mockData); - expect(authorization.getFindAuthorizationFilter).toHaveBeenCalledWith('rule', { - fieldNames: { - consumer: 'alert.attributes.consumer', - ruleTypeId: 'alert.attributes.alertTypeId', + expect(authorization.getFindAuthorizationFilter).toHaveBeenCalledWith({ + authorizationEntity: 'rule', + filterOpts: { + fieldNames: { + consumer: 'alert.attributes.consumer', + ruleTypeId: 'alert.attributes.alertTypeId', + }, + type: 'kql', }, - type: 'kql', }); expect(unsecuredSavedObjectsClient.find).toHaveBeenCalledWith({ diff --git a/x-pack/plugins/alerting/server/application/backfill/methods/schedule/schedule_backfill.ts b/x-pack/plugins/alerting/server/application/backfill/methods/schedule/schedule_backfill.ts index 534262aa31c31..2dec1a78e3171 100644 --- a/x-pack/plugins/alerting/server/application/backfill/methods/schedule/schedule_backfill.ts +++ b/x-pack/plugins/alerting/server/application/backfill/methods/schedule/schedule_backfill.ts @@ -46,10 +46,10 @@ export async function scheduleBackfill( let authorizationTuple; try { - authorizationTuple = await context.authorization.getFindAuthorizationFilter( - AlertingAuthorizationEntity.Rule, - alertingAuthorizationFilterOpts - ); + authorizationTuple = await context.authorization.getFindAuthorizationFilter({ + authorizationEntity: AlertingAuthorizationEntity.Rule, + filterOpts: alertingAuthorizationFilterOpts, + }); } catch (error) { context.auditLogger?.log( ruleAuditEvent({ diff --git a/x-pack/plugins/alerting/server/application/rule/methods/aggregate/aggregate_rules.test.ts b/x-pack/plugins/alerting/server/application/rule/methods/aggregate/aggregate_rules.test.ts index 57fb2bf8f48a4..23ccbf97cb6ce 100644 --- a/x-pack/plugins/alerting/server/application/rule/methods/aggregate/aggregate_rules.test.ts +++ b/x-pack/plugins/alerting/server/application/rule/methods/aggregate/aggregate_rules.test.ts @@ -23,7 +23,7 @@ import { auditLoggerMock } from '@kbn/security-plugin/server/audit/mocks'; import { getBeforeSetup, setGlobalDate } from '../../../../rules_client/tests/lib'; import { RegistryRuleType } from '../../../../rule_type_registry'; -import { fromKueryExpression, nodeTypes } from '@kbn/es-query'; +import { fromKueryExpression, nodeTypes, toKqlExpression } from '@kbn/es-query'; import { RecoveredActionGroup } from '../../../../../common'; import { DefaultRuleAggregationResult } from '../../../../routes/rule/apis/aggregate/types'; import { defaultRuleAggregationFactory } from '.'; @@ -78,24 +78,28 @@ beforeEach(() => { setGlobalDate(); describe('aggregate()', () => { - const listedTypes = new Set([ - { - actionGroups: [], - actionVariables: undefined, - defaultActionGroupId: 'default', - minimumLicenseRequired: 'basic', - isExportable: true, - recoveryActionGroup: RecoveredActionGroup, - id: 'myType', - name: 'myType', - category: 'test', - producer: 'myApp', - enabledInLicense: true, - hasAlertsMappings: false, - hasFieldsForAAD: false, - validLegacyConsumers: [], - }, + const listedTypes = new Map([ + [ + 'myType', + { + actionGroups: [], + actionVariables: undefined, + defaultActionGroupId: 'default', + minimumLicenseRequired: 'basic', + isExportable: true, + recoveryActionGroup: RecoveredActionGroup, + id: 'myType', + name: 'myType', + category: 'test', + producer: 'myApp', + enabledInLicense: true, + hasAlertsMappings: false, + hasFieldsForAAD: false, + validLegacyConsumers: [], + }, + ], ]); + beforeEach(() => { authorization.getFindAuthorizationFilter.mockResolvedValue({ ensureRuleTypeIsAuthorized() {}, @@ -161,26 +165,16 @@ describe('aggregate()', () => { }); ruleTypeRegistry.list.mockReturnValue(listedTypes); - authorization.filterByRuleTypeAuthorization.mockResolvedValue( - new Set([ - { - id: 'myType', - name: 'Test', - actionGroups: [{ id: 'default', name: 'Default' }], - defaultActionGroupId: 'default', - minimumLicenseRequired: 'basic', - isExportable: true, - recoveryActionGroup: RecoveredActionGroup, - category: 'test', - producer: 'alerts', - authorizedConsumers: { - myApp: { read: true, all: true }, + authorization.getAuthorizedRuleTypes.mockResolvedValue( + new Map([ + [ + 'myType', + { + authorizedConsumers: { + myApp: { read: true, all: true }, + }, }, - enabledInLicense: true, - hasAlertsMappings: false, - hasFieldsForAAD: false, - validLegacyConsumers: [], - }, + ], ]) ); }); @@ -394,6 +388,34 @@ describe('aggregate()', () => { ]); }); + test('combines the filters with the auth filter correctly', async () => { + const authFilter = fromKueryExpression( + 'alert.attributes.alertTypeId:myType and alert.attributes.consumer:myApp' + ); + + authorization.getFindAuthorizationFilter.mockResolvedValue({ + filter: authFilter, + ensureRuleTypeIsAuthorized() {}, + }); + + const rulesClient = new RulesClient(rulesClientParams); + await rulesClient.aggregate({ + options: { + ruleTypeIds: ['my-rule-type-id'], + consumers: ['bar'], + filter: `alert.attributes.tags: ['bar']`, + }, + aggs: defaultRuleAggregationFactory(), + }); + + const finalFilter = unsecuredSavedObjectsClient.find.mock.calls[0][0].filter; + + expect(unsecuredSavedObjectsClient.find).toHaveBeenCalledTimes(1); + expect(toKqlExpression(finalFilter)).toMatchInlineSnapshot( + `"((alert.attributes.tags: ['bar'] AND alert.attributes.alertTypeId: my-rule-type-id AND alert.attributes.consumer: bar) AND (alert.attributes.alertTypeId: myType AND alert.attributes.consumer: myApp))"` + ); + }); + test('logs audit event when not authorized to aggregate rules', async () => { const rulesClient = new RulesClient({ ...rulesClientParams, auditLogger }); authorization.getFindAuthorizationFilter.mockRejectedValue(new Error('Unauthorized')); diff --git a/x-pack/plugins/alerting/server/application/rule/methods/aggregate/aggregate_rules.ts b/x-pack/plugins/alerting/server/application/rule/methods/aggregate/aggregate_rules.ts index 9011b971e629a..307e27184ca7e 100644 --- a/x-pack/plugins/alerting/server/application/rule/methods/aggregate/aggregate_rules.ts +++ b/x-pack/plugins/alerting/server/application/rule/methods/aggregate/aggregate_rules.ts @@ -5,8 +5,13 @@ * 2.0. */ -import { KueryNode, nodeBuilder } from '@kbn/es-query'; -import { isEmpty } from 'lodash'; +import type { KueryNode } from '@kbn/es-query'; +import { + buildConsumersFilter, + buildRuleTypeIdsFilter, + combineFilterWithAuthorizationFilter, + combineFilters, +} from '../../../../rules_client/common/filters'; import { findRulesSo } from '../../../../data/rule'; import { AlertingAuthorizationEntity } from '../../../../authorization'; import { ruleAuditEvent, RuleAuditAction } from '../../../../rules_client/common/audit_events'; @@ -22,15 +27,15 @@ export async function aggregateRules>( params: AggregateParams ): Promise { const { options = {}, aggs } = params; - const { filter, page = 1, perPage = 0, filterConsumers, ...restOptions } = options; + const { filter, page = 1, perPage = 0, ruleTypeIds, consumers, ...restOptions } = options; let authorizationTuple; try { - authorizationTuple = await context.authorization.getFindAuthorizationFilter( - AlertingAuthorizationEntity.Rule, - alertingAuthorizationFilterOpts, - isEmpty(filterConsumers) ? undefined : new Set(filterConsumers) - ); + authorizationTuple = await context.authorization.getFindAuthorizationFilter({ + authorizationEntity: AlertingAuthorizationEntity.Rule, + filterOpts: alertingAuthorizationFilterOpts, + }); + validateRuleAggregationFields(aggs); aggregateOptionsSchema.validate(options); } catch (error) { @@ -45,15 +50,21 @@ export async function aggregateRules>( const { filter: authorizationFilter } = authorizationTuple; const filterKueryNode = buildKueryNodeFilter(filter); + const ruleTypeIdsFilter = buildRuleTypeIdsFilter(ruleTypeIds); + const consumersFilter = buildConsumersFilter(consumers); + const combinedFilters = combineFilters( + [filterKueryNode, ruleTypeIdsFilter, consumersFilter], + 'and' + ); const { aggregations } = await findRulesSo({ savedObjectsClient: context.unsecuredSavedObjectsClient, savedObjectsFindOptions: { ...restOptions, - filter: - authorizationFilter && filterKueryNode - ? nodeBuilder.and([filterKueryNode, authorizationFilter as KueryNode]) - : authorizationFilter, + filter: combineFilterWithAuthorizationFilter( + combinedFilters, + authorizationFilter as KueryNode + ), page, perPage, aggs, diff --git a/x-pack/plugins/alerting/server/application/rule/methods/aggregate/schemas/aggregate_options_schema.ts b/x-pack/plugins/alerting/server/application/rule/methods/aggregate/schemas/aggregate_options_schema.ts index 7250094160a04..d26f48e2462f5 100644 --- a/x-pack/plugins/alerting/server/application/rule/methods/aggregate/schemas/aggregate_options_schema.ts +++ b/x-pack/plugins/alerting/server/application/rule/methods/aggregate/schemas/aggregate_options_schema.ts @@ -16,7 +16,8 @@ export const aggregateOptionsSchema = schema.object({ id: schema.string(), }) ), - filterConsumers: schema.maybe(schema.arrayOf(schema.string())), + ruleTypeIds: schema.maybe(schema.arrayOf(schema.string())), + consumers: schema.maybe(schema.arrayOf(schema.string())), // filter type is `string | KueryNode`, but `KueryNode` has no schema to import yet filter: schema.maybe( schema.oneOf([schema.string(), schema.recordOf(schema.string(), schema.any())]) diff --git a/x-pack/plugins/alerting/server/application/rule/methods/aggregate/types/index.ts b/x-pack/plugins/alerting/server/application/rule/methods/aggregate/types/index.ts index 2156fb91e8778..e146928efcfff 100644 --- a/x-pack/plugins/alerting/server/application/rule/methods/aggregate/types/index.ts +++ b/x-pack/plugins/alerting/server/application/rule/methods/aggregate/types/index.ts @@ -9,17 +9,9 @@ import { TypeOf } from '@kbn/config-schema'; import { KueryNode } from '@kbn/es-query'; import { aggregateOptionsSchema } from '../schemas'; -type AggregateOptionsSchemaTypes = TypeOf; export type AggregateOptions = TypeOf & { - search?: AggregateOptionsSchemaTypes['search']; - defaultSearchOperator?: AggregateOptionsSchemaTypes['defaultSearchOperator']; - searchFields?: AggregateOptionsSchemaTypes['searchFields']; - hasReference?: AggregateOptionsSchemaTypes['hasReference']; // Adding filter as in schema it's defined as any instead of KueryNode filter?: string | KueryNode; - page?: AggregateOptionsSchemaTypes['page']; - perPage?: AggregateOptionsSchemaTypes['perPage']; - filterConsumers?: string[]; }; export interface AggregateParams { 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 8868065fa43a5..f7d83545ec193 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 @@ -132,10 +132,10 @@ export async function bulkEditRules( const qNodeFilter = ids ? convertRuleIdsToKueryNode(ids) : qNodeQueryFilter; let authorizationTuple; try { - authorizationTuple = await context.authorization.getFindAuthorizationFilter( - AlertingAuthorizationEntity.Rule, - alertingAuthorizationFilterOpts - ); + authorizationTuple = await context.authorization.getFindAuthorizationFilter({ + authorizationEntity: AlertingAuthorizationEntity.Rule, + filterOpts: alertingAuthorizationFilterOpts, + }); } catch (error) { context.auditLogger?.log( ruleAuditEvent({ diff --git a/x-pack/plugins/alerting/server/application/rule/methods/bulk_untrack/bulk_untrack_alerts.ts b/x-pack/plugins/alerting/server/application/rule/methods/bulk_untrack/bulk_untrack_alerts.ts index 304037782f6d3..e93f82da28cbe 100644 --- a/x-pack/plugins/alerting/server/application/rule/methods/bulk_untrack/bulk_untrack_alerts.ts +++ b/x-pack/plugins/alerting/server/application/rule/methods/bulk_untrack/bulk_untrack_alerts.ts @@ -41,12 +41,11 @@ async function bulkUntrackAlertsWithOCC(context: RulesClientContext, params: Bul if (!context.alertsService) throw new Error('unable to access alertsService'); const result = await context.alertsService.setAlertsToUntracked({ ...params, - featureIds: params.featureIds || [], + ruleTypeIds: params.ruleTypeIds || [], spaceId: context.spaceId, getAlertIndicesAlias: context.getAlertIndicesAlias, - getAuthorizedRuleTypes: context.authorization.getAuthorizedRuleTypes.bind( - context.authorization - ), + getAllAuthorizedRuleTypesFindOperation: + context.authorization.getAllAuthorizedRuleTypesFindOperation.bind(context.authorization), ensureAuthorized: async ({ ruleTypeId, consumer, diff --git a/x-pack/plugins/alerting/server/application/rule/methods/bulk_untrack/schemas/bulk_untrack_body_schema.ts b/x-pack/plugins/alerting/server/application/rule/methods/bulk_untrack/schemas/bulk_untrack_body_schema.ts index f597d9f5b6fa4..8a4affbc83c3f 100644 --- a/x-pack/plugins/alerting/server/application/rule/methods/bulk_untrack/schemas/bulk_untrack_body_schema.ts +++ b/x-pack/plugins/alerting/server/application/rule/methods/bulk_untrack/schemas/bulk_untrack_body_schema.ts @@ -11,5 +11,5 @@ export const bulkUntrackBodySchema = schema.object({ indices: schema.maybe(schema.arrayOf(schema.string())), alertUuids: schema.maybe(schema.arrayOf(schema.string())), query: schema.maybe(schema.arrayOf(schema.any())), - featureIds: schema.maybe(schema.arrayOf(schema.string())), + ruleTypeIds: schema.maybe(schema.arrayOf(schema.string())), }); diff --git a/x-pack/plugins/alerting/server/application/rule/methods/create/create_rule.ts b/x-pack/plugins/alerting/server/application/rule/methods/create/create_rule.ts index 34e13b65d76c5..3514f8ce2237b 100644 --- a/x-pack/plugins/alerting/server/application/rule/methods/create/create_rule.ts +++ b/x-pack/plugins/alerting/server/application/rule/methods/create/create_rule.ts @@ -84,6 +84,12 @@ export async function createRule( throw Boom.badRequest(`Error validating create data - ${error.message}`); } + /** + * ruleTypeRegistry.get will throw a 400 (Bad request) + * error if the rule type is not registered. + */ + context.ruleTypeRegistry.get(data.alertTypeId); + let validationPayload: ValidateScheduleLimitResult = null; if (data.enabled) { validationPayload = await validateScheduleLimit({ diff --git a/x-pack/plugins/alerting/server/application/rule/methods/find/find_rules.test.ts b/x-pack/plugins/alerting/server/application/rule/methods/find/find_rules.test.ts index e6bfd3408a538..369549d839c79 100644 --- a/x-pack/plugins/alerting/server/application/rule/methods/find/find_rules.test.ts +++ b/x-pack/plugins/alerting/server/application/rule/methods/find/find_rules.test.ts @@ -15,7 +15,7 @@ import { import { taskManagerMock } from '@kbn/task-manager-plugin/server/mocks'; import { ruleTypeRegistryMock } from '../../../../rule_type_registry.mock'; import { alertingAuthorizationMock } from '../../../../authorization/alerting_authorization.mock'; -import { nodeTypes, fromKueryExpression } from '@kbn/es-query'; +import { nodeTypes, fromKueryExpression, toKqlExpression } from '@kbn/es-query'; import { encryptedSavedObjectsMock } from '@kbn/encrypted-saved-objects-plugin/server/mocks'; import { actionsAuthorizationMock } from '@kbn/actions-plugin/server/mocks'; import { AlertingAuthorization } from '../../../../authorization/alerting_authorization'; @@ -92,23 +92,26 @@ jest.mock('../../../../rules_client/common/map_sort_field', () => ({ })); describe('find()', () => { - const listedTypes = new Set([ - { - actionGroups: [], - recoveryActionGroup: RecoveredActionGroup, - actionVariables: undefined, - defaultActionGroupId: 'default', - minimumLicenseRequired: 'basic', - isExportable: true, - id: 'myType', - name: 'myType', - category: 'test', - producer: 'myApp', - enabledInLicense: true, - hasAlertsMappings: false, - hasFieldsForAAD: false, - validLegacyConsumers: [], - }, + const listedTypes = new Map([ + [ + 'myType', + { + actionGroups: [], + recoveryActionGroup: RecoveredActionGroup, + actionVariables: undefined, + defaultActionGroupId: 'default', + minimumLicenseRequired: 'basic', + isExportable: true, + id: 'myType', + name: 'myType', + category: 'test', + producer: 'myApp', + enabledInLicense: true, + hasAlertsMappings: false, + hasFieldsForAAD: false, + validLegacyConsumers: [], + }, + ], ]); beforeEach(() => { @@ -163,26 +166,16 @@ describe('find()', () => { }); ruleTypeRegistry.list.mockReturnValue(listedTypes); - authorization.filterByRuleTypeAuthorization.mockResolvedValue( - new Set([ - { - id: 'myType', - name: 'Test', - actionGroups: [{ id: 'default', name: 'Default' }], - recoveryActionGroup: RecoveredActionGroup, - defaultActionGroupId: 'default', - minimumLicenseRequired: 'basic', - isExportable: true, - category: 'test', - producer: 'alerts', - authorizedConsumers: { - myApp: { read: true, all: true }, + authorization.getAuthorizedRuleTypes.mockResolvedValue( + new Map([ + [ + 'myType', + { + authorizedConsumers: { + myApp: { read: true, all: true }, + }, }, - enabledInLicense: true, - hasAlertsMappings: false, - hasFieldsForAAD: false, - validLegacyConsumers: [], - }, + ], ]) ); }); @@ -235,7 +228,7 @@ describe('find()', () => { Array [ Object { "fields": undefined, - "filter": null, + "filter": undefined, "sortField": undefined, "type": "alert", }, @@ -349,7 +342,7 @@ describe('find()', () => { Array [ Object { "fields": undefined, - "filter": null, + "filter": undefined, "sortField": undefined, "type": "alert", }, @@ -461,7 +454,7 @@ describe('find()', () => { Array [ Object { "fields": undefined, - "filter": null, + "filter": undefined, "sortField": undefined, "type": "alert", }, @@ -513,13 +506,34 @@ describe('find()', () => { authorization.getFindAuthorizationFilter.mockResolvedValue({ ensureRuleTypeIsAuthorized() {}, }); + const injectReferencesFn = jest.fn().mockReturnValue({ bar: true, parameterThatIsSavedObjectId: '9', }); - ruleTypeRegistry.list.mockReturnValue( - new Set([ - ...listedTypes, + + const ruleTypes = new Map([ + [ + 'myType', + { + actionGroups: [], + recoveryActionGroup: RecoveredActionGroup, + actionVariables: undefined, + defaultActionGroupId: 'default', + minimumLicenseRequired: 'basic', + isExportable: true, + id: 'myType', + name: 'myType', + category: 'test', + producer: 'myApp', + enabledInLicense: true, + hasAlertsMappings: false, + hasFieldsForAAD: false, + validLegacyConsumers: [], + }, + ], + [ + '123', { actionGroups: [], recoveryActionGroup: RecoveredActionGroup, @@ -536,8 +550,10 @@ describe('find()', () => { hasFieldsForAAD: false, validLegacyConsumers: [], }, - ]) - ); + ], + ]); + + ruleTypeRegistry.list.mockReturnValue(ruleTypes); ruleTypeRegistry.get.mockImplementationOnce(() => ({ id: 'myType', name: 'myType', @@ -750,12 +766,33 @@ describe('find()', () => { authorization.getFindAuthorizationFilter.mockResolvedValue({ ensureRuleTypeIsAuthorized() {}, }); + const injectReferencesFn = jest.fn().mockImplementation(() => { throw new Error('something went wrong!'); }); - ruleTypeRegistry.list.mockReturnValue( - new Set([ - ...listedTypes, + + const ruleTypes = new Map([ + [ + 'myType', + { + actionGroups: [], + recoveryActionGroup: RecoveredActionGroup, + actionVariables: undefined, + defaultActionGroupId: 'default', + minimumLicenseRequired: 'basic', + isExportable: true, + id: 'myType', + name: 'myType', + category: 'test', + producer: 'myApp', + enabledInLicense: true, + hasAlertsMappings: false, + hasFieldsForAAD: false, + validLegacyConsumers: [], + }, + ], + [ + '123', { actionGroups: [], recoveryActionGroup: RecoveredActionGroup, @@ -772,8 +809,10 @@ describe('find()', () => { hasFieldsForAAD: false, validLegacyConsumers: [], }, - ]) - ); + ], + ]); + + ruleTypeRegistry.list.mockReturnValue(ruleTypes); ruleTypeRegistry.get.mockImplementationOnce(() => ({ id: 'myType', name: 'myType', @@ -792,6 +831,7 @@ describe('find()', () => { }, validLegacyConsumers: [], })); + ruleTypeRegistry.get.mockImplementationOnce(() => ({ id: '123', name: 'Test', @@ -987,12 +1027,58 @@ describe('find()', () => { expect(unsecuredSavedObjectsClient.find).toHaveBeenCalledWith({ fields: ['tags', 'alertTypeId', 'consumer'], - filter: null, + filter: undefined, sortField: undefined, type: RULE_SAVED_OBJECT_TYPE, }); expect(ensureRuleTypeIsAuthorized).toHaveBeenCalledWith('myType', 'myApp', 'rule'); }); + + test('calls getFindAuthorizationFilter correctly', async () => { + authorization.getFindAuthorizationFilter.mockResolvedValue({ + ensureRuleTypeIsAuthorized() {}, + }); + + const rulesClient = new RulesClient(rulesClientParams); + await rulesClient.find({ options: { ruleTypeIds: ['foo'], consumers: ['bar'] } }); + + expect(authorization.getFindAuthorizationFilter).toHaveBeenCalledWith({ + authorizationEntity: 'rule', + filterOpts: { + fieldNames: { + consumer: 'alert.attributes.consumer', + ruleTypeId: 'alert.attributes.alertTypeId', + }, + type: 'kql', + }, + }); + }); + + test('combines the filters with the auth filter correctly', async () => { + const filter = fromKueryExpression( + 'alert.attributes.alertTypeId:myType and alert.attributes.consumer:myApp' + ); + + authorization.getFindAuthorizationFilter.mockResolvedValue({ + filter, + ensureRuleTypeIsAuthorized() {}, + }); + + const rulesClient = new RulesClient(rulesClientParams); + await rulesClient.find({ + options: { + ruleTypeIds: ['foo'], + consumers: ['bar'], + filter: `alert.attributes.tags: ['bar']`, + }, + }); + + const finalFilter = unsecuredSavedObjectsClient.find.mock.calls[0][0].filter; + + expect(toKqlExpression(finalFilter)).toMatchInlineSnapshot( + `"((alert.attributes.tags: ['bar'] AND alert.attributes.alertTypeId: foo AND alert.attributes.consumer: bar) AND (alert.attributes.alertTypeId: myType AND alert.attributes.consumer: myApp))"` + ); + }); }); describe('auditLogger', () => { diff --git a/x-pack/plugins/alerting/server/application/rule/methods/find/find_rules.ts b/x-pack/plugins/alerting/server/application/rule/methods/find/find_rules.ts index 7e4efb2665f6b..26441a4474473 100644 --- a/x-pack/plugins/alerting/server/application/rule/methods/find/find_rules.ts +++ b/x-pack/plugins/alerting/server/application/rule/methods/find/find_rules.ts @@ -6,11 +6,17 @@ */ import Boom from '@hapi/boom'; -import { isEmpty, pick } from 'lodash'; -import { KueryNode, nodeBuilder } from '@kbn/es-query'; +import { pick } from 'lodash'; +import { KueryNode } from '@kbn/es-query'; import { AlertConsumers } from '@kbn/rule-data-utils'; +import { + buildConsumersFilter, + buildRuleTypeIdsFilter, + combineFilterWithAuthorizationFilter, + combineFilters, +} from '../../../../rules_client/common/filters'; +import { AlertingAuthorizationEntity } from '../../../../authorization/types'; import { SanitizedRule, Rule as DeprecatedRule, RawRule } from '../../../../types'; -import { AlertingAuthorizationEntity } from '../../../../authorization'; import { ruleAuditEvent, RuleAuditAction } from '../../../../rules_client/common/audit_events'; import { mapSortField, @@ -46,7 +52,7 @@ export async function findRules( ): Promise> { const { options, excludeFromPublicApi = false, includeSnoozeData = false } = params || {}; - const { fields, filterConsumers, ...restOptions } = options || {}; + const { fields, ruleTypeIds, consumers, ...restOptions } = options || {}; try { if (params) { @@ -58,11 +64,10 @@ export async function findRules( let authorizationTuple; try { - authorizationTuple = await context.authorization.getFindAuthorizationFilter( - AlertingAuthorizationEntity.Rule, - alertingAuthorizationFilterOpts, - isEmpty(filterConsumers) ? undefined : new Set(filterConsumers) - ); + authorizationTuple = await context.authorization.getFindAuthorizationFilter({ + authorizationEntity: AlertingAuthorizationEntity.Rule, + filterOpts: alertingAuthorizationFilterOpts, + }); } catch (error) { context.auditLogger?.log( ruleAuditEvent({ @@ -76,6 +81,7 @@ export async function findRules( const { filter: authorizationFilter, ensureRuleTypeIsAuthorized } = authorizationTuple; const filterKueryNode = buildKueryNodeFilter(restOptions.filter as string | KueryNode); let sortField = mapSortField(restOptions.sortField); + if (excludeFromPublicApi) { try { validateOperationOnAttributes( @@ -111,6 +117,18 @@ export async function findRules( modifyFilterKueryNode({ astFilter: filterKueryNode }); } + const ruleTypeIdsFilter = buildRuleTypeIdsFilter(ruleTypeIds); + const consumersFilter = buildConsumersFilter(consumers); + const combinedFilters = combineFilters( + [filterKueryNode, ruleTypeIdsFilter, consumersFilter], + 'and' + ); + + const finalFilter = combineFilterWithAuthorizationFilter( + combinedFilters, + authorizationFilter as KueryNode + ); + const { page, per_page: perPage, @@ -121,10 +139,7 @@ export async function findRules( savedObjectsFindOptions: { ...modifiedOptions, sortField, - filter: - (authorizationFilter && filterKueryNode - ? nodeBuilder.and([filterKueryNode, authorizationFilter as KueryNode]) - : authorizationFilter) ?? filterKueryNode, + filter: finalFilter, fields: fields ? includeFieldsRequiredForAuthentication(fields) : fields, }, }); diff --git a/x-pack/plugins/alerting/server/application/rule/methods/find/schemas/find_rules_schemas.ts b/x-pack/plugins/alerting/server/application/rule/methods/find/schemas/find_rules_schemas.ts index b766ffc283bb2..aec95d7f2c061 100644 --- a/x-pack/plugins/alerting/server/application/rule/methods/find/schemas/find_rules_schemas.ts +++ b/x-pack/plugins/alerting/server/application/rule/methods/find/schemas/find_rules_schemas.ts @@ -28,7 +28,8 @@ export const findRulesOptionsSchema = schema.object( filter: schema.maybe( schema.oneOf([schema.string(), schema.recordOf(schema.string(), schema.any())]) ), - filterConsumers: schema.maybe(schema.arrayOf(schema.string())), + ruleTypeIds: schema.maybe(schema.arrayOf(schema.string())), + consumers: schema.maybe(schema.arrayOf(schema.string())), }, { unknowns: 'allow' } ); @@ -37,5 +38,4 @@ export const findRulesParamsSchema = schema.object({ options: schema.maybe(findRulesOptionsSchema), excludeFromPublicApi: schema.maybe(schema.boolean()), includeSnoozeData: schema.maybe(schema.boolean()), - featureIds: schema.maybe(schema.arrayOf(schema.string())), }); diff --git a/x-pack/plugins/alerting/server/application/rule/methods/find/types/find_rules_types.ts b/x-pack/plugins/alerting/server/application/rule/methods/find/types/find_rules_types.ts index 615a5b5db8672..77694f150c5a9 100644 --- a/x-pack/plugins/alerting/server/application/rule/methods/find/types/find_rules_types.ts +++ b/x-pack/plugins/alerting/server/application/rule/methods/find/types/find_rules_types.ts @@ -9,5 +9,4 @@ import { TypeOf } from '@kbn/config-schema'; import { findRulesOptionsSchema, findRulesParamsSchema } from '../schemas'; export type FindRulesOptions = TypeOf; - export type FindRulesParams = TypeOf; diff --git a/x-pack/plugins/alerting/server/application/rule/methods/rule_types/rule_types.test.ts b/x-pack/plugins/alerting/server/application/rule/methods/rule_types/rule_types.test.ts new file mode 100644 index 0000000000000..fd0a641df022c --- /dev/null +++ b/x-pack/plugins/alerting/server/application/rule/methods/rule_types/rule_types.test.ts @@ -0,0 +1,52 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { rulesClientContextMock } from '../../../../rules_client/rules_client.mock'; +import { RulesClient } from '../../../../rules_client'; + +describe('listRuleTypes', () => { + const rulesClientContext = rulesClientContextMock.create(); + let rulesClient: RulesClient; + + beforeEach(async () => { + jest.clearAllMocks(); + rulesClient = new RulesClient(rulesClientContext); + + rulesClientContext.ruleTypeRegistry.list = jest.fn().mockReturnValue( + new Map([ + ['apm.anomaly', { name: 'Anomaly' }], + ['.es-query', { name: 'ES rule type' }], + ]) + ); + rulesClientContext.ruleTypeRegistry.has = jest + .fn() + .mockImplementation((ruleTypeId: string) => ruleTypeId === '.es-query'); + + rulesClientContext.authorization.getAuthorizedRuleTypes = jest.fn().mockResolvedValue( + new Map([ + ['.es-query', { authorizedConsumers: { all: true, read: true } }], + ['.not-exist', { authorizedConsumers: { all: true, read: true } }], + ]) + ); + }); + + it('authorizes correctly', async () => { + await rulesClient.listRuleTypes(); + + expect(rulesClientContext.authorization.getAuthorizedRuleTypes).toHaveBeenCalledWith({ + authorizationEntity: 'rule', + operations: ['get', 'create'], + ruleTypeIds: ['apm.anomaly', '.es-query'], + }); + }); + + it('returns the authorized rule types correctly and does not return non authorized or non existing rule types', async () => { + const res = await rulesClient.listRuleTypes(); + + expect(res).toEqual([{ name: 'ES rule type', authorizedConsumers: { all: true, read: true } }]); + }); +}); diff --git a/x-pack/plugins/alerting/server/application/rule/methods/rule_types/rule_types.ts b/x-pack/plugins/alerting/server/application/rule/methods/rule_types/rule_types.ts index 66256b4b7d7eb..4bcb6fdece3e2 100644 --- a/x-pack/plugins/alerting/server/application/rule/methods/rule_types/rule_types.ts +++ b/x-pack/plugins/alerting/server/application/rule/methods/rule_types/rule_types.ts @@ -6,16 +6,28 @@ */ import { - WriteOperations, - ReadOperations, AlertingAuthorizationEntity, + ReadOperations, + RegistryAlertTypeWithAuth, + WriteOperations, } from '../../../../authorization'; import { RulesClientContext } from '../../../../rules_client/types'; -export async function listRuleTypes(context: RulesClientContext) { - return await context.authorization.filterByRuleTypeAuthorization( - context.ruleTypeRegistry.list(), - [ReadOperations.Get, WriteOperations.Create], - AlertingAuthorizationEntity.Rule - ); +export async function listRuleTypes( + context: RulesClientContext +): Promise { + const registeredRuleTypes = context.ruleTypeRegistry.list(); + + const authorizedRuleTypes = await context.authorization.getAuthorizedRuleTypes({ + authorizationEntity: AlertingAuthorizationEntity.Rule, + operations: [ReadOperations.Get, WriteOperations.Create], + ruleTypeIds: Array.from(registeredRuleTypes.keys()).map((id) => id), + }); + + return Array.from(authorizedRuleTypes.entries()) + .filter(([id, _]) => context.ruleTypeRegistry.has(id)) + .map(([id, { authorizedConsumers }]) => ({ + ...registeredRuleTypes.get(id)!, + authorizedConsumers, + })); } diff --git a/x-pack/plugins/alerting/server/application/rule/methods/tags/get_rule_tags.test.ts b/x-pack/plugins/alerting/server/application/rule/methods/tags/get_rule_tags.test.ts index de356c3a2e2b9..2a84becfd83d6 100644 --- a/x-pack/plugins/alerting/server/application/rule/methods/tags/get_rule_tags.test.ts +++ b/x-pack/plugins/alerting/server/application/rule/methods/tags/get_rule_tags.test.ts @@ -66,23 +66,26 @@ const rulesClientParams: jest.Mocked = { isSystemAction: jest.fn(), }; -const listedTypes = new Set([ - { - actionGroups: [], - actionVariables: undefined, - defaultActionGroupId: 'default', - minimumLicenseRequired: 'basic', - isExportable: true, - recoveryActionGroup: RecoveredActionGroup, - id: 'myType', - name: 'myType', - category: 'test', - producer: 'myApp', - enabledInLicense: true, - hasAlertsMappings: false, - hasFieldsForAAD: false, - validLegacyConsumers: [], - }, +const listedTypes = new Map([ + [ + 'myType', + { + actionGroups: [], + actionVariables: undefined, + defaultActionGroupId: 'default', + minimumLicenseRequired: 'basic', + isExportable: true, + recoveryActionGroup: RecoveredActionGroup, + id: 'myType', + name: 'myType', + category: 'test', + producer: 'myApp', + enabledInLicense: true, + hasAlertsMappings: false, + hasFieldsForAAD: false, + validLegacyConsumers: [], + }, + ], ]); beforeEach(() => { @@ -118,26 +121,16 @@ describe('getTags()', () => { unsecuredSavedObjectsClient.find.mockResolvedValue(getMockAggregationResult(['a', 'b', 'c'])); ruleTypeRegistry.list.mockReturnValue(listedTypes); - authorization.filterByRuleTypeAuthorization.mockResolvedValue( - new Set([ - { - id: 'myType', - name: 'Test', - actionGroups: [{ id: 'default', name: 'Default' }], - defaultActionGroupId: 'default', - minimumLicenseRequired: 'basic', - isExportable: true, - recoveryActionGroup: RecoveredActionGroup, - category: 'test', - producer: 'alerts', - authorizedConsumers: { - myApp: { read: true, all: true }, + authorization.getAuthorizedRuleTypes.mockResolvedValue( + new Map([ + [ + 'myType', + { + authorizedConsumers: { + myApp: { read: true, all: true }, + }, }, - enabledInLicense: true, - hasAlertsMappings: false, - hasFieldsForAAD: false, - validLegacyConsumers: [], - }, + ], ]) ); }); diff --git a/x-pack/plugins/alerting/server/application/rule/methods/tags/get_rule_tags.ts b/x-pack/plugins/alerting/server/application/rule/methods/tags/get_rule_tags.ts index c26fae42ce324..84a05ac67057a 100644 --- a/x-pack/plugins/alerting/server/application/rule/methods/tags/get_rule_tags.ts +++ b/x-pack/plugins/alerting/server/application/rule/methods/tags/get_rule_tags.ts @@ -33,10 +33,10 @@ export async function getRuleTags( let authorizationTuple; try { - authorizationTuple = await context.authorization.getFindAuthorizationFilter( - AlertingAuthorizationEntity.Rule, - alertingAuthorizationFilterOpts - ); + authorizationTuple = await context.authorization.getFindAuthorizationFilter({ + authorizationEntity: AlertingAuthorizationEntity.Rule, + filterOpts: alertingAuthorizationFilterOpts, + }); } catch (error) { context.auditLogger?.log( ruleAuditEvent({ diff --git a/x-pack/plugins/alerting/server/authorization/alerting_authorization.mock.ts b/x-pack/plugins/alerting/server/authorization/alerting_authorization.mock.ts index e51a5c9b12c79..12e360c7cd644 100644 --- a/x-pack/plugins/alerting/server/authorization/alerting_authorization.mock.ts +++ b/x-pack/plugins/alerting/server/authorization/alerting_authorization.mock.ts @@ -14,12 +14,20 @@ export type AlertingAuthorizationMock = jest.Mocked; const createAlertingAuthorizationMock = () => { const mocked: AlertingAuthorizationMock = { ensureAuthorized: jest.fn(), - filterByRuleTypeAuthorization: jest.fn(), - getAuthorizationFilter: jest.fn(), - getAuthorizedRuleTypes: jest.fn(), - getFindAuthorizationFilter: jest.fn(), - getAugmentedRuleTypesWithAuthorization: jest.fn(), + getAuthorizedRuleTypes: jest.fn().mockResolvedValue(new Map()), + getFindAuthorizationFilter: jest.fn().mockResolvedValue({ + filter: undefined, + ensureRuleTypeIsAuthorized: () => {}, + }), getSpaceId: jest.fn(), + getAllAuthorizedRuleTypes: jest + .fn() + .mockResolvedValue({ hasAllRequested: true, authorizedRuleTypes: new Map() }), + getAllAuthorizedRuleTypesFindOperation: jest.fn().mockResolvedValue(new Map()), + getAuthorizationFilter: jest.fn().mockResolvedValue({ + filter: undefined, + ensureRuleTypeIsAuthorized: () => {}, + }), }; return mocked; }; diff --git a/x-pack/plugins/alerting/server/authorization/alerting_authorization.test.ts b/x-pack/plugins/alerting/server/authorization/alerting_authorization.test.ts index f1cfb99a6daaa..9c470823362d8 100644 --- a/x-pack/plugins/alerting/server/authorization/alerting_authorization.test.ts +++ b/x-pack/plugins/alerting/server/authorization/alerting_authorization.test.ts @@ -5,75 +5,53 @@ * 2.0. */ -import { KueryNode, fromKueryExpression, toKqlExpression } from '@kbn/es-query'; +import Boom from '@hapi/boom'; +import { KueryNode, toKqlExpression } from '@kbn/es-query'; import { KibanaRequest } from '@kbn/core/server'; import { ruleTypeRegistryMock } from '../rule_type_registry.mock'; import { securityMock } from '@kbn/security-plugin/server/mocks'; -import { - FeaturesPluginStart as FeaturesStartContract, - KibanaFeature, -} from '@kbn/features-plugin/server'; +import { KibanaFeature } from '@kbn/features-plugin/server'; import { featuresPluginMock } from '@kbn/features-plugin/server/mocks'; -import { - AlertingAuthorization, - WriteOperations, - ReadOperations, - AlertingAuthorizationEntity, -} from './alerting_authorization'; -import { v4 as uuidv4 } from 'uuid'; -import { RecoveredActionGroup } from '../../common'; -import { NormalizedRuleType, RegistryRuleType } from '../rule_type_registry'; +import { AlertingAuthorization } from './alerting_authorization'; import { AlertingAuthorizationFilterType } from './alerting_authorization_kuery'; -import { schema } from '@kbn/config-schema'; - -const ruleTypeRegistry = ruleTypeRegistryMock.create(); -const features: jest.Mocked = featuresPluginMock.createStart(); -const request = {} as KibanaRequest; - -const getSpace = jest.fn(); -const getSpaceId = () => 'space1'; +import { httpServerMock } from '@kbn/core-http-server-mocks'; +import { CheckPrivilegesResponse } from '@kbn/security-plugin-types-server'; +import type { FeaturesPluginStart } from '@kbn/features-plugin/server'; +import { WriteOperations, AlertingAuthorizationEntity, ReadOperations } from './types'; +import { AlertingKibanaPrivilege } from '@kbn/features-plugin/common/alerting_kibana_privilege'; const mockAuthorizationAction = ( - type: string, - app: string, - alertingType: string, + ruleType: string, + consumer: string, + entity: string, operation: string -) => `${type}/${app}/${alertingType}/${operation}`; -function mockSecurity() { - const security = securityMock.createSetup(); - const authorization = security.authz; - // typescript is having trouble inferring jest's automocking - ( - authorization.actions.alerting.get as jest.MockedFunction< - typeof authorization.actions.alerting.get - > - ).mockImplementation(mockAuthorizationAction); - authorization.mode.useRbacForRequest.mockReturnValue(true); - return { authorization }; -} +) => `${ruleType}/${consumer}/${entity}/${operation}`; -function mockFeature(appName: string, typeName?: string | string[]) { - const typeNameArray = typeName ? (Array.isArray(typeName) ? typeName : [typeName]) : undefined; +function mockFeatureWithConsumers( + appName: string, + alertingFeatures?: AlertingKibanaPrivilege, + subFeature?: boolean +) { return new KibanaFeature({ id: appName, name: appName, app: [], category: { id: 'foo', label: 'foo' }, - ...(typeNameArray + ...(alertingFeatures ? { - alerting: typeNameArray, + alerting: alertingFeatures, } : {}), privileges: { all: { - ...(typeNameArray + ...(alertingFeatures ? { alerting: { rule: { - all: typeNameArray, + all: alertingFeatures, }, alert: { - all: typeNameArray, + all: alertingFeatures, }, }, } @@ -85,14 +63,14 @@ function mockFeature(appName: string, typeName?: string | string[]) { ui: [], }, read: { - ...(typeNameArray + ...(alertingFeatures ? { alerting: { rule: { - read: typeNameArray, + read: alertingFeatures, }, alert: { - read: typeNameArray, + read: alertingFeatures, }, }, } @@ -104,2480 +82,2219 @@ function mockFeature(appName: string, typeName?: string | string[]) { ui: [], }, }, - }); -} - -function mockFeatureWithSubFeature(appName: string, typeName: string) { - return new KibanaFeature({ - id: appName, - name: appName, - app: [], - category: { id: 'foo', label: 'foo' }, - ...(typeName + ...(subFeature ? { - alerting: [typeName], + subFeatures: [ + { + name: appName, + privilegeGroups: [ + { + groupType: 'independent', + privileges: [ + { + id: 'doSomethingAlertRelated', + name: 'sub feature alert', + includeIn: 'all', + alerting: { + rule: { + all: alertingFeatures, + }, + }, + savedObject: { + all: [], + read: [], + }, + ui: ['doSomethingAlertRelated'], + }, + { + id: 'doSomethingAlertRelated', + name: 'sub feature alert', + includeIn: 'read', + alerting: { + rule: { + read: alertingFeatures, + }, + }, + savedObject: { + all: [], + read: [], + }, + ui: ['doSomethingAlertRelated'], + }, + ], + }, + ], + }, + ], } : {}), - privileges: { - all: { - savedObject: { - all: [], - read: [], - }, - ui: [], - }, - read: { - savedObject: { - all: [], - read: [], - }, - ui: [], - }, - }, - subFeatures: [ - { - name: appName, - privilegeGroups: [ - { - groupType: 'independent', - privileges: [ - { - id: 'doSomethingAlertRelated', - name: 'sub feature alert', - includeIn: 'all', - alerting: { - rule: { - all: [typeName], - }, - }, - savedObject: { - all: [], - read: [], - }, - ui: ['doSomethingAlertRelated'], - }, - { - id: 'doSomethingAlertRelated', - name: 'sub feature alert', - includeIn: 'read', - alerting: { - rule: { - read: [typeName], - }, - }, - savedObject: { - all: [], - read: [], - }, - ui: ['doSomethingAlertRelated'], - }, - ], - }, - ], - }, - ], }); } -const myAppFeature = mockFeature('myApp', 'myType'); -const myOtherAppFeature = mockFeature('myOtherApp', 'myType'); -const myAppWithSubFeature = mockFeatureWithSubFeature('myAppWithSubFeature', 'myType'); -const myFeatureWithoutAlerting = mockFeature('myOtherApp'); - -beforeEach(() => { - jest.resetAllMocks(); - ruleTypeRegistry.get.mockImplementation((id) => ({ - id, - name: 'My Alert Type', - actionGroups: [{ id: 'default', name: 'Default' }], - defaultActionGroupId: 'default', - minimumLicenseRequired: 'basic', - isExportable: true, - recoveryActionGroup: RecoveredActionGroup, - async executor() { - return { state: {} }; - }, - category: 'test', - producer: 'myApp', - validate: { - params: schema.any(), - }, - validLegacyConsumers: [], - })); - features.getKibanaFeatures.mockReturnValue([ - myAppFeature, - myOtherAppFeature, - myAppWithSubFeature, - myFeatureWithoutAlerting, - ]); - getSpace.mockResolvedValue(undefined); -}); +type CheckPrivilegesResponseWithoutES = Omit & { + privileges: Omit; +}; describe('AlertingAuthorization', () => { - describe('constructor', () => { - test(`fetches the user's current space`, async () => { - const space = { - id: uuidv4(), - name: uuidv4(), - disabledFeatures: [], - }; - getSpace.mockResolvedValue(space); + const getSpace = jest.fn(); + const getSpaceId = () => 'space1'; + const allRegisteredConsumers = new Set(); + const ruleTypesConsumersMap = new Map>(); + + const checkPrivileges = jest.fn, []>(async () => ({ + username: 'elastic', + hasAllRequested: true, + privileges: { kibana: [] }, + })); + + const ruleTypeIds = ['rule-type-id-1', 'rule-type-id-2', 'rule-type-id-3', 'rule-type-id-4']; + + let request: KibanaRequest; + let ruleTypeRegistry = ruleTypeRegistryMock.create(); + let securityStart: ReturnType; + let features: jest.Mocked; + + beforeEach(() => { + jest.clearAllMocks(); + allRegisteredConsumers.clear(); + allRegisteredConsumers.clear(); + ruleTypesConsumersMap.clear(); + + securityStart = securityMock.createStart(); + securityStart.authz.mode.useRbacForRequest.mockReturnValue(true); + securityStart.authz.checkPrivilegesDynamicallyWithRequest.mockReturnValue(checkPrivileges); + request = httpServerMock.createKibanaRequest(); + getSpace.mockResolvedValue(undefined); + + features = featuresPluginMock.createStart(); + features.getKibanaFeatures.mockReturnValue([ + mockFeatureWithConsumers('feature-id-1', [ + { + ruleTypeId: 'rule-type-id-1', + consumers: ['alerts', 'consumer-a'], + }, + { ruleTypeId: 'rule-type-id-2', consumers: ['alerts', 'consumer-b'] }, + ]), + mockFeatureWithConsumers('feature-id-2', [ + { + ruleTypeId: 'rule-type-id-1', + consumers: ['alerts', 'consumer-b'], + }, + { + ruleTypeId: 'rule-type-id-3', + consumers: ['alerts', 'consumer-c'], + }, + ]), + mockFeatureWithConsumers('feature-id-3', [ + { + ruleTypeId: 'rule-type-id-4', + consumers: ['consumer-d'], + }, + ]), + ]); + + const alertingGet = securityStart.authz.actions.alerting.get as jest.Mock; + alertingGet.mockImplementation(mockAuthorizationAction); + + ruleTypeRegistry = ruleTypeRegistryMock.create(); + ruleTypeRegistry.getAllTypes.mockReturnValue(ruleTypeIds); + ruleTypeRegistry.has.mockImplementation((ruleTypeId: string) => + ruleTypeIds.includes(ruleTypeId) + ); + + // @ts-expect-error: only the id is needed for the tests + ruleTypeRegistry.get.mockImplementation((ruleTypeId: string) => ({ id: ruleTypeId })); + }); + + describe('create', () => { + beforeEach(() => { + jest.clearAllMocks(); + securityStart = securityMock.createStart(); + features = featuresPluginMock.createStart(); + + getSpace.mockReturnValue({ id: 'default', name: 'Default', disabledFeatures: [] }); + features.getKibanaFeatures.mockReturnValue([mockFeatureWithConsumers('my-feature-1')]); + }); + + it('creates an AlertingAuthorization object', async () => { + expect.assertions(2); - new AlertingAuthorization({ + const authPromise = AlertingAuthorization.create({ request, ruleTypeRegistry, + getSpaceId, features, getSpace, - getSpaceId, + authorization: securityStart.authz, }); - expect(getSpace).toHaveBeenCalledWith(request); + await expect(authPromise).resolves.toBeDefined(); + await expect(authPromise).resolves.not.toThrow(); }); - }); - describe('ensureAuthorized', () => { - test('is a no-op when there is no authorization api', async () => { - const alertAuthorization = new AlertingAuthorization({ + it('creates an AlertingAuthorization object without spaces', async () => { + getSpace.mockReturnValue(undefined); + expect.assertions(2); + + const authPromise = AlertingAuthorization.create({ request, ruleTypeRegistry, + getSpaceId, features, getSpace, - getSpaceId, + authorization: securityStart.authz, }); - await alertAuthorization.ensureAuthorized({ - ruleTypeId: 'myType', - consumer: 'myApp', - operation: WriteOperations.Create, - entity: AlertingAuthorizationEntity.Rule, + await expect(authPromise).resolves.toBeDefined(); + await expect(authPromise).resolves.not.toThrow(); + }); + + it('filters out disabled spaces and features without alerting', async () => { + getSpace.mockReturnValue({ + id: 'default', + name: 'Default', + disabledFeatures: ['my-feature-1'], }); - expect(ruleTypeRegistry.get).toHaveBeenCalledTimes(1); - }); + features.getKibanaFeatures.mockReturnValue([ + mockFeatureWithConsumers('my-feature-1', [ + { ruleTypeId: 'rule-type-1', consumers: ['consumer-a', 'consumer-b'] }, + ]), + mockFeatureWithConsumers('my-feature-2', [ + { ruleTypeId: 'rule-type-2', consumers: ['consumer-c', 'consumer-d'] }, + ]), + mockFeatureWithConsumers('my-feature-3'), + mockFeatureWithConsumers('my-feature-4', []), + ]); - test('is a no-op when the security license is disabled', async () => { - const { authorization } = mockSecurity(); - authorization.mode.useRbacForRequest.mockReturnValue(false); - const alertAuthorization = new AlertingAuthorization({ + const auth = await AlertingAuthorization.create({ request, ruleTypeRegistry, - authorization, + getSpaceId, features, getSpace, - getSpaceId, + authorization: securityStart.authz, }); - await alertAuthorization.ensureAuthorized({ - ruleTypeId: 'myType', - consumer: 'myApp', - operation: WriteOperations.Create, - entity: AlertingAuthorizationEntity.Rule, + // @ts-expect-error: allRegisteredConsumers is a private method of the auth class + expect(auth.allRegisteredConsumers).toMatchInlineSnapshot(` + Set { + "consumer-c", + "consumer-d", + } + `); + // @ts-expect-error: allRegisteredConsumers is a private method of the auth class + expect(auth.ruleTypesConsumersMap).toMatchInlineSnapshot(` + Map { + "rule-type-2" => Set { + "consumer-c", + "consumer-d", + }, + } + `); + }); + + it('removes duplicated consumers', async () => { + getSpace.mockReturnValue({ + id: 'default', + name: 'Default', + disabledFeatures: [], }); - expect(ruleTypeRegistry.get).toHaveBeenCalledTimes(1); - }); + features.getKibanaFeatures.mockReturnValue([ + mockFeatureWithConsumers('my-feature-1', [ + { ruleTypeId: 'rule-type-1', consumers: ['consumer-a', 'consumer-b', 'consumer-a'] }, + { ruleTypeId: 'rule-type-2', consumers: ['consumer-a', 'consumer-b', 'consumer-c'] }, + ]), + mockFeatureWithConsumers('my-feature-2', [ + { ruleTypeId: 'rule-type-2', consumers: ['consumer-a', 'consumer-b', 'consumer-c'] }, + ]), + ]); - test('ensures the user has privileges to execute rules for the specified rule type and operation without consumer when producer and consumer are the same', async () => { - const { authorization } = mockSecurity(); - const checkPrivileges: jest.MockedFunction< - ReturnType - > = jest.fn(); - authorization.checkPrivilegesDynamicallyWithRequest.mockReturnValue(checkPrivileges); - const alertAuthorization = new AlertingAuthorization({ + const auth = await AlertingAuthorization.create({ request, - authorization, ruleTypeRegistry, + getSpaceId, features, getSpace, - getSpaceId, + authorization: securityStart.authz, }); - checkPrivileges.mockResolvedValueOnce({ - username: 'some-user', - hasAllRequested: true, - privileges: { kibana: [] }, - }); + // @ts-expect-error: allRegisteredConsumers is a private method of the auth class + expect(auth.allRegisteredConsumers).toMatchInlineSnapshot(` + Set { + "consumer-a", + "consumer-b", + "consumer-c", + } + `); + }); - await alertAuthorization.ensureAuthorized({ - ruleTypeId: 'myType', - consumer: 'myApp', - operation: WriteOperations.Create, - entity: AlertingAuthorizationEntity.Rule, + it('removes duplicated ruleTypes and consumers', async () => { + getSpace.mockReturnValue({ + id: 'default', + name: 'Default', + disabledFeatures: [], }); - expect(ruleTypeRegistry.get).toHaveBeenCalledWith('myType'); - - expect(authorization.actions.alerting.get).toHaveBeenCalledTimes(1); - expect(authorization.actions.alerting.get).toHaveBeenCalledWith( - 'myType', - 'myApp', - 'rule', - 'create' - ); - expect(checkPrivileges).toHaveBeenCalledWith({ - kibana: [mockAuthorizationAction('myType', 'myApp', 'rule', 'create')], - }); - }); + features.getKibanaFeatures.mockReturnValue([ + mockFeatureWithConsumers('my-feature-1', [ + { ruleTypeId: 'rule-type-1', consumers: ['consumer-a', 'consumer-b', 'consumer-a'] }, + { ruleTypeId: 'rule-type-2', consumers: ['consumer-a', 'consumer-b', 'consumer-c'] }, + ]), + mockFeatureWithConsumers('my-feature-2', [ + { ruleTypeId: 'rule-type-2', consumers: ['consumer-a', 'consumer-b', 'consumer-e'] }, + { ruleTypeId: 'rule-type-1', consumers: ['consumer-a', 'consumer-b', 'consumer-d'] }, + ]), + ]); - test('ensures the user has privileges to execute alerts for the specified rule type and operation without consumer when producer and consumer are the same', async () => { - const { authorization } = mockSecurity(); - const checkPrivileges: jest.MockedFunction< - ReturnType - > = jest.fn(); - authorization.checkPrivilegesDynamicallyWithRequest.mockReturnValue(checkPrivileges); - const alertAuthorization = new AlertingAuthorization({ + const auth = await AlertingAuthorization.create({ request, - authorization, ruleTypeRegistry, + getSpaceId, features, getSpace, - getSpaceId, - }); - - checkPrivileges.mockResolvedValueOnce({ - username: 'some-user', - hasAllRequested: true, - privileges: { kibana: [] }, + authorization: securityStart.authz, }); - await alertAuthorization.ensureAuthorized({ - ruleTypeId: 'myType', - consumer: 'myApp', - operation: WriteOperations.Update, - entity: AlertingAuthorizationEntity.Alert, - }); + // @ts-expect-error: ruleTypesConsumersMap is a private method of the auth class + expect(auth.ruleTypesConsumersMap).toMatchInlineSnapshot(` + Map { + "rule-type-1" => Set { + "consumer-a", + "consumer-b", + "consumer-d", + }, + "rule-type-2" => Set { + "consumer-a", + "consumer-b", + "consumer-c", + "consumer-e", + }, + } + `); + }); - expect(ruleTypeRegistry.get).toHaveBeenCalledWith('myType'); + it('throws an error when a generic error occurs', async () => { + expect.assertions(1); - expect(authorization.actions.alerting.get).toHaveBeenCalledTimes(1); - expect(authorization.actions.alerting.get).toHaveBeenCalledWith( - 'myType', - 'myApp', - 'alert', - 'update' - ); - expect(checkPrivileges).toHaveBeenCalledWith({ - kibana: [mockAuthorizationAction('myType', 'myApp', 'alert', 'update')], - }); - }); + getSpace.mockRejectedValue(new Error('Error')); - test('ensures the user has privileges to execute rules for the specified rule type and operation without consumer when consumer is alerts', async () => { - const { authorization } = mockSecurity(); - const checkPrivileges: jest.MockedFunction< - ReturnType - > = jest.fn(); - authorization.checkPrivilegesDynamicallyWithRequest.mockReturnValue(checkPrivileges); - const alertAuthorization = new AlertingAuthorization({ + const authPromise = AlertingAuthorization.create({ request, - authorization, ruleTypeRegistry, + getSpaceId, features, getSpace, - getSpaceId, + authorization: securityStart.authz, }); - checkPrivileges.mockResolvedValueOnce({ - username: 'some-user', - hasAllRequested: true, - privileges: { kibana: [] }, - }); + await expect(authPromise).rejects.toThrow(); + }); - await alertAuthorization.ensureAuthorized({ - ruleTypeId: 'myType', - consumer: 'alerts', - operation: WriteOperations.Create, - entity: AlertingAuthorizationEntity.Rule, - }); + it.each([403, 404])( + `construct the AlertingAuthorization with empty features if the error is boom and %s`, + async (errorStatusCode: number) => { + getSpace.mockRejectedValue( + new Boom.Boom('Server error', { + statusCode: errorStatusCode, + message: 'my error message', + }) + ); + + const auth = await AlertingAuthorization.create({ + request, + ruleTypeRegistry, + getSpaceId, + features, + getSpace, + authorization: securityStart.authz, + }); + + // @ts-expect-error: allRegisteredConsumers is a private method of the auth class + expect(auth.ruleTypesConsumersMap).toMatchInlineSnapshot(`Map {}`); + // @ts-expect-error: allRegisteredConsumers is a private method of the auth class + expect(auth.allRegisteredConsumers).toMatchInlineSnapshot(`Set {}`); + } + ); - expect(ruleTypeRegistry.get).toHaveBeenCalledWith('myType'); + it('throws an error if the error is boom but not 403', async () => { + expect.assertions(1); - expect(authorization.actions.alerting.get).toHaveBeenCalledTimes(1); - expect(authorization.actions.alerting.get).toHaveBeenCalledWith( - 'myType', - 'myApp', - 'rule', - 'create' + getSpace.mockRejectedValue( + new Boom.Boom('Server error', { statusCode: 400, message: 'my error message' }) ); - expect(checkPrivileges).toHaveBeenCalledWith({ - kibana: [mockAuthorizationAction('myType', 'myApp', 'rule', 'create')], - }); - }); - test('ensures the user has privileges to execute alerts for the specified rule type and operation without consumer when consumer is alerts', async () => { - const { authorization } = mockSecurity(); - const checkPrivileges: jest.MockedFunction< - ReturnType - > = jest.fn(); - authorization.checkPrivilegesDynamicallyWithRequest.mockReturnValue(checkPrivileges); - const alertAuthorization = new AlertingAuthorization({ + const authPromise = AlertingAuthorization.create({ request, - authorization, ruleTypeRegistry, + getSpaceId, features, getSpace, - getSpaceId, - }); - - checkPrivileges.mockResolvedValueOnce({ - username: 'some-user', - hasAllRequested: true, - privileges: { kibana: [] }, - }); - - await alertAuthorization.ensureAuthorized({ - ruleTypeId: 'myType', - consumer: 'alerts', - operation: WriteOperations.Update, - entity: AlertingAuthorizationEntity.Alert, + authorization: securityStart.authz, }); - expect(ruleTypeRegistry.get).toHaveBeenCalledWith('myType'); - - expect(authorization.actions.alerting.get).toHaveBeenCalledTimes(1); - expect(authorization.actions.alerting.get).toHaveBeenCalledWith( - 'myType', - 'myApp', - 'alert', - 'update' - ); - expect(checkPrivileges).toHaveBeenCalledWith({ - kibana: [mockAuthorizationAction('myType', 'myApp', 'alert', 'update')], - }); + await expect(authPromise).rejects.toThrow(); }); + }); - test('ensures the user has privileges to execute rules for the specified rule type, operation and producer when producer is different from consumer', async () => { - const { authorization } = mockSecurity(); - const checkPrivileges: jest.MockedFunction< - ReturnType - > = jest.fn(); - authorization.checkPrivilegesDynamicallyWithRequest.mockReturnValue(checkPrivileges); - checkPrivileges.mockResolvedValueOnce({ - username: 'some-user', - hasAllRequested: true, - privileges: { kibana: [] }, - }); + describe('ensureAuthorized', () => { + beforeEach(() => { + jest.clearAllMocks(); + allRegisteredConsumers.clear(); + allRegisteredConsumers.add('myApp'); + }); + it('is a no-op when there is no authorization api', async () => { const alertAuthorization = new AlertingAuthorization({ request, - authorization, ruleTypeRegistry, - features, - getSpace, getSpaceId, + allRegisteredConsumers, + ruleTypesConsumersMap, }); await alertAuthorization.ensureAuthorized({ ruleTypeId: 'myType', - consumer: 'myOtherApp', + consumer: 'myApp', operation: WriteOperations.Create, entity: AlertingAuthorizationEntity.Rule, }); - expect(ruleTypeRegistry.get).toHaveBeenCalledWith('myType'); - - expect(authorization.actions.alerting.get).toHaveBeenCalledTimes(1); - expect(authorization.actions.alerting.get).toHaveBeenCalledWith( - 'myType', - 'myOtherApp', - 'rule', - 'create' - ); - expect(checkPrivileges).toHaveBeenCalledWith({ - kibana: [mockAuthorizationAction('myType', 'myOtherApp', 'rule', 'create')], - }); + expect(checkPrivileges).not.toHaveBeenCalled(); }); - test('ensures the user has privileges to execute alerts for the specified rule type, operation and producer when producer is different from consumer', async () => { - const { authorization } = mockSecurity(); - const checkPrivileges: jest.MockedFunction< - ReturnType - > = jest.fn(); - authorization.checkPrivilegesDynamicallyWithRequest.mockReturnValue(checkPrivileges); - checkPrivileges.mockResolvedValueOnce({ - username: 'some-user', - hasAllRequested: true, - privileges: { kibana: [] }, - }); + it('is a no-op when the security license is disabled', async () => { + securityStart.authz.mode.useRbacForRequest.mockReturnValue(false); const alertAuthorization = new AlertingAuthorization({ request, - authorization, ruleTypeRegistry, - features, - getSpace, + authorization: securityStart.authz, getSpaceId, + allRegisteredConsumers, + ruleTypesConsumersMap, }); await alertAuthorization.ensureAuthorized({ ruleTypeId: 'myType', - consumer: 'myOtherApp', - operation: WriteOperations.Update, - entity: AlertingAuthorizationEntity.Alert, + consumer: 'myApp', + operation: WriteOperations.Create, + entity: AlertingAuthorizationEntity.Rule, }); - expect(ruleTypeRegistry.get).toHaveBeenCalledWith('myType'); - - expect(authorization.actions.alerting.get).toHaveBeenCalledTimes(1); - expect(authorization.actions.alerting.get).toHaveBeenCalledWith( - 'myType', - 'myOtherApp', - 'alert', - 'update' - ); - expect(checkPrivileges).toHaveBeenCalledWith({ - kibana: [mockAuthorizationAction('myType', 'myOtherApp', 'alert', 'update')], - }); + expect(checkPrivileges).not.toHaveBeenCalled(); }); - test('ensures the producer is used for authorization if the consumer is `alerts`', async () => { - const { authorization } = mockSecurity(); - const checkPrivileges: jest.MockedFunction< - ReturnType - > = jest.fn(); - authorization.checkPrivilegesDynamicallyWithRequest.mockReturnValue(checkPrivileges); - checkPrivileges.mockResolvedValueOnce({ - username: 'some-user', - hasAllRequested: true, - privileges: { kibana: [] }, - }); - + it('authorized correctly', async () => { const alertAuthorization = new AlertingAuthorization({ request, - authorization, ruleTypeRegistry, - features, - getSpace, + authorization: securityStart.authz, getSpaceId, + allRegisteredConsumers, + ruleTypesConsumersMap, }); await alertAuthorization.ensureAuthorized({ ruleTypeId: 'myType', - consumer: 'alerts', + consumer: 'myApp', operation: WriteOperations.Create, entity: AlertingAuthorizationEntity.Rule, }); - expect(ruleTypeRegistry.get).toHaveBeenCalledWith('myType'); + expect(checkPrivileges).toBeCalledTimes(1); + expect(checkPrivileges.mock.calls[0]).toMatchInlineSnapshot(` + Array [ + Object { + "kibana": Array [ + "myType/myApp/rule/create", + ], + }, + ] + `); + }); - expect(authorization.actions.alerting.get).toHaveBeenCalledTimes(1); - expect(authorization.actions.alerting.get).toHaveBeenCalledWith( - 'myType', - 'myApp', - 'rule', - 'create' + it('throws if user lacks the required rule privileges for the consumer', async () => { + securityStart.authz.checkPrivilegesDynamicallyWithRequest.mockReturnValue( + jest.fn(async () => ({ hasAllRequested: false })) ); - expect(checkPrivileges).toHaveBeenCalledWith({ - kibana: [mockAuthorizationAction('myType', 'myApp', 'rule', 'create')], - }); - }); - test('throws if user lacks the required rule privileges for the consumer', async () => { - const { authorization } = mockSecurity(); - const checkPrivileges: jest.MockedFunction< - ReturnType - > = jest.fn(); - authorization.checkPrivilegesDynamicallyWithRequest.mockReturnValue(checkPrivileges); const alertAuthorization = new AlertingAuthorization({ request, - authorization, ruleTypeRegistry, - features, - getSpace, + authorization: securityStart.authz, getSpaceId, - }); - - checkPrivileges.mockResolvedValueOnce({ - username: 'some-user', - hasAllRequested: false, - privileges: { - kibana: [ - { - privilege: mockAuthorizationAction('myType', 'myOtherApp', 'rule', 'create'), - authorized: false, - }, - { - privilege: mockAuthorizationAction('myType', 'myApp', 'rule', 'create'), - authorized: true, - }, - ], - }, + allRegisteredConsumers, + ruleTypesConsumersMap, }); await expect( alertAuthorization.ensureAuthorized({ ruleTypeId: 'myType', - consumer: 'myOtherApp', + consumer: 'myApp', operation: WriteOperations.Create, entity: AlertingAuthorizationEntity.Rule, }) ).rejects.toThrowErrorMatchingInlineSnapshot( - `"Unauthorized by \\"myOtherApp\\" to create \\"myType\\" rule"` + `"Unauthorized by \\"myApp\\" to create \\"myType\\" rule"` ); }); - test('throws if user lacks the required alert privileges for the consumer', async () => { - const { authorization } = mockSecurity(); - const checkPrivileges: jest.MockedFunction< - ReturnType - > = jest.fn(); - authorization.checkPrivilegesDynamicallyWithRequest.mockReturnValue(checkPrivileges); + it('throws if user lacks the required alert privileges for the consumer', async () => { + securityStart.authz.checkPrivilegesDynamicallyWithRequest.mockReturnValue( + jest.fn(async () => ({ hasAllRequested: false })) + ); + const alertAuthorization = new AlertingAuthorization({ request, - authorization, ruleTypeRegistry, - features, - getSpace, + authorization: securityStart.authz, getSpaceId, - }); - - checkPrivileges.mockResolvedValueOnce({ - username: 'some-user', - hasAllRequested: false, - privileges: { - kibana: [ - { - privilege: mockAuthorizationAction('myType', 'myOtherApp', 'alert', 'update'), - authorized: false, - }, - { - privilege: mockAuthorizationAction('myType', 'myApp', 'alert', 'update'), - authorized: true, - }, - { - privilege: mockAuthorizationAction('myType', 'myAppRulesOnly', 'alert', 'update'), - authorized: false, - }, - ], - }, + allRegisteredConsumers, + ruleTypesConsumersMap, }); await expect( alertAuthorization.ensureAuthorized({ ruleTypeId: 'myType', - consumer: 'myAppRulesOnly', + consumer: 'myApp', operation: WriteOperations.Update, entity: AlertingAuthorizationEntity.Alert, }) ).rejects.toThrowErrorMatchingInlineSnapshot( - `"Unauthorized by \\"myAppRulesOnly\\" to update \\"myType\\" alert"` + `"Unauthorized by \\"myApp\\" to update \\"myType\\" alert"` ); }); - test('throws if user lacks the required privileges for the producer', async () => { - const { authorization } = mockSecurity(); - const checkPrivileges: jest.MockedFunction< - ReturnType - > = jest.fn(); - authorization.checkPrivilegesDynamicallyWithRequest.mockReturnValue(checkPrivileges); + it('throws if the user has access but the consumer is not registered', async () => { const alertAuthorization = new AlertingAuthorization({ request, - authorization, ruleTypeRegistry, - features, - getSpace, + authorization: securityStart.authz, getSpaceId, - }); - - checkPrivileges.mockResolvedValueOnce({ - username: 'some-user', - hasAllRequested: false, - privileges: { - kibana: [ - { - privilege: mockAuthorizationAction('myType', 'myOtherApp', 'alert', 'update'), - authorized: true, - }, - { - privilege: mockAuthorizationAction('myType', 'myApp', 'alert', 'update'), - authorized: false, - }, - ], - }, + allRegisteredConsumers, + ruleTypesConsumersMap, }); await expect( alertAuthorization.ensureAuthorized({ ruleTypeId: 'myType', - consumer: 'myOtherApp', - operation: WriteOperations.Update, - entity: AlertingAuthorizationEntity.Alert, + consumer: 'not-exist', + operation: WriteOperations.Create, + entity: AlertingAuthorizationEntity.Rule, }) ).rejects.toThrowErrorMatchingInlineSnapshot( - `"Unauthorized by \\"myOtherApp\\" to update \\"myType\\" alert"` + `"Unauthorized by \\"not-exist\\" to create \\"myType\\" rule"` ); }); - test('throws if user lacks the required privileges for both consumer and producer', async () => { - const { authorization } = mockSecurity(); - const checkPrivileges: jest.MockedFunction< - ReturnType - > = jest.fn(); - authorization.checkPrivilegesDynamicallyWithRequest.mockReturnValue(checkPrivileges); + it('throws when there is no authorization api but the consumer is not registered', async () => { const alertAuthorization = new AlertingAuthorization({ request, - authorization, ruleTypeRegistry, - features, - getSpace, getSpaceId, - }); - - checkPrivileges.mockResolvedValueOnce({ - username: 'some-user', - hasAllRequested: false, - privileges: { - kibana: [ - { - privilege: mockAuthorizationAction('myType', 'myOtherApp', 'alert', 'create'), - authorized: false, - }, - { - privilege: mockAuthorizationAction('myType', 'myApp', 'alert', 'create'), - authorized: false, - }, - ], - }, + allRegisteredConsumers, + ruleTypesConsumersMap, }); await expect( alertAuthorization.ensureAuthorized({ ruleTypeId: 'myType', - consumer: 'myOtherApp', + consumer: 'not-exist', operation: WriteOperations.Create, - entity: AlertingAuthorizationEntity.Alert, + entity: AlertingAuthorizationEntity.Rule, }) ).rejects.toThrowErrorMatchingInlineSnapshot( - `"Unauthorized by \\"myOtherApp\\" to create \\"myType\\" alert"` + `"Unauthorized by \\"not-exist\\" to create \\"myType\\" rule"` ); }); - test('checks additional privileges correctly', async () => { - const { authorization } = mockSecurity(); - const checkPrivileges: jest.MockedFunction< - ReturnType - > = jest.fn(); - authorization.checkPrivilegesDynamicallyWithRequest.mockReturnValue(checkPrivileges); + it('throws when the security license is disabled but the consumer is not registered', async () => { + securityStart.authz.mode.useRbacForRequest.mockReturnValue(false); + const alertAuthorization = new AlertingAuthorization({ request, - authorization, ruleTypeRegistry, - features, - getSpace, getSpaceId, + allRegisteredConsumers, + ruleTypesConsumersMap, }); - checkPrivileges.mockResolvedValueOnce({ - username: 'some-user', - hasAllRequested: true, - privileges: { kibana: [] }, - }); - - await alertAuthorization.ensureAuthorized({ - ruleTypeId: 'myType', - consumer: 'myApp', - operation: WriteOperations.Create, - entity: AlertingAuthorizationEntity.Rule, - additionalPrivileges: ['test/create'], - }); + await expect( + alertAuthorization.ensureAuthorized({ + ruleTypeId: 'myType', + consumer: 'not-exist', + operation: WriteOperations.Create, + entity: AlertingAuthorizationEntity.Rule, + }) + ).rejects.toThrowErrorMatchingInlineSnapshot( + `"Unauthorized by \\"not-exist\\" to create \\"myType\\" rule"` + ); + }); - expect(ruleTypeRegistry.get).toHaveBeenCalledWith('myType'); + it('throws an error when the consumer does not exist because it was from a disabled plugin', async () => { + features.getKibanaFeatures.mockReturnValue([ + mockFeatureWithConsumers('my-feature-1', [ + { ruleTypeId: 'rule-type-1', consumers: ['disabled-feature-consumer'] }, + ]), + mockFeatureWithConsumers('my-feature-2', [ + { ruleTypeId: 'rule-type-2', consumers: ['enabled-feature-consumer'] }, + ]), + ]); - expect(authorization.actions.alerting.get).toHaveBeenCalledTimes(1); - expect(authorization.actions.alerting.get).toHaveBeenCalledWith( - 'myType', - 'myApp', - 'rule', - 'create' - ); - expect(checkPrivileges).toHaveBeenCalledWith({ - kibana: [mockAuthorizationAction('myType', 'myApp', 'rule', 'create'), 'test/create'], + getSpace.mockReturnValue({ + id: 'default', + name: 'Default', + disabledFeatures: ['my-feature-1'], }); - }); - }); - describe('getFindAuthorizationFilter', () => { - const myOtherAppAlertType: RegistryRuleType = { - actionGroups: [], - actionVariables: undefined, - defaultActionGroupId: 'default', - minimumLicenseRequired: 'basic', - isExportable: true, - recoveryActionGroup: RecoveredActionGroup, - id: 'myOtherAppAlertType', - name: 'myOtherAppAlertType', - category: 'test', - producer: 'alerts', - enabledInLicense: true, - hasAlertsMappings: false, - hasFieldsForAAD: false, - validLegacyConsumers: [], - }; - const myAppAlertType: RegistryRuleType = { - actionGroups: [], - actionVariables: undefined, - defaultActionGroupId: 'default', - minimumLicenseRequired: 'basic', - isExportable: true, - recoveryActionGroup: RecoveredActionGroup, - id: 'myAppAlertType', - name: 'myAppAlertType', - category: 'test', - producer: 'myApp', - enabledInLicense: true, - hasAlertsMappings: false, - hasFieldsForAAD: false, - validLegacyConsumers: [], - }; - const mySecondAppAlertType: RegistryRuleType = { - actionGroups: [], - actionVariables: undefined, - defaultActionGroupId: 'default', - minimumLicenseRequired: 'basic', - isExportable: true, - recoveryActionGroup: RecoveredActionGroup, - id: 'mySecondAppAlertType', - name: 'mySecondAppAlertType', - category: 'test', - producer: 'myApp', - enabledInLicense: true, - hasAlertsMappings: false, - hasFieldsForAAD: false, - validLegacyConsumers: [], - }; - const setOfAlertTypes = new Set([myAppAlertType, myOtherAppAlertType, mySecondAppAlertType]); - test('omits filter when there is no authorization api', async () => { - const alertAuthorization = new AlertingAuthorization({ + const auth = await AlertingAuthorization.create({ request, ruleTypeRegistry, - features, - getSpace, getSpaceId, - }); - const { filter, ensureRuleTypeIsAuthorized } = - await alertAuthorization.getFindAuthorizationFilter(AlertingAuthorizationEntity.Rule, { - type: AlertingAuthorizationFilterType.KQL, - fieldNames: { - ruleTypeId: 'ruleId', - consumer: 'consumer', - }, - }); - expect(() => ensureRuleTypeIsAuthorized('someMadeUpType', 'myApp', 'rule')).not.toThrow(); - expect(filter).toEqual(undefined); - }); - test('ensureRuleTypeIsAuthorized is no-op when there is no authorization api', async () => { - const alertAuthorization = new AlertingAuthorization({ - request, - ruleTypeRegistry, features, getSpace, - getSpaceId, + authorization: securityStart.authz, }); - const { ensureRuleTypeIsAuthorized } = await alertAuthorization.getFindAuthorizationFilter( - AlertingAuthorizationEntity.Rule, - { - type: AlertingAuthorizationFilterType.KQL, - fieldNames: { - ruleTypeId: 'ruleId', - consumer: 'consumer', - }, - } + + await expect( + auth.ensureAuthorized({ + ruleTypeId: 'rule-type-1', + consumer: 'disabled-feature-consumer', + operation: WriteOperations.Create, + entity: AlertingAuthorizationEntity.Rule, + }) + ).rejects.toThrowErrorMatchingInlineSnapshot( + `"Unauthorized by \\"disabled-feature-consumer\\" to create \\"rule-type-1\\" rule"` ); - ensureRuleTypeIsAuthorized('someMadeUpType', 'myApp', 'rule'); }); - test('creates a filter based on the privileged types', async () => { - features.getKibanaFeatures.mockReturnValue([ - mockFeature('myApp', ['myAppAlertType', 'mySecondAppAlertType']), - mockFeature('alerts', 'myOtherAppAlertType'), - myOtherAppFeature, - myAppWithSubFeature, - ]); - const { authorization } = mockSecurity(); - const checkPrivileges: jest.MockedFunction< - ReturnType - > = jest.fn(); - authorization.checkPrivilegesDynamicallyWithRequest.mockReturnValue(checkPrivileges); - checkPrivileges.mockResolvedValueOnce({ - username: 'some-user', - hasAllRequested: true, - privileges: { kibana: [] }, - }); + + it('checks additional privileges correctly', async () => { const alertAuthorization = new AlertingAuthorization({ request, - authorization, ruleTypeRegistry, - features, - getSpace, + authorization: securityStart.authz, getSpaceId, + allRegisteredConsumers, + ruleTypesConsumersMap, }); - ruleTypeRegistry.list.mockReturnValue(setOfAlertTypes); - const filter = ( - await alertAuthorization.getFindAuthorizationFilter(AlertingAuthorizationEntity.Rule, { - type: AlertingAuthorizationFilterType.KQL, - fieldNames: { - ruleTypeId: 'path.to.rule_type_id', - consumer: 'consumer-field', - }, - }) - ).filter; + await alertAuthorization.ensureAuthorized({ + ruleTypeId: 'myType', + consumer: 'myApp', + operation: WriteOperations.Create, + entity: AlertingAuthorizationEntity.Rule, + additionalPrivileges: ['test/create'], + }); - expect(toKqlExpression(filter as KueryNode)).toMatchInlineSnapshot( - `"((path.to.rule_type_id: myAppAlertType AND (consumer-field: alerts OR consumer-field: discover OR consumer-field: myApp OR consumer-field: myOtherApp OR consumer-field: myAppWithSubFeature)) OR (path.to.rule_type_id: mySecondAppAlertType AND (consumer-field: alerts OR consumer-field: discover OR consumer-field: myApp OR consumer-field: myOtherApp OR consumer-field: myAppWithSubFeature)) OR (path.to.rule_type_id: myOtherAppAlertType AND (consumer-field: alerts OR consumer-field: discover OR consumer-field: myApp OR consumer-field: myOtherApp OR consumer-field: myAppWithSubFeature)))"` - ); + expect(checkPrivileges).toBeCalledTimes(1); + expect(checkPrivileges.mock.calls[0]).toMatchInlineSnapshot(` + Array [ + Object { + "kibana": Array [ + "myType/myApp/rule/create", + "test/create", + ], + }, + ] + `); }); - test('throws if user has no privileges to any rule type', async () => { - const { authorization } = mockSecurity(); - const checkPrivileges: jest.MockedFunction< - ReturnType - > = jest.fn(); - authorization.checkPrivilegesDynamicallyWithRequest.mockReturnValue(checkPrivileges); - checkPrivileges.mockResolvedValueOnce({ - username: 'some-user', - hasAllRequested: false, - privileges: { - kibana: [ - { - privilege: mockAuthorizationAction('myType', 'myOtherApp', 'rule', 'create'), - authorized: false, - }, - { - privilege: mockAuthorizationAction('myType', 'myApp', 'rule', 'create'), - authorized: false, - }, - ], - }, - }); - const alertAuthorization = new AlertingAuthorization({ + }); + + describe('getFindAuthorizationFilter', () => { + it('creates a filter based on the privileged types', async () => { + const auth = await AlertingAuthorization.create({ request, - authorization, ruleTypeRegistry, + getSpaceId, features, getSpace, - getSpaceId, + authorization: securityStart.authz, }); - ruleTypeRegistry.list.mockReturnValue(setOfAlertTypes); - await expect( - alertAuthorization.getFindAuthorizationFilter(AlertingAuthorizationEntity.Rule, { - type: AlertingAuthorizationFilterType.KQL, - fieldNames: { - ruleTypeId: 'path.to.rule_type_id', - consumer: 'consumer-field', - }, - }) - ).rejects.toThrowErrorMatchingInlineSnapshot( - `"Unauthorized to find rules for any rule types"` - ); - }); - test('creates an `ensureRuleTypeIsAuthorized` function which throws if type is unauthorized', async () => { - features.getKibanaFeatures.mockReturnValue([ - mockFeature('myApp', ['myOtherAppAlertType', 'myAppAlertType']), - mockFeature('myOtherApp', ['myOtherAppAlertType', 'myAppAlertType']), - ]); - const { authorization } = mockSecurity(); - const checkPrivileges: jest.MockedFunction< - ReturnType - > = jest.fn(); - authorization.checkPrivilegesDynamicallyWithRequest.mockReturnValue(checkPrivileges); + checkPrivileges.mockResolvedValueOnce({ username: 'some-user', - hasAllRequested: false, + hasAllRequested: true, privileges: { kibana: [ { - privilege: mockAuthorizationAction('myOtherAppAlertType', 'myApp', 'alert', 'find'), + privilege: mockAuthorizationAction('rule-type-id-1', 'alerts', 'rule', 'find'), authorized: true, }, { - privilege: mockAuthorizationAction( - 'myOtherAppAlertType', - 'myOtherApp', - 'alert', - 'find' - ), - authorized: false, + privilege: mockAuthorizationAction('rule-type-id-1', 'consumer-a', 'rule', 'find'), + authorized: true, }, { - privilege: mockAuthorizationAction('myAppAlertType', 'myApp', 'alert', 'find'), + privilege: mockAuthorizationAction('rule-type-id-1', 'consumer-b', 'rule', 'find'), authorized: true, }, { - privilege: mockAuthorizationAction('myAppAlertType', 'myOtherApp', 'alert', 'find'), - authorized: false, + privilege: mockAuthorizationAction('rule-type-id-2', 'alerts', 'rule', 'find'), + authorized: true, }, - ], - }, - }); - const alertAuthorization = new AlertingAuthorization({ - request, - authorization, - ruleTypeRegistry, - features, - getSpace, - getSpaceId, - }); - ruleTypeRegistry.list.mockReturnValue(setOfAlertTypes); - const { ensureRuleTypeIsAuthorized } = await alertAuthorization.getFindAuthorizationFilter( - AlertingAuthorizationEntity.Alert, - { - type: AlertingAuthorizationFilterType.KQL, - fieldNames: { - ruleTypeId: 'ruleId', - consumer: 'consumer', - }, - } - ); - expect(() => { - ensureRuleTypeIsAuthorized('myAppAlertType', 'myOtherApp', 'alert'); - }).toThrowErrorMatchingInlineSnapshot( - `"Unauthorized by \\"myOtherApp\\" to find \\"myAppAlertType\\" alert"` - ); - }); - test('creates an `ensureRuleTypeIsAuthorized` function which is no-op if type is authorized', async () => { - features.getKibanaFeatures.mockReturnValue([ - mockFeature('myApp', ['myOtherAppAlertType', 'myAppAlertType']), - mockFeature('myOtherApp', 'myAppAlertType'), - ]); - const { authorization } = mockSecurity(); - const checkPrivileges: jest.MockedFunction< - ReturnType - > = jest.fn(); - authorization.checkPrivilegesDynamicallyWithRequest.mockReturnValue(checkPrivileges); - checkPrivileges.mockResolvedValueOnce({ - username: 'some-user', - hasAllRequested: false, - privileges: { - kibana: [ { - privilege: mockAuthorizationAction('myOtherAppAlertType', 'myApp', 'rule', 'find'), + privilege: mockAuthorizationAction('rule-type-id-2', 'consumer-b', 'rule', 'find'), authorized: true, }, { - privilege: mockAuthorizationAction( - 'myOtherAppAlertType', - 'myOtherApp', - 'rule', - 'find' - ), - authorized: false, + privilege: mockAuthorizationAction('rule-type-id-3', 'consumer-c', 'rule', 'find'), + authorized: true, }, { - privilege: mockAuthorizationAction('myAppAlertType', 'myApp', 'rule', 'find'), + privilege: mockAuthorizationAction('rule-type-id-3', 'alerts', 'rule', 'find'), authorized: true, }, { - privilege: mockAuthorizationAction('myAppAlertType', 'myOtherApp', 'rule', 'find'), - authorized: true, + privilege: mockAuthorizationAction('rule-type-id-3', 'consumer-d', 'rule', 'find'), + authorized: false, }, ], }, }); - const alertAuthorization = new AlertingAuthorization({ - request, - authorization, - ruleTypeRegistry, - features, - getSpace, - getSpaceId, - }); - ruleTypeRegistry.list.mockReturnValue(setOfAlertTypes); - const { ensureRuleTypeIsAuthorized } = await alertAuthorization.getFindAuthorizationFilter( - AlertingAuthorizationEntity.Rule, - { - type: AlertingAuthorizationFilterType.KQL, - fieldNames: { - ruleTypeId: 'ruleId', - consumer: 'consumer', + + const filter = ( + await auth.getFindAuthorizationFilter({ + authorizationEntity: AlertingAuthorizationEntity.Rule, + filterOpts: { + type: AlertingAuthorizationFilterType.KQL, + fieldNames: { + ruleTypeId: 'path.to.rule_type_id', + consumer: 'consumer-field', + }, }, - } + }) + ).filter; + + expect(checkPrivileges).toBeCalledTimes(1); + expect(checkPrivileges.mock.calls[0]).toMatchInlineSnapshot(` + Array [ + Object { + "kibana": Array [ + "rule-type-id-1/alerts/rule/find", + "rule-type-id-1/consumer-a/rule/find", + "rule-type-id-1/consumer-b/rule/find", + "rule-type-id-2/alerts/rule/find", + "rule-type-id-2/consumer-b/rule/find", + "rule-type-id-3/alerts/rule/find", + "rule-type-id-3/consumer-c/rule/find", + "rule-type-id-4/consumer-d/rule/find", + ], + }, + ] + `); + + expect(toKqlExpression(filter as KueryNode)).toMatchInlineSnapshot( + `"((path.to.rule_type_id: rule-type-id-1 AND (consumer-field: alerts OR consumer-field: consumer-a OR consumer-field: consumer-b)) OR (path.to.rule_type_id: rule-type-id-2 AND (consumer-field: alerts OR consumer-field: consumer-b)) OR (path.to.rule_type_id: rule-type-id-3 AND (consumer-field: consumer-c OR consumer-field: alerts)))"` ); - expect(() => { - ensureRuleTypeIsAuthorized('myAppAlertType', 'myOtherApp', 'rule'); - }).not.toThrow(); }); - test('creates an `logSuccessfulAuthorization` function which logs every authorized type', async () => { - features.getKibanaFeatures.mockReturnValue([ - mockFeature('myApp', ['myOtherAppAlertType', 'myAppAlertType', 'mySecondAppAlertType']), - mockFeature('myOtherApp', ['mySecondAppAlertType', 'myAppAlertType']), - ]); - const { authorization } = mockSecurity(); - const checkPrivileges: jest.MockedFunction< - ReturnType - > = jest.fn(); - authorization.checkPrivilegesDynamicallyWithRequest.mockReturnValue(checkPrivileges); + + it('does not throw if the rule type is authorized', async () => { checkPrivileges.mockResolvedValueOnce({ username: 'some-user', - hasAllRequested: false, + hasAllRequested: true, privileges: { kibana: [ { - privilege: mockAuthorizationAction('myOtherAppAlertType', 'myApp', 'rule', 'find'), - authorized: true, - }, - { - privilege: mockAuthorizationAction( - 'myOtherAppAlertType', - 'myOtherApp', - 'rule', - 'find' - ), - authorized: false, - }, - { - privilege: mockAuthorizationAction('myAppAlertType', 'myApp', 'rule', 'find'), - authorized: true, - }, - { - privilege: mockAuthorizationAction('myAppAlertType', 'myOtherApp', 'rule', 'find'), + privilege: mockAuthorizationAction('rule-type-id-1', 'consumer-a', 'rule', 'find'), authorized: true, }, { - privilege: mockAuthorizationAction('mySecondAppAlertType', 'myApp', 'rule', 'find'), - authorized: true, - }, - { - privilege: mockAuthorizationAction( - 'mySecondAppAlertType', - 'myOtherApp', - 'rule', - 'find' - ), + privilege: mockAuthorizationAction('rule-type-id-2', 'consumer-b', 'rule', 'find'), authorized: true, }, ], }, }); - const alertAuthorization = new AlertingAuthorization({ + + const auth = await AlertingAuthorization.create({ request, - authorization, ruleTypeRegistry, + getSpaceId, features, getSpace, - getSpaceId, + authorization: securityStart.authz, }); - ruleTypeRegistry.list.mockReturnValue(setOfAlertTypes); - const { ensureRuleTypeIsAuthorized } = await alertAuthorization.getFindAuthorizationFilter( - AlertingAuthorizationEntity.Rule, - { + + const { ensureRuleTypeIsAuthorized } = await auth.getFindAuthorizationFilter({ + authorizationEntity: AlertingAuthorizationEntity.Rule, + filterOpts: { type: AlertingAuthorizationFilterType.KQL, fieldNames: { - ruleTypeId: 'ruleId', - consumer: 'consumer', + ruleTypeId: 'path.to.rule_type_id', + consumer: 'consumer-field', }, - } - ); - expect(() => { - ensureRuleTypeIsAuthorized('myAppAlertType', 'myOtherApp', 'rule'); - ensureRuleTypeIsAuthorized('mySecondAppAlertType', 'myOtherApp', 'rule'); - ensureRuleTypeIsAuthorized('myAppAlertType', 'myOtherApp', 'rule'); - }).not.toThrow(); + }, + }); + + expect(() => + ensureRuleTypeIsAuthorized('rule-type-id-1', 'consumer-a', 'rule') + ).not.toThrow(); + + expect(() => + ensureRuleTypeIsAuthorized('rule-type-id-2', 'consumer-b', 'rule') + ).not.toThrow(); }); + }); - // This is a specific use case currently for alerts as data - // Space ids are stored in the alerts documents and even if security is disabled - // still need to consider the users space privileges - test('creates a spaceId only filter if security is disabled, but require space awareness', async () => { - const alertAuthorization = new AlertingAuthorization({ - request, - ruleTypeRegistry, - features, - getSpace, - getSpaceId, + describe('getAuthorizationFilter', () => { + describe('filter', () => { + it('gets the filter correctly with no security and no spaceIds in the fields names', async () => { + const auth = await AlertingAuthorization.create({ + request, + ruleTypeRegistry, + getSpaceId, + features, + getSpace, + }); + + const { filter } = await auth.getAuthorizationFilter({ + authorizationEntity: AlertingAuthorizationEntity.Rule, + filterOpts: { + type: AlertingAuthorizationFilterType.KQL, + fieldNames: { + ruleTypeId: 'ruleId', + consumer: 'consumer', + }, + }, + operation: ReadOperations.Get, + }); + + expect(filter).toEqual(undefined); }); - const { filter } = await alertAuthorization.getFindAuthorizationFilter( - AlertingAuthorizationEntity.Alert, - { - type: AlertingAuthorizationFilterType.ESDSL, - fieldNames: { - ruleTypeId: 'ruleId', - consumer: 'consumer', - spaceIds: 'path.to.space.id', + + // This is a specific use case currently for alerts as data + // Space ids are stored in the alerts documents and even if security is disabled + // still need to consider the users space privileges + it('gets the filter correctly with no security and spaceIds in the fields names', async () => { + const auth = await AlertingAuthorization.create({ + request, + ruleTypeRegistry, + getSpaceId, + features, + getSpace, + }); + + const { filter } = await auth.getAuthorizationFilter({ + authorizationEntity: AlertingAuthorizationEntity.Rule, + filterOpts: { + type: AlertingAuthorizationFilterType.KQL, + fieldNames: { + ruleTypeId: 'ruleId', + consumer: 'consumer', + spaceIds: 'path.to.space.id', + }, }, - } - ); + operation: ReadOperations.Get, + }); - expect(filter).toEqual({ - bool: { minimum_should_match: 1, should: [{ match: { 'path.to.space.id': 'space1' } }] }, + expect(toKqlExpression(filter as KueryNode)).toMatchInlineSnapshot( + `"path.to.space.id: space1"` + ); }); - }); - }); - describe('filterByRuleTypeAuthorization', () => { - const myOtherAppAlertType: RegistryRuleType = { - actionGroups: [], - actionVariables: undefined, - defaultActionGroupId: 'default', - minimumLicenseRequired: 'basic', - isExportable: true, - recoveryActionGroup: RecoveredActionGroup, - id: 'myOtherAppAlertType', - name: 'myOtherAppAlertType', - category: 'test', - producer: 'myOtherApp', - enabledInLicense: true, - hasAlertsMappings: false, - hasFieldsForAAD: false, - validLegacyConsumers: [], - }; - const myAppAlertType: RegistryRuleType = { - actionGroups: [], - actionVariables: undefined, - defaultActionGroupId: 'default', - minimumLicenseRequired: 'basic', - isExportable: true, - recoveryActionGroup: RecoveredActionGroup, - id: 'myAppAlertType', - name: 'myAppAlertType', - category: 'test', - producer: 'myApp', - enabledInLicense: true, - hasAlertsMappings: false, - hasFieldsForAAD: false, - validLegacyConsumers: [], - }; - const setOfAlertTypes = new Set([myAppAlertType, myOtherAppAlertType]); - beforeEach(() => { - features.getKibanaFeatures.mockReturnValue([ - mockFeature('myApp', ['myOtherAppAlertType', 'myAppAlertType']), - mockFeature('myOtherApp', ['myAppAlertType', 'myOtherAppAlertType']), - ]); - }); - test('augments a list of types with all features when there is no authorization api', async () => { - features.getKibanaFeatures.mockReturnValue([ - myAppFeature, - myOtherAppFeature, - myAppWithSubFeature, - myFeatureWithoutAlerting, - ]); - const alertAuthorization = new AlertingAuthorization({ - request, - ruleTypeRegistry, - features, - getSpace, - getSpaceId, + it('gets the filter correctly with security disabled', async () => { + securityStart.authz.mode.useRbacForRequest.mockReturnValue(false); + + const auth = await AlertingAuthorization.create({ + request, + ruleTypeRegistry, + getSpaceId, + features, + getSpace, + authorization: securityStart.authz, + }); + + const { filter } = await auth.getAuthorizationFilter({ + authorizationEntity: AlertingAuthorizationEntity.Rule, + filterOpts: { + type: AlertingAuthorizationFilterType.KQL, + fieldNames: { + ruleTypeId: 'ruleId', + consumer: 'consumer', + }, + }, + operation: ReadOperations.Get, + }); + + expect(filter).toEqual(undefined); }); - ruleTypeRegistry.list.mockReturnValue(setOfAlertTypes); - await expect( - alertAuthorization.filterByRuleTypeAuthorization( - new Set([myAppAlertType, myOtherAppAlertType]), - [WriteOperations.Create], - AlertingAuthorizationEntity.Rule - ) - ).resolves.toMatchInlineSnapshot(` - Set { - Object { - "actionGroups": Array [], - "actionVariables": undefined, - "authorizedConsumers": Object { - "alerts": Object { - "all": true, - "read": true, + it('gets the filter correctly for all rule types and consumers', async () => { + checkPrivileges.mockResolvedValueOnce({ + username: 'some-user', + hasAllRequested: true, + privileges: { + kibana: [ + { + privilege: mockAuthorizationAction('rule-type-id-1', 'consumer-a', 'rule', 'get'), + authorized: true, }, - "discover": Object { - "all": true, - "read": true, + { + privilege: mockAuthorizationAction('rule-type-id-1', 'consumer-b', 'rule', 'get'), + authorized: true, }, - "myApp": Object { - "all": true, - "read": true, + { + privilege: mockAuthorizationAction('rule-type-id-2', 'consumer-b', 'rule', 'get'), + authorized: true, }, - "myAppWithSubFeature": Object { - "all": true, - "read": true, + { + privilege: mockAuthorizationAction('rule-type-id-3', 'consumer-c', 'rule', 'get'), + authorized: true, }, - "myOtherApp": Object { - "all": true, - "read": true, + { + privilege: mockAuthorizationAction('rule-type-id-4', 'consumer-d', 'rule', 'get'), + authorized: true, }, + ], + }, + }); + + const auth = await AlertingAuthorization.create({ + request, + ruleTypeRegistry, + getSpaceId, + features, + getSpace, + authorization: securityStart.authz, + }); + + const { filter } = await auth.getAuthorizationFilter({ + authorizationEntity: AlertingAuthorizationEntity.Rule, + filterOpts: { + type: AlertingAuthorizationFilterType.KQL, + fieldNames: { + ruleTypeId: 'ruleId', + consumer: 'consumer', }, - "category": "test", - "defaultActionGroupId": "default", - "enabledInLicense": true, - "hasAlertsMappings": false, - "hasFieldsForAAD": false, - "id": "myAppAlertType", - "isExportable": true, - "minimumLicenseRequired": "basic", - "name": "myAppAlertType", - "producer": "myApp", - "recoveryActionGroup": Object { - "id": "recovered", - "name": "Recovered", - }, - "validLegacyConsumers": Array [], }, - Object { - "actionGroups": Array [], - "actionVariables": undefined, - "authorizedConsumers": Object { - "alerts": Object { - "all": true, - "read": true, + operation: ReadOperations.Get, + }); + + expect(toKqlExpression(filter as KueryNode)).toMatchInlineSnapshot( + `"((ruleId: rule-type-id-1 AND (consumer: consumer-a OR consumer: consumer-b)) OR (ruleId: rule-type-id-2 AND consumer: consumer-b) OR (ruleId: rule-type-id-3 AND consumer: consumer-c) OR (ruleId: rule-type-id-4 AND consumer: consumer-d))"` + ); + }); + + it('throws when the user is not authorized for any rule type', async () => { + checkPrivileges.mockResolvedValueOnce({ + username: 'some-user', + hasAllRequested: true, + privileges: { + kibana: [], + }, + }); + + const auth = await AlertingAuthorization.create({ + request, + ruleTypeRegistry, + getSpaceId, + features, + getSpace, + authorization: securityStart.authz, + }); + + await expect( + auth.getAuthorizationFilter({ + authorizationEntity: AlertingAuthorizationEntity.Rule, + filterOpts: { + type: AlertingAuthorizationFilterType.KQL, + fieldNames: { + ruleTypeId: 'ruleId', + consumer: 'consumer', }, - "discover": Object { - "all": true, - "read": true, + }, + operation: ReadOperations.Get, + }) + ).rejects.toThrowErrorMatchingInlineSnapshot( + `"Unauthorized to get rules for any rule types"` + ); + }); + }); + + describe('ensureRuleTypeIsAuthorized', () => { + it('does not throw if the rule type is authorized', async () => { + checkPrivileges.mockResolvedValueOnce({ + username: 'some-user', + hasAllRequested: true, + privileges: { + kibana: [ + { + privilege: mockAuthorizationAction('rule-type-id-1', 'consumer-a', 'rule', 'get'), + authorized: true, }, - "myApp": Object { - "all": true, - "read": true, + { + privilege: mockAuthorizationAction('rule-type-id-2', 'consumer-b', 'rule', 'get'), + authorized: true, }, - "myAppWithSubFeature": Object { - "all": true, - "read": true, + ], + }, + }); + + const auth = await AlertingAuthorization.create({ + request, + ruleTypeRegistry, + getSpaceId, + features, + getSpace, + authorization: securityStart.authz, + }); + + const { ensureRuleTypeIsAuthorized } = await auth.getAuthorizationFilter({ + authorizationEntity: AlertingAuthorizationEntity.Rule, + filterOpts: { + type: AlertingAuthorizationFilterType.KQL, + fieldNames: { + ruleTypeId: 'ruleId', + consumer: 'consumer', + }, + }, + operation: ReadOperations.Get, + }); + + expect(() => + ensureRuleTypeIsAuthorized('rule-type-id-1', 'consumer-a', 'rule') + ).not.toThrow(); + + expect(() => + ensureRuleTypeIsAuthorized('rule-type-id-2', 'consumer-b', 'rule') + ).not.toThrow(); + }); + + it('throws if the rule type is not authorized', async () => { + checkPrivileges.mockResolvedValueOnce({ + username: 'some-user', + hasAllRequested: true, + privileges: { + kibana: [ + { + privilege: mockAuthorizationAction('rule-type-id-1', 'consumer-a', 'rule', 'get'), + authorized: true, }, - "myOtherApp": Object { - "all": true, - "read": true, + ], + }, + }); + + const auth = await AlertingAuthorization.create({ + request, + ruleTypeRegistry, + getSpaceId, + features, + getSpace, + authorization: securityStart.authz, + }); + + const { ensureRuleTypeIsAuthorized } = await auth.getAuthorizationFilter({ + authorizationEntity: AlertingAuthorizationEntity.Rule, + filterOpts: { + type: AlertingAuthorizationFilterType.KQL, + fieldNames: { + ruleTypeId: 'ruleId', + consumer: 'consumer', + }, + }, + operation: ReadOperations.Get, + }); + + expect(() => + ensureRuleTypeIsAuthorized('rule-type-id-2', 'consumer-a', 'rule') + ).toThrowErrorMatchingInlineSnapshot( + `"Unauthorized by \\"consumer-a\\" to get \\"rule-type-id-2\\" rule"` + ); + }); + + it('throws if the rule type is not authorized for the entity', async () => { + checkPrivileges.mockResolvedValueOnce({ + username: 'some-user', + hasAllRequested: true, + privileges: { + kibana: [ + { + privilege: mockAuthorizationAction('rule-type-id-1', 'consumer-a', 'rule', 'get'), + authorized: true, + }, + ], + }, + }); + + const auth = await AlertingAuthorization.create({ + request, + ruleTypeRegistry, + getSpaceId, + features, + getSpace, + authorization: securityStart.authz, + }); + + const { ensureRuleTypeIsAuthorized } = await auth.getAuthorizationFilter({ + authorizationEntity: AlertingAuthorizationEntity.Rule, + filterOpts: { + type: AlertingAuthorizationFilterType.KQL, + fieldNames: { + ruleTypeId: 'ruleId', + consumer: 'consumer', + }, + }, + operation: ReadOperations.Get, + }); + + expect(() => + ensureRuleTypeIsAuthorized('rule-type-id-1', 'consumer-a', 'alert') + ).toThrowErrorMatchingInlineSnapshot( + `"Unauthorized by \\"consumer-a\\" to get \\"rule-type-id-1\\" alert"` + ); + }); + + it('throws if the rule type is not authorized for the consumer', async () => { + checkPrivileges.mockResolvedValueOnce({ + username: 'some-user', + hasAllRequested: true, + privileges: { + kibana: [ + { + privilege: mockAuthorizationAction('rule-type-id-1', 'consumer-a', 'rule', 'get'), + authorized: true, }, + ], + }, + }); + + const auth = await AlertingAuthorization.create({ + request, + ruleTypeRegistry, + getSpaceId, + features, + getSpace, + authorization: securityStart.authz, + }); + + const { ensureRuleTypeIsAuthorized } = await auth.getAuthorizationFilter({ + authorizationEntity: AlertingAuthorizationEntity.Rule, + filterOpts: { + type: AlertingAuthorizationFilterType.KQL, + fieldNames: { + ruleTypeId: 'ruleId', + consumer: 'consumer', }, - "category": "test", - "defaultActionGroupId": "default", - "enabledInLicense": true, - "hasAlertsMappings": false, - "hasFieldsForAAD": false, - "id": "myOtherAppAlertType", - "isExportable": true, - "minimumLicenseRequired": "basic", - "name": "myOtherAppAlertType", - "producer": "myOtherApp", - "recoveryActionGroup": Object { - "id": "recovered", - "name": "Recovered", - }, - "validLegacyConsumers": Array [], }, - } + operation: ReadOperations.Get, + }); + + expect(() => + ensureRuleTypeIsAuthorized('rule-type-id-1', 'consumer-b', 'rule') + ).toThrowErrorMatchingInlineSnapshot( + `"Unauthorized by \\"consumer-b\\" to get \\"rule-type-id-1\\" rule"` + ); + }); + }); + }); + + describe('getAuthorizedRuleTypes', () => { + it('calls checkPrivileges correctly', async () => { + const auth = await AlertingAuthorization.create({ + request, + ruleTypeRegistry, + getSpaceId, + features, + getSpace, + authorization: securityStart.authz, + }); + + await auth.getAuthorizedRuleTypes({ + ruleTypeIds: ['rule-type-id-1'], + operations: [WriteOperations.Create], + authorizationEntity: AlertingAuthorizationEntity.Rule, + }); + + expect(checkPrivileges).toBeCalledTimes(1); + expect(checkPrivileges.mock.calls[0]).toMatchInlineSnapshot(` + Array [ + Object { + "kibana": Array [ + "rule-type-id-1/alerts/rule/create", + "rule-type-id-1/consumer-a/rule/create", + "rule-type-id-1/consumer-b/rule/create", + ], + }, + ] `); }); - test('augments a list of types with consumers under which the operation is authorized', async () => { - const { authorization } = mockSecurity(); - const checkPrivileges: jest.MockedFunction< - ReturnType - > = jest.fn(); - authorization.checkPrivilegesDynamicallyWithRequest.mockReturnValue(checkPrivileges); + it('returns the authorized rules correctly', async () => { checkPrivileges.mockResolvedValueOnce({ username: 'some-user', - hasAllRequested: false, + hasAllRequested: true, privileges: { kibana: [ { - privilege: mockAuthorizationAction('myOtherAppAlertType', 'myApp', 'rule', 'create'), + privilege: mockAuthorizationAction('rule-type-id-1', 'consumer-a', 'rule', 'get'), authorized: true, }, { - privilege: mockAuthorizationAction( - 'myOtherAppAlertType', - 'myOtherApp', - 'rule', - 'create' - ), - authorized: false, + privilege: mockAuthorizationAction('rule-type-id-1', 'consumer-a', 'rule', 'create'), + authorized: true, }, { - privilege: mockAuthorizationAction('myAppAlertType', 'myApp', 'rule', 'create'), + privilege: mockAuthorizationAction('rule-type-id-2', 'consumer-b', 'rule', 'get'), authorized: true, }, { - privilege: mockAuthorizationAction('myAppAlertType', 'myOtherApp', 'rule', 'create'), + privilege: mockAuthorizationAction('rule-type-id-3', 'consumer-c', 'rule', 'create'), authorized: true, }, ], }, }); - const alertAuthorization = new AlertingAuthorization({ + const auth = await AlertingAuthorization.create({ request, - authorization, ruleTypeRegistry, + getSpaceId, features, getSpace, - getSpaceId, + authorization: securityStart.authz, }); - ruleTypeRegistry.list.mockReturnValue(setOfAlertTypes); - await expect( - alertAuthorization.filterByRuleTypeAuthorization( - new Set([myAppAlertType, myOtherAppAlertType]), - [WriteOperations.Create], - AlertingAuthorizationEntity.Rule - ) - ).resolves.toMatchInlineSnapshot(` - Set { - Object { - "actionGroups": Array [], - "actionVariables": undefined, + expect( + await auth.getAuthorizedRuleTypes({ + ruleTypeIds: ['rule-type-id-1'], + operations: [WriteOperations.Create], + authorizationEntity: AlertingAuthorizationEntity.Rule, + }) + ).toMatchInlineSnapshot(` + Map { + "rule-type-id-1" => Object { "authorizedConsumers": Object { - "myApp": Object { + "consumer-a": Object { "all": true, "read": true, }, }, - "category": "test", - "defaultActionGroupId": "default", - "enabledInLicense": true, - "hasAlertsMappings": false, - "hasFieldsForAAD": false, - "id": "myOtherAppAlertType", - "isExportable": true, - "minimumLicenseRequired": "basic", - "name": "myOtherAppAlertType", - "producer": "myOtherApp", - "recoveryActionGroup": Object { - "id": "recovered", - "name": "Recovered", - }, - "validLegacyConsumers": Array [], }, - Object { - "actionGroups": Array [], - "actionVariables": undefined, - "authorizedConsumers": Object { - "myApp": Object { - "all": true, - "read": true, - }, - "myOtherApp": Object { - "all": true, - "read": true, + } + `); + }); + }); + + describe('getAllAuthorizedRuleTypes', () => { + it('get authorized rule types with authorized consumers', async () => { + checkPrivileges.mockResolvedValueOnce({ + username: 'some-user', + hasAllRequested: true, + privileges: { + kibana: [ + { + privilege: mockAuthorizationAction('rule-type-id-1', 'consumer-a', 'rule', 'get'), + authorized: true, + }, + { + privilege: mockAuthorizationAction('rule-type-id-1', 'consumer-a', 'rule', 'create'), + authorized: true, + }, + { + privilege: mockAuthorizationAction('rule-type-id-2', 'consumer-b', 'rule', 'get'), + authorized: true, + }, + { + privilege: mockAuthorizationAction('rule-type-id-3', 'consumer-c', 'rule', 'create'), + authorized: false, + }, + ], + }, + }); + + const auth = await AlertingAuthorization.create({ + request, + ruleTypeRegistry, + getSpaceId, + features, + getSpace, + authorization: securityStart.authz, + }); + + expect( + await auth.getAllAuthorizedRuleTypes({ + operations: [ReadOperations.Get, WriteOperations.Create], + authorizationEntity: AlertingAuthorizationEntity.Rule, + }) + ).toMatchInlineSnapshot(` + Object { + "authorizedRuleTypes": Map { + "rule-type-id-1" => Object { + "authorizedConsumers": Object { + "consumer-a": Object { + "all": true, + "read": true, + }, + }, + }, + "rule-type-id-2" => Object { + "authorizedConsumers": Object { + "consumer-b": Object { + "all": false, + "read": true, + }, + }, + }, + }, + "hasAllRequested": true, + "username": "some-user", + } + `); + }); + + it('calls checkPrivileges with the correct actions', async () => { + const auth = await AlertingAuthorization.create({ + request, + ruleTypeRegistry, + getSpaceId, + features, + getSpace, + authorization: securityStart.authz, + }); + + await auth.getAllAuthorizedRuleTypes({ + operations: [ReadOperations.Get, WriteOperations.Create], + authorizationEntity: AlertingAuthorizationEntity.Rule, + }); + + expect(checkPrivileges).toBeCalledTimes(1); + expect(checkPrivileges.mock.calls[0]).toMatchInlineSnapshot(` + Array [ + Object { + "kibana": Array [ + "rule-type-id-1/alerts/rule/get", + "rule-type-id-1/alerts/rule/create", + "rule-type-id-1/consumer-a/rule/get", + "rule-type-id-1/consumer-a/rule/create", + "rule-type-id-1/consumer-b/rule/get", + "rule-type-id-1/consumer-b/rule/create", + "rule-type-id-2/alerts/rule/get", + "rule-type-id-2/alerts/rule/create", + "rule-type-id-2/consumer-b/rule/get", + "rule-type-id-2/consumer-b/rule/create", + "rule-type-id-3/alerts/rule/get", + "rule-type-id-3/alerts/rule/create", + "rule-type-id-3/consumer-c/rule/get", + "rule-type-id-3/consumer-c/rule/create", + "rule-type-id-4/consumer-d/rule/get", + "rule-type-id-4/consumer-d/rule/create", + ], + }, + ] + `); + }); + }); + + describe('_getAuthorizedRuleTypesWithAuthorizedConsumers', () => { + it('returns all rule types with all consumers as authorized with no authorization', async () => { + const auth = await AlertingAuthorization.create({ + request, + ruleTypeRegistry, + getSpaceId, + features, + getSpace, + }); + + expect( + // @ts-expect-error: need to test the private method + await auth._getAuthorizedRuleTypesWithAuthorizedConsumers({ + ruleTypeIds, + operations: [ReadOperations.Get, WriteOperations.Create], + authorizationEntity: AlertingAuthorizationEntity.Rule, + }) + ).toMatchInlineSnapshot(` + Object { + "authorizedRuleTypes": Map { + "rule-type-id-1" => Object { + "authorizedConsumers": Object { + "alerts": Object { + "all": true, + "read": true, + }, + "consumer-a": Object { + "all": true, + "read": true, + }, + "consumer-b": Object { + "all": true, + "read": true, + }, + "consumer-c": Object { + "all": true, + "read": true, + }, + "consumer-d": Object { + "all": true, + "read": true, + }, + }, + }, + "rule-type-id-2" => Object { + "authorizedConsumers": Object { + "alerts": Object { + "all": true, + "read": true, + }, + "consumer-a": Object { + "all": true, + "read": true, + }, + "consumer-b": Object { + "all": true, + "read": true, + }, + "consumer-c": Object { + "all": true, + "read": true, + }, + "consumer-d": Object { + "all": true, + "read": true, + }, + }, + }, + "rule-type-id-3" => Object { + "authorizedConsumers": Object { + "alerts": Object { + "all": true, + "read": true, + }, + "consumer-a": Object { + "all": true, + "read": true, + }, + "consumer-b": Object { + "all": true, + "read": true, + }, + "consumer-c": Object { + "all": true, + "read": true, + }, + "consumer-d": Object { + "all": true, + "read": true, + }, + }, + }, + "rule-type-id-4" => Object { + "authorizedConsumers": Object { + "alerts": Object { + "all": true, + "read": true, + }, + "consumer-a": Object { + "all": true, + "read": true, + }, + "consumer-b": Object { + "all": true, + "read": true, + }, + "consumer-c": Object { + "all": true, + "read": true, + }, + "consumer-d": Object { + "all": true, + "read": true, + }, + }, + }, + }, + "hasAllRequested": true, + } + `); + }); + + it('filters out rule types with no authorization', async () => { + const auth = await AlertingAuthorization.create({ + request, + ruleTypeRegistry, + getSpaceId, + features, + getSpace, + }); + + expect( + // @ts-expect-error: need to test the private method + await auth._getAuthorizedRuleTypesWithAuthorizedConsumers({ + ruleTypeIds: [ruleTypeIds[0], ruleTypeIds[1]], + operations: [ReadOperations.Get, WriteOperations.Create], + authorizationEntity: AlertingAuthorizationEntity.Rule, + }) + ).toMatchInlineSnapshot(` + Object { + "authorizedRuleTypes": Map { + "rule-type-id-1" => Object { + "authorizedConsumers": Object { + "alerts": Object { + "all": true, + "read": true, + }, + "consumer-a": Object { + "all": true, + "read": true, + }, + "consumer-b": Object { + "all": true, + "read": true, + }, + "consumer-c": Object { + "all": true, + "read": true, + }, + "consumer-d": Object { + "all": true, + "read": true, + }, + }, + }, + "rule-type-id-2" => Object { + "authorizedConsumers": Object { + "alerts": Object { + "all": true, + "read": true, + }, + "consumer-a": Object { + "all": true, + "read": true, + }, + "consumer-b": Object { + "all": true, + "read": true, + }, + "consumer-c": Object { + "all": true, + "read": true, + }, + "consumer-d": Object { + "all": true, + "read": true, + }, + }, + }, + }, + "hasAllRequested": true, + } + `); + }); + + it('returns all rule types with all consumers as authorized with disabled authorization', async () => { + securityStart.authz.mode.useRbacForRequest.mockReturnValue(false); + + const auth = await AlertingAuthorization.create({ + request, + ruleTypeRegistry, + getSpaceId, + features, + getSpace, + authorization: securityStart.authz, + }); + + expect( + // @ts-expect-error: need to test the private method + await auth._getAuthorizedRuleTypesWithAuthorizedConsumers({ + ruleTypeIds, + operations: [ReadOperations.Get, WriteOperations.Create], + authorizationEntity: AlertingAuthorizationEntity.Rule, + }) + ).toMatchInlineSnapshot(` + Object { + "authorizedRuleTypes": Map { + "rule-type-id-1" => Object { + "authorizedConsumers": Object { + "alerts": Object { + "all": true, + "read": true, + }, + "consumer-a": Object { + "all": true, + "read": true, + }, + "consumer-b": Object { + "all": true, + "read": true, + }, + "consumer-c": Object { + "all": true, + "read": true, + }, + "consumer-d": Object { + "all": true, + "read": true, + }, + }, + }, + "rule-type-id-2" => Object { + "authorizedConsumers": Object { + "alerts": Object { + "all": true, + "read": true, + }, + "consumer-a": Object { + "all": true, + "read": true, + }, + "consumer-b": Object { + "all": true, + "read": true, + }, + "consumer-c": Object { + "all": true, + "read": true, + }, + "consumer-d": Object { + "all": true, + "read": true, + }, + }, + }, + "rule-type-id-3" => Object { + "authorizedConsumers": Object { + "alerts": Object { + "all": true, + "read": true, + }, + "consumer-a": Object { + "all": true, + "read": true, + }, + "consumer-b": Object { + "all": true, + "read": true, + }, + "consumer-c": Object { + "all": true, + "read": true, + }, + "consumer-d": Object { + "all": true, + "read": true, + }, + }, + }, + "rule-type-id-4" => Object { + "authorizedConsumers": Object { + "alerts": Object { + "all": true, + "read": true, + }, + "consumer-a": Object { + "all": true, + "read": true, + }, + "consumer-b": Object { + "all": true, + "read": true, + }, + "consumer-c": Object { + "all": true, + "read": true, + }, + "consumer-d": Object { + "all": true, + "read": true, + }, + }, + }, + }, + "hasAllRequested": true, + } + `); + }); + + it('filters out rule types with disabled authorization', async () => { + securityStart.authz.mode.useRbacForRequest.mockReturnValue(false); + + const auth = await AlertingAuthorization.create({ + request, + ruleTypeRegistry, + getSpaceId, + features, + getSpace, + authorization: securityStart.authz, + }); + + expect( + // @ts-expect-error: need to test the private method + await auth._getAuthorizedRuleTypesWithAuthorizedConsumers({ + ruleTypeIds: [ruleTypeIds[0], ruleTypeIds[1]], + operations: [ReadOperations.Get, WriteOperations.Create], + authorizationEntity: AlertingAuthorizationEntity.Rule, + }) + ).toMatchInlineSnapshot(` + Object { + "authorizedRuleTypes": Map { + "rule-type-id-1" => Object { + "authorizedConsumers": Object { + "alerts": Object { + "all": true, + "read": true, + }, + "consumer-a": Object { + "all": true, + "read": true, + }, + "consumer-b": Object { + "all": true, + "read": true, + }, + "consumer-c": Object { + "all": true, + "read": true, + }, + "consumer-d": Object { + "all": true, + "read": true, + }, + }, + }, + "rule-type-id-2" => Object { + "authorizedConsumers": Object { + "alerts": Object { + "all": true, + "read": true, + }, + "consumer-a": Object { + "all": true, + "read": true, + }, + "consumer-b": Object { + "all": true, + "read": true, + }, + "consumer-c": Object { + "all": true, + "read": true, + }, + "consumer-d": Object { + "all": true, + "read": true, + }, + }, + }, + }, + "hasAllRequested": true, + } + `); + }); + + it('get authorized rule types with authorized consumers with read access only', async () => { + checkPrivileges.mockResolvedValueOnce({ + username: 'some-user', + hasAllRequested: true, + privileges: { + kibana: [ + { + privilege: mockAuthorizationAction('rule-type-id-1', 'consumer-a', 'rule', 'get'), + authorized: true, + }, + ], + }, + }); + + const auth = await AlertingAuthorization.create({ + request, + ruleTypeRegistry, + getSpaceId, + features, + getSpace, + authorization: securityStart.authz, + }); + + expect( + // @ts-expect-error: need to test the private method + await auth._getAuthorizedRuleTypesWithAuthorizedConsumers({ + ruleTypeIds, + operations: [ReadOperations.Get, WriteOperations.Create], + authorizationEntity: AlertingAuthorizationEntity.Rule, + }) + ).toMatchInlineSnapshot(` + Object { + "authorizedRuleTypes": Map { + "rule-type-id-1" => Object { + "authorizedConsumers": Object { + "consumer-a": Object { + "all": false, + "read": true, + }, + }, + }, + }, + "hasAllRequested": true, + "username": "some-user", + } + `); + }); + + it('get authorized rule types with authorized consumers with full access', async () => { + checkPrivileges.mockResolvedValueOnce({ + username: 'some-user', + hasAllRequested: true, + privileges: { + kibana: [ + { + privilege: mockAuthorizationAction('rule-type-id-1', 'consumer-a', 'rule', 'get'), + authorized: true, + }, + { + privilege: mockAuthorizationAction('rule-type-id-1', 'consumer-a', 'rule', 'create'), + authorized: true, + }, + ], + }, + }); + + const auth = await AlertingAuthorization.create({ + request, + ruleTypeRegistry, + getSpaceId, + features, + getSpace, + authorization: securityStart.authz, + }); + + expect( + // @ts-expect-error: need to test the private method + await auth._getAuthorizedRuleTypesWithAuthorizedConsumers({ + ruleTypeIds, + operations: [ReadOperations.Get, WriteOperations.Create], + authorizationEntity: AlertingAuthorizationEntity.Rule, + }) + ).toMatchInlineSnapshot(` + Object { + "authorizedRuleTypes": Map { + "rule-type-id-1" => Object { + "authorizedConsumers": Object { + "consumer-a": Object { + "all": true, + "read": true, + }, + }, + }, + }, + "hasAllRequested": true, + "username": "some-user", + } + `); + }); + + it('filters out not requested rule types', async () => { + checkPrivileges.mockResolvedValueOnce({ + username: 'some-user', + hasAllRequested: true, + privileges: { + kibana: [ + { + privilege: mockAuthorizationAction('rule-type-id-1', 'consumer-a', 'rule', 'get'), + authorized: true, + }, + { + privilege: mockAuthorizationAction('rule-type-id-1', 'consumer-b', 'rule', 'create'), + authorized: true, + }, + { + privilege: mockAuthorizationAction('rule-type-id-3', 'consumer-c', 'rule', 'create'), + authorized: true, + }, + ], + }, + }); + + const auth = await AlertingAuthorization.create({ + request, + ruleTypeRegistry, + getSpaceId, + features, + getSpace, + authorization: securityStart.authz, + }); + + expect( + // @ts-expect-error: need to test the private method + await auth._getAuthorizedRuleTypesWithAuthorizedConsumers({ + ruleTypeIds: [ruleTypeIds[0], ruleTypeIds[1]], + operations: [ReadOperations.Get, WriteOperations.Create], + authorizationEntity: AlertingAuthorizationEntity.Rule, + }) + ).toMatchInlineSnapshot(` + Object { + "authorizedRuleTypes": Map { + "rule-type-id-1" => Object { + "authorizedConsumers": Object { + "consumer-a": Object { + "all": false, + "read": true, + }, + "consumer-b": Object { + "all": true, + "read": true, + }, }, }, - "category": "test", - "defaultActionGroupId": "default", - "enabledInLicense": true, - "hasAlertsMappings": false, - "hasFieldsForAAD": false, - "id": "myAppAlertType", - "isExportable": true, - "minimumLicenseRequired": "basic", - "name": "myAppAlertType", - "producer": "myApp", - "recoveryActionGroup": Object { - "id": "recovered", - "name": "Recovered", - }, - "validLegacyConsumers": Array [], }, + "hasAllRequested": true, + "username": "some-user", } `); }); - test('authorizes user under the `alerts` consumer when they are authorized by the producer', async () => { - const { authorization } = mockSecurity(); - const checkPrivileges: jest.MockedFunction< - ReturnType - > = jest.fn(); - authorization.checkPrivilegesDynamicallyWithRequest.mockReturnValue(checkPrivileges); + it('returns an empty map with no requested rule types', async () => { checkPrivileges.mockResolvedValueOnce({ username: 'some-user', - hasAllRequested: false, + hasAllRequested: true, privileges: { kibana: [ { - privilege: mockAuthorizationAction('myAppAlertType', 'myApp', 'alert', 'create'), + privilege: mockAuthorizationAction('rule-type-id-1', 'consumer-a', 'rule', 'get'), authorized: true, }, { - privilege: mockAuthorizationAction('myAppAlertType', 'myOtherApp', 'alert', 'create'), - authorized: false, + privilege: mockAuthorizationAction('rule-type-id-1', 'consumer-a', 'rule', 'create'), + authorized: true, }, ], }, }); - const alertAuthorization = new AlertingAuthorization({ + const auth = await AlertingAuthorization.create({ request, - authorization, ruleTypeRegistry, + getSpaceId, features, getSpace, - getSpaceId, + authorization: securityStart.authz, }); - ruleTypeRegistry.list.mockReturnValue(setOfAlertTypes); - await expect( - alertAuthorization.filterByRuleTypeAuthorization( - new Set([myAppAlertType]), - [WriteOperations.Create], - AlertingAuthorizationEntity.Alert - ) - ).resolves.toMatchInlineSnapshot(` - Set { - Object { - "actionGroups": Array [], - "actionVariables": undefined, - "authorizedConsumers": Object { - "myApp": Object { - "all": true, - "read": true, - }, - }, - "category": "test", - "defaultActionGroupId": "default", - "enabledInLicense": true, - "hasAlertsMappings": false, - "hasFieldsForAAD": false, - "id": "myAppAlertType", - "isExportable": true, - "minimumLicenseRequired": "basic", - "name": "myAppAlertType", - "producer": "myApp", - "recoveryActionGroup": Object { - "id": "recovered", - "name": "Recovered", - }, - "validLegacyConsumers": Array [], - }, + expect( + // @ts-expect-error: need to test the private method + await auth._getAuthorizedRuleTypesWithAuthorizedConsumers({ + ruleTypeIds: [], + operations: [ReadOperations.Get, WriteOperations.Create], + authorizationEntity: AlertingAuthorizationEntity.Rule, + }) + ).toMatchInlineSnapshot(` + Object { + "authorizedRuleTypes": Map {}, + "hasAllRequested": true, + "username": "some-user", } `); }); - test('augments a list of types with consumers under which multiple operations are authorized', async () => { - const { authorization } = mockSecurity(); - const checkPrivileges: jest.MockedFunction< - ReturnType - > = jest.fn(); - authorization.checkPrivilegesDynamicallyWithRequest.mockReturnValue(checkPrivileges); + it('get authorized rule types with authorized consumers when some rule types are not authorized', async () => { checkPrivileges.mockResolvedValueOnce({ username: 'some-user', - hasAllRequested: false, + hasAllRequested: true, privileges: { kibana: [ { - privilege: mockAuthorizationAction('myOtherAppAlertType', 'myApp', 'alert', 'create'), - authorized: true, - }, - { - privilege: mockAuthorizationAction( - 'myOtherAppAlertType', - 'myOtherApp', - 'alert', - 'create' - ), - authorized: false, - }, - { - privilege: mockAuthorizationAction('myAppAlertType', 'myApp', 'alert', 'create'), - authorized: false, - }, - { - privilege: mockAuthorizationAction('myAppAlertType', 'myOtherApp', 'alert', 'create'), - authorized: false, - }, - { - privilege: mockAuthorizationAction('myOtherAppAlertType', 'myApp', 'alert', 'get'), + privilege: mockAuthorizationAction('rule-type-id-1', 'consumer-a', 'rule', 'get'), authorized: true, }, { - privilege: mockAuthorizationAction( - 'myOtherAppAlertType', - 'myOtherApp', - 'alert', - 'get' - ), + privilege: mockAuthorizationAction('rule-type-id-1', 'consumer-a', 'rule', 'create'), authorized: true, }, { - privilege: mockAuthorizationAction('myAppAlertType', 'myApp', 'alert', 'get'), - authorized: true, + privilege: mockAuthorizationAction('rule-type-id-2', 'consumer-b', 'rule', 'create'), + authorized: false, }, { - privilege: mockAuthorizationAction('myAppAlertType', 'myOtherApp', 'alert', 'get'), + privilege: mockAuthorizationAction('rule-type-id-3', 'consumer-c', 'rule', 'get'), authorized: true, }, ], }, }); - const alertAuthorization = new AlertingAuthorization({ + const auth = await AlertingAuthorization.create({ request, - authorization, ruleTypeRegistry, + getSpaceId, features, getSpace, - getSpaceId, + authorization: securityStart.authz, }); - ruleTypeRegistry.list.mockReturnValue(setOfAlertTypes); - await expect( - alertAuthorization.filterByRuleTypeAuthorization( - new Set([myAppAlertType, myOtherAppAlertType]), - [WriteOperations.Create, ReadOperations.Get], - AlertingAuthorizationEntity.Alert - ) - ).resolves.toMatchInlineSnapshot(` - Set { - Object { - "actionGroups": Array [], - "actionVariables": undefined, - "authorizedConsumers": Object { - "myApp": Object { - "all": true, - "read": true, - }, - "myOtherApp": Object { - "all": false, - "read": true, + expect( + // @ts-expect-error: need to test the private method + await auth._getAuthorizedRuleTypesWithAuthorizedConsumers({ + ruleTypeIds, + operations: [ReadOperations.Get, WriteOperations.Create], + authorizationEntity: AlertingAuthorizationEntity.Rule, + }) + ).toMatchInlineSnapshot(` + Object { + "authorizedRuleTypes": Map { + "rule-type-id-1" => Object { + "authorizedConsumers": Object { + "consumer-a": Object { + "all": true, + "read": true, + }, }, }, - "category": "test", - "defaultActionGroupId": "default", - "enabledInLicense": true, - "hasAlertsMappings": false, - "hasFieldsForAAD": false, - "id": "myOtherAppAlertType", - "isExportable": true, - "minimumLicenseRequired": "basic", - "name": "myOtherAppAlertType", - "producer": "myOtherApp", - "recoveryActionGroup": Object { - "id": "recovered", - "name": "Recovered", - }, - "validLegacyConsumers": Array [], - }, - Object { - "actionGroups": Array [], - "actionVariables": undefined, - "authorizedConsumers": Object { - "myApp": Object { - "all": false, - "read": true, - }, - "myOtherApp": Object { - "all": false, - "read": true, + "rule-type-id-3" => Object { + "authorizedConsumers": Object { + "consumer-c": Object { + "all": false, + "read": true, + }, }, }, - "category": "test", - "defaultActionGroupId": "default", - "enabledInLicense": true, - "hasAlertsMappings": false, - "hasFieldsForAAD": false, - "id": "myAppAlertType", - "isExportable": true, - "minimumLicenseRequired": "basic", - "name": "myAppAlertType", - "producer": "myApp", - "recoveryActionGroup": Object { - "id": "recovered", - "name": "Recovered", - }, - "validLegacyConsumers": Array [], }, + "hasAllRequested": true, + "username": "some-user", } `); }); - test('omits types which have no consumers under which the operation is authorized', async () => { - const { authorization } = mockSecurity(); - const checkPrivileges: jest.MockedFunction< - ReturnType - > = jest.fn(); - authorization.checkPrivilegesDynamicallyWithRequest.mockReturnValue(checkPrivileges); + it('get authorized rule types with authorized consumers when consumers are not valid for a rule type', async () => { checkPrivileges.mockResolvedValueOnce({ username: 'some-user', - hasAllRequested: false, + hasAllRequested: true, privileges: { kibana: [ { - privilege: mockAuthorizationAction('myOtherAppAlertType', 'myApp', 'alert', 'create'), + privilege: mockAuthorizationAction('rule-type-id-1', 'consumer-a', 'rule', 'get'), authorized: true, }, { - privilege: mockAuthorizationAction( - 'myOtherAppAlertType', - 'myOtherApp', - 'alert', - 'create' - ), + privilege: mockAuthorizationAction('rule-type-id-1', 'consumer-a', 'rule', 'create'), authorized: true, }, { - privilege: mockAuthorizationAction('myAppAlertType', 'myApp', 'alert', 'create'), + privilege: mockAuthorizationAction('rule-type-id-2', 'consumer-b', 'rule', 'create'), authorized: false, }, { - privilege: mockAuthorizationAction('myAppAlertType', 'myOtherApp', 'alert', 'create'), - authorized: false, + privilege: mockAuthorizationAction('rule-type-id-3', 'consumer-d', 'rule', 'get'), + authorized: true, }, ], }, }); - const alertAuthorization = new AlertingAuthorization({ + const auth = await AlertingAuthorization.create({ request, - authorization, ruleTypeRegistry, + getSpaceId, features, getSpace, - getSpaceId, + authorization: securityStart.authz, }); - ruleTypeRegistry.list.mockReturnValue(setOfAlertTypes); - await expect( - alertAuthorization.filterByRuleTypeAuthorization( - new Set([myAppAlertType, myOtherAppAlertType]), - [WriteOperations.Create], - AlertingAuthorizationEntity.Alert - ) - ).resolves.toMatchInlineSnapshot(` - Set { - Object { - "actionGroups": Array [], - "actionVariables": undefined, - "authorizedConsumers": Object { - "myApp": Object { - "all": true, - "read": true, - }, - "myOtherApp": Object { - "all": true, - "read": true, + expect( + // @ts-expect-error: need to test the private method + await auth._getAuthorizedRuleTypesWithAuthorizedConsumers({ + ruleTypeIds, + operations: [ReadOperations.Get, WriteOperations.Create], + authorizationEntity: AlertingAuthorizationEntity.Rule, + }) + ).toMatchInlineSnapshot(` + Object { + "authorizedRuleTypes": Map { + "rule-type-id-1" => Object { + "authorizedConsumers": Object { + "consumer-a": Object { + "all": true, + "read": true, + }, }, }, - "category": "test", - "defaultActionGroupId": "default", - "enabledInLicense": true, - "hasAlertsMappings": false, - "hasFieldsForAAD": false, - "id": "myOtherAppAlertType", - "isExportable": true, - "minimumLicenseRequired": "basic", - "name": "myOtherAppAlertType", - "producer": "myOtherApp", - "recoveryActionGroup": Object { - "id": "recovered", - "name": "Recovered", - }, - "validLegacyConsumers": Array [], }, + "hasAllRequested": true, + "username": "some-user", } `); }); - }); - describe('getAugmentedRuleTypesWithAuthorization', () => { - const myOtherAppAlertType: RegistryRuleType = { - actionGroups: [], - actionVariables: undefined, - defaultActionGroupId: 'default', - minimumLicenseRequired: 'basic', - recoveryActionGroup: RecoveredActionGroup, - id: 'myOtherAppAlertType', - name: 'myOtherAppAlertType', - category: 'test', - producer: 'alerts', - enabledInLicense: true, - isExportable: true, - hasAlertsMappings: false, - hasFieldsForAAD: false, - validLegacyConsumers: [], - }; - const myAppAlertType: RegistryRuleType = { - actionGroups: [], - actionVariables: undefined, - defaultActionGroupId: 'default', - minimumLicenseRequired: 'basic', - recoveryActionGroup: RecoveredActionGroup, - id: 'myAppAlertType', - name: 'myAppAlertType', - category: 'test', - producer: 'myApp', - enabledInLicense: true, - isExportable: true, - hasAlertsMappings: true, - hasFieldsForAAD: true, - validLegacyConsumers: [], - }; - const mySecondAppAlertType: RegistryRuleType = { - actionGroups: [], - actionVariables: undefined, - defaultActionGroupId: 'default', - minimumLicenseRequired: 'basic', - recoveryActionGroup: RecoveredActionGroup, - id: 'mySecondAppAlertType', - name: 'mySecondAppAlertType', - category: 'test', - producer: 'myApp', - enabledInLicense: true, - isExportable: true, - hasAlertsMappings: false, - hasFieldsForAAD: false, - validLegacyConsumers: [], - }; - const setOfAlertTypes = new Set([myAppAlertType, myOtherAppAlertType, mySecondAppAlertType]); - beforeEach(() => { - features.getKibanaFeatures.mockReturnValue([mockFeature('myApp', ['myOtherAppAlertType'])]); - }); - test('it returns authorized rule types given a set of feature ids', async () => { - const { authorization } = mockSecurity(); - const checkPrivileges: jest.MockedFunction< - ReturnType - > = jest.fn(); - authorization.checkPrivilegesDynamicallyWithRequest.mockReturnValue(checkPrivileges); + it('filters out rule types that are not in the rule type registry but registered in the feature', async () => { + ruleTypeRegistry.has.mockImplementation((ruleTypeId: string) => false); + checkPrivileges.mockResolvedValueOnce({ username: 'some-user', - hasAllRequested: false, + hasAllRequested: true, privileges: { kibana: [ { - privilege: mockAuthorizationAction('myOtherAppAlertType', 'myApp', 'alert', 'find'), + privilege: mockAuthorizationAction('rule-type-id-1', 'consumer-a', 'rule', 'get'), authorized: true, }, ], }, }); - const alertAuthorization = new AlertingAuthorization({ + + const auth = await AlertingAuthorization.create({ request, - authorization, ruleTypeRegistry, + getSpaceId, features, getSpace, - getSpaceId, + authorization: securityStart.authz, }); - ruleTypeRegistry.list.mockReturnValue(setOfAlertTypes); - await expect( - alertAuthorization.getAugmentedRuleTypesWithAuthorization( - ['myApp'], - [ReadOperations.Find, ReadOperations.Get, WriteOperations.Update], - AlertingAuthorizationEntity.Alert - ) - ).resolves.toMatchInlineSnapshot(` + expect( + // @ts-expect-error: need to test the private method + await auth._getAuthorizedRuleTypesWithAuthorizedConsumers({ + ruleTypeIds: ['rule-type-id-1'], + operations: [ReadOperations.Get, WriteOperations.Create], + authorizationEntity: AlertingAuthorizationEntity.Rule, + }) + ).toMatchInlineSnapshot(` Object { - "authorizedRuleTypes": Set { - Object { - "actionGroups": Array [], - "actionVariables": undefined, - "authorizedConsumers": Object { - "myApp": Object { - "all": false, - "read": true, - }, - }, - "category": "test", - "defaultActionGroupId": "default", - "enabledInLicense": true, - "hasAlertsMappings": false, - "hasFieldsForAAD": false, - "id": "myOtherAppAlertType", - "isExportable": true, - "minimumLicenseRequired": "basic", - "name": "myOtherAppAlertType", - "producer": "alerts", - "recoveryActionGroup": Object { - "id": "recovered", - "name": "Recovered", - }, - "validLegacyConsumers": Array [], - }, - }, - "hasAllRequested": false, + "authorizedRuleTypes": Map {}, + "hasAllRequested": true, "username": "some-user", } `); }); - test('it returns all authorized if user has read, get and update alert privileges', async () => { - const { authorization } = mockSecurity(); - const checkPrivileges: jest.MockedFunction< - ReturnType - > = jest.fn(); - authorization.checkPrivilegesDynamicallyWithRequest.mockReturnValue(checkPrivileges); + it('filters out rule types that are registered in the rule type registry but not in the feature', async () => { + ruleTypeRegistry.has.mockImplementation((ruleTypeId: string) => true); + checkPrivileges.mockResolvedValueOnce({ username: 'some-user', - hasAllRequested: false, + hasAllRequested: true, privileges: { kibana: [ { - privilege: mockAuthorizationAction('myOtherAppAlertType', 'myApp', 'alert', 'find'), - authorized: true, - }, - { - privilege: mockAuthorizationAction('myOtherAppAlertType', 'myApp', 'alert', 'get'), - authorized: true, - }, - { - privilege: mockAuthorizationAction('myOtherAppAlertType', 'myApp', 'alert', 'update'), + privilege: mockAuthorizationAction('not-exist', 'consumer-a', 'rule', 'get'), authorized: true, }, ], }, }); - const alertAuthorization = new AlertingAuthorization({ + + const auth = await AlertingAuthorization.create({ request, - authorization, ruleTypeRegistry, + getSpaceId, features, getSpace, - getSpaceId, + authorization: securityStart.authz, }); - ruleTypeRegistry.list.mockReturnValue(setOfAlertTypes); - await expect( - alertAuthorization.getAugmentedRuleTypesWithAuthorization( - ['myApp'], - [ReadOperations.Find, ReadOperations.Get, WriteOperations.Update], - AlertingAuthorizationEntity.Alert - ) - ).resolves.toMatchInlineSnapshot(` + expect( + // @ts-expect-error: need to test the private method + await auth._getAuthorizedRuleTypesWithAuthorizedConsumers({ + ruleTypeIds: ['not-exist'], + operations: [ReadOperations.Get, WriteOperations.Create], + authorizationEntity: AlertingAuthorizationEntity.Rule, + }) + ).toMatchInlineSnapshot(` Object { - "authorizedRuleTypes": Set { - Object { - "actionGroups": Array [], - "actionVariables": undefined, - "authorizedConsumers": Object { - "myApp": Object { - "all": true, - "read": true, - }, - }, - "category": "test", - "defaultActionGroupId": "default", - "enabledInLicense": true, - "hasAlertsMappings": false, - "hasFieldsForAAD": false, - "id": "myOtherAppAlertType", - "isExportable": true, - "minimumLicenseRequired": "basic", - "name": "myOtherAppAlertType", - "producer": "alerts", - "recoveryActionGroup": Object { - "id": "recovered", - "name": "Recovered", - }, - "validLegacyConsumers": Array [], - }, - }, - "hasAllRequested": false, + "authorizedRuleTypes": Map {}, + "hasAllRequested": true, "username": "some-user", } `); }); - }); - describe('8.11+', () => { - let alertAuthorization: AlertingAuthorization; - - const setOfRuleTypes: RegistryRuleType[] = [ - { - actionGroups: [], - actionVariables: undefined, - defaultActionGroupId: 'default', - minimumLicenseRequired: 'basic', - isExportable: true, - recoveryActionGroup: RecoveredActionGroup, - id: '.esQuery', - name: 'ES Query', - category: 'management', - producer: 'stackAlerts', - enabledInLicense: true, - hasAlertsMappings: false, - hasFieldsForAAD: false, - validLegacyConsumers: ['discover', 'alerts'], - }, - { - actionGroups: [], - actionVariables: undefined, - defaultActionGroupId: 'default', - minimumLicenseRequired: 'basic', - isExportable: true, - recoveryActionGroup: RecoveredActionGroup, - id: '.threshold-rule-o11y', - name: 'New threshold 011y', - category: 'observability', - producer: 'observability', - enabledInLicense: true, - hasAlertsMappings: false, - hasFieldsForAAD: false, - validLegacyConsumers: [], - }, - { - actionGroups: [], - actionVariables: undefined, - defaultActionGroupId: 'default', - minimumLicenseRequired: 'basic', - isExportable: true, - recoveryActionGroup: RecoveredActionGroup, - id: '.infrastructure-threshold-o11y', - name: 'Metrics o11y', - category: 'observability', - producer: 'infrastructure', - enabledInLicense: true, - hasAlertsMappings: false, - hasFieldsForAAD: false, - validLegacyConsumers: ['alerts'], - }, - { - actionGroups: [], - actionVariables: undefined, - defaultActionGroupId: 'default', - minimumLicenseRequired: 'basic', - isExportable: true, - recoveryActionGroup: RecoveredActionGroup, - id: '.logs-threshold-o11y', - name: 'Logs o11y', - category: 'observability', - producer: 'logs', - enabledInLicense: true, - hasAlertsMappings: false, - hasFieldsForAAD: false, - validLegacyConsumers: ['alerts'], - }, - ]; + it('call checkPrivileges with the correct actions', async () => { + const auth = await AlertingAuthorization.create({ + request, + ruleTypeRegistry, + getSpaceId, + features, + getSpace, + authorization: securityStart.authz, + }); - const onlyStackAlertsKibanaPrivileges = [ - { - privilege: mockAuthorizationAction('.esQuery', 'stackAlerts', 'rule', 'create'), - authorized: true, - }, - { - privilege: mockAuthorizationAction('.esQuery', 'stackAlerts', 'rule', 'find'), - authorized: true, - }, - ]; - const only011yKibanaPrivileges = [ - { - privilege: mockAuthorizationAction( - '.infrastructure-threshold-o11y', - 'infrastructure', - 'rule', - 'create' - ), - authorized: true, - }, - { - privilege: mockAuthorizationAction( - '.infrastructure-threshold-o11y', - 'infrastructure', - 'rule', - 'find' - ), - authorized: true, - }, - { - privilege: mockAuthorizationAction( - '.threshold-rule-o11y', - 'infrastructure', - 'rule', - 'create' - ), - authorized: true, - }, - { - privilege: mockAuthorizationAction( - '.threshold-rule-o11y', - 'infrastructure', - 'rule', - 'find' - ), - authorized: true, - }, - { - privilege: mockAuthorizationAction('.logs-threshold-o11y', 'logs', 'rule', 'create'), - authorized: true, - }, - { - privilege: mockAuthorizationAction('.logs-threshold-o11y', 'logs', 'rule', 'find'), - authorized: true, - }, - { - privilege: mockAuthorizationAction('.threshold-rule-o11y', 'logs', 'rule', 'create'), - authorized: true, - }, - { - privilege: mockAuthorizationAction('.threshold-rule-o11y', 'logs', 'rule', 'find'), - authorized: true, - }, - ]; - const onlyLogsAndStackAlertsKibanaPrivileges = [ - { - privilege: mockAuthorizationAction('.esQuery', 'stackAlerts', 'rule', 'create'), - authorized: true, - }, - { - privilege: mockAuthorizationAction('.esQuery', 'stackAlerts', 'rule', 'find'), - authorized: true, - }, - { - privilege: mockAuthorizationAction('.logs-threshold-o11y', 'logs', 'rule', 'create'), - authorized: true, - }, - { - privilege: mockAuthorizationAction('.logs-threshold-o11y', 'logs', 'rule', 'find'), - authorized: true, - }, - { - privilege: mockAuthorizationAction('.threshold-rule-o11y', 'logs', 'rule', 'create'), - authorized: true, - }, - { - privilege: mockAuthorizationAction('.threshold-rule-o11y', 'logs', 'rule', 'find'), - authorized: true, - }, - ]; - - beforeEach(async () => { - ruleTypeRegistry.list.mockReturnValue(new Set(setOfRuleTypes)); - ruleTypeRegistry.get.mockImplementation((id: string) => { - if (setOfRuleTypes.some((rt) => rt.id === id)) { - const ruleType = setOfRuleTypes.find((rt) => rt.id === id); - return (ruleType ?? {}) as NormalizedRuleType<{}, {}, {}, {}, {}, '', '', {}>; - } - return {} as NormalizedRuleType<{}, {}, {}, {}, {}, '', '', {}>; + // @ts-expect-error: need to test the private method + await auth._getAuthorizedRuleTypesWithAuthorizedConsumers({ + ruleTypeIds: [...ruleTypeIds, 'rule-type-not-exist'], + operations: [ReadOperations.Get, WriteOperations.Create], + authorizationEntity: AlertingAuthorizationEntity.Rule, }); - }); - describe('user only access to stack alerts + discover', () => { - beforeEach(() => { - const { authorization } = mockSecurity(); - const checkPrivileges: jest.MockedFunction< - ReturnType - > = jest.fn(); - authorization.mode.useRbacForRequest.mockReturnValue(true); - - features.getKibanaFeatures.mockReset(); - features.getKibanaFeatures.mockReturnValue([ - mockFeature('stackAlerts', ['.esQuery']), - mockFeature('discover', []), - ]); - checkPrivileges.mockReset(); - checkPrivileges.mockResolvedValue({ - username: 'onlyStack', - hasAllRequested: true, - privileges: { - kibana: onlyStackAlertsKibanaPrivileges, + expect(checkPrivileges).toBeCalledTimes(1); + expect(checkPrivileges.mock.calls[0]).toMatchInlineSnapshot(` + Array [ + Object { + "kibana": Array [ + "rule-type-id-1/alerts/rule/get", + "rule-type-id-1/alerts/rule/create", + "rule-type-id-1/consumer-a/rule/get", + "rule-type-id-1/consumer-a/rule/create", + "rule-type-id-1/consumer-b/rule/get", + "rule-type-id-1/consumer-b/rule/create", + "rule-type-id-2/alerts/rule/get", + "rule-type-id-2/alerts/rule/create", + "rule-type-id-2/consumer-b/rule/get", + "rule-type-id-2/consumer-b/rule/create", + "rule-type-id-3/alerts/rule/get", + "rule-type-id-3/alerts/rule/create", + "rule-type-id-3/consumer-c/rule/get", + "rule-type-id-3/consumer-c/rule/create", + "rule-type-id-4/consumer-d/rule/get", + "rule-type-id-4/consumer-d/rule/create", + ], }, - }); - authorization.checkPrivilegesDynamicallyWithRequest.mockReset(); - authorization.checkPrivilegesDynamicallyWithRequest.mockReturnValue(checkPrivileges); - alertAuthorization = new AlertingAuthorization({ - request, - authorization, - ruleTypeRegistry, - features, - getSpace, - getSpaceId, - }); - }); + ] + `); + }); - describe('ensureAuthorized', () => { - test('should allow to create .esquery rule type with stackAlerts consumer', async () => { - await expect( - alertAuthorization.ensureAuthorized({ - ruleTypeId: '.esQuery', - consumer: 'stackAlerts', - operation: WriteOperations.Create, - entity: AlertingAuthorizationEntity.Rule, - }) - ).resolves.toEqual(undefined); + it('call checkPrivileges with the correct actions when the rule type does not exist in the registry', async () => { + ruleTypeRegistry.has.mockImplementation((ruleTypeId: string) => false); - expect(ruleTypeRegistry.get).toHaveBeenCalledTimes(1); - }); - test('should allow to create .esquery rule type with discover consumer', async () => { - await expect( - alertAuthorization.ensureAuthorized({ - ruleTypeId: '.esQuery', - consumer: 'discover', - operation: WriteOperations.Create, - entity: AlertingAuthorizationEntity.Rule, - }) - ).resolves.toEqual(undefined); - - expect(ruleTypeRegistry.get).toHaveBeenCalledTimes(1); - }); - test('should allow to create .esquery rule type with alerts consumer', async () => { - await expect( - alertAuthorization.ensureAuthorized({ - ruleTypeId: '.esQuery', - consumer: 'alerts', - operation: WriteOperations.Create, - entity: AlertingAuthorizationEntity.Rule, - }) - ).resolves.toEqual(undefined); - - expect(ruleTypeRegistry.get).toHaveBeenCalledTimes(1); - }); - test('should throw an error to create .esquery rule type with logs consumer', async () => { - await expect( - alertAuthorization.ensureAuthorized({ - ruleTypeId: '.esQuery', - consumer: 'logs', - operation: WriteOperations.Create, - entity: AlertingAuthorizationEntity.Rule, - }) - ).rejects.toThrowErrorMatchingInlineSnapshot( - `"Unauthorized by \\"logs\\" to create \\".esQuery\\" rule"` - ); - - expect(ruleTypeRegistry.get).toHaveBeenCalledTimes(1); - }); - test('should throw an error to create .esquery rule type with infrastructure consumer', async () => { - await expect( - alertAuthorization.ensureAuthorized({ - ruleTypeId: '.esQuery', - consumer: 'infrastructure', - operation: WriteOperations.Create, - entity: AlertingAuthorizationEntity.Rule, - }) - ).rejects.toThrowErrorMatchingInlineSnapshot( - `"Unauthorized by \\"infrastructure\\" to create \\".esQuery\\" rule"` - ); - - expect(ruleTypeRegistry.get).toHaveBeenCalledTimes(1); - }); - test('should throw an error to create .threshold-rule-o11y rule type with alerts consumer', async () => { - await expect( - alertAuthorization.ensureAuthorized({ - ruleTypeId: '.threshold-rule-o11y', - consumer: 'alerts', - operation: WriteOperations.Create, - entity: AlertingAuthorizationEntity.Rule, - }) - ).rejects.toThrowErrorMatchingInlineSnapshot( - `"Unauthorized by \\"alerts\\" to create \\".threshold-rule-o11y\\" rule"` - ); - - expect(ruleTypeRegistry.get).toHaveBeenCalledTimes(1); - }); - test('should throw an error to create .logs-threshold-o11y rule type with alerts infrastructure', async () => { - await expect( - alertAuthorization.ensureAuthorized({ - ruleTypeId: '.logs-threshold-o11y', - consumer: 'alerts', - operation: WriteOperations.Create, - entity: AlertingAuthorizationEntity.Rule, - }) - ).rejects.toThrowErrorMatchingInlineSnapshot( - `"Unauthorized by \\"alerts\\" to create \\".logs-threshold-o11y\\" rule"` - ); - - expect(ruleTypeRegistry.get).toHaveBeenCalledTimes(1); - }); + const auth = await AlertingAuthorization.create({ + request, + ruleTypeRegistry, + getSpaceId, + features, + getSpace, + authorization: securityStart.authz, }); - test('creates a filter based on the privileged types', async () => { - const filter = ( - await alertAuthorization.getFindAuthorizationFilter(AlertingAuthorizationEntity.Rule, { - type: AlertingAuthorizationFilterType.KQL, - fieldNames: { - ruleTypeId: 'path.to.rule_type_id', - consumer: 'consumer-field', - }, - }) - ).filter; - expect(toKqlExpression(filter as KueryNode)).toMatchInlineSnapshot( - `"(path.to.rule_type_id: .esQuery AND (consumer-field: alerts OR consumer-field: discover OR consumer-field: stackAlerts))"` - ); + // @ts-expect-error: need to test the private method + await auth._getAuthorizedRuleTypesWithAuthorizedConsumers({ + ruleTypeIds: ['rule-type-id-1'], + operations: [ReadOperations.Get, WriteOperations.Create], + authorizationEntity: AlertingAuthorizationEntity.Rule, }); - }); - describe('user only access to o11y', () => { - beforeEach(() => { - const { authorization } = mockSecurity(); - const checkPrivileges: jest.MockedFunction< - ReturnType - > = jest.fn(); - authorization.mode.useRbacForRequest.mockReturnValue(true); - - features.getKibanaFeatures.mockReset(); - features.getKibanaFeatures.mockReturnValue([ - mockFeature('infrastructure', [ - '.infrastructure-threshold-o11y', - '.threshold-rule-o11y', - '.esQuery', - ]), - mockFeature('logs', ['.threshold-rule-o11y', '.esQuery', '.logs-threshold-o11y']), - ]); - checkPrivileges.mockReset(); - checkPrivileges.mockResolvedValue({ - username: 'onlyO11y', - hasAllRequested: true, - privileges: { - kibana: only011yKibanaPrivileges, + expect(checkPrivileges).toBeCalledTimes(1); + expect(checkPrivileges.mock.calls[0]).toMatchInlineSnapshot(` + Array [ + Object { + "kibana": Array [], }, - }); - authorization.checkPrivilegesDynamicallyWithRequest.mockReset(); - authorization.checkPrivilegesDynamicallyWithRequest.mockReturnValue(checkPrivileges); - alertAuthorization = new AlertingAuthorization({ - request, - authorization, - ruleTypeRegistry, - features, - getSpace, - getSpaceId, - }); - }); - - describe('ensureAuthorized', () => { - test('should throw an error to create .esquery rule type with stackAlerts consumer', async () => { - await expect( - alertAuthorization.ensureAuthorized({ - ruleTypeId: '.esQuery', - consumer: 'stackAlerts', - operation: WriteOperations.Create, - entity: AlertingAuthorizationEntity.Rule, - }) - ).rejects.toThrowErrorMatchingInlineSnapshot( - `"Unauthorized by \\"stackAlerts\\" to create \\".esQuery\\" rule"` - ); - - expect(ruleTypeRegistry.get).toHaveBeenCalledTimes(1); - }); - test('should throw an error to create .esquery rule type with discover consumer', async () => { - await expect( - alertAuthorization.ensureAuthorized({ - ruleTypeId: '.esQuery', - consumer: 'discover', - operation: WriteOperations.Create, - entity: AlertingAuthorizationEntity.Rule, - }) - ).rejects.toThrowErrorMatchingInlineSnapshot( - `"Unauthorized by \\"discover\\" to create \\".esQuery\\" rule"` - ); - - expect(ruleTypeRegistry.get).toHaveBeenCalledTimes(1); - }); - test('should throw an error to create .threshold-rule-o11y rule type with alerts consumer', async () => { - await expect( - alertAuthorization.ensureAuthorized({ - ruleTypeId: '.threshold-rule-o11y', - consumer: 'alerts', - operation: WriteOperations.Create, - entity: AlertingAuthorizationEntity.Rule, - }) - ).rejects.toThrowErrorMatchingInlineSnapshot( - `"Unauthorized by \\"alerts\\" to create \\".threshold-rule-o11y\\" rule"` - ); - - expect(ruleTypeRegistry.get).toHaveBeenCalledTimes(1); - }); - test('should allow to create .esquery rule type with logs consumer', async () => { - await expect( - alertAuthorization.ensureAuthorized({ - ruleTypeId: '.esQuery', - consumer: 'logs', - operation: WriteOperations.Create, - entity: AlertingAuthorizationEntity.Rule, - }) - ).resolves.toEqual(undefined); - - expect(ruleTypeRegistry.get).toHaveBeenCalledTimes(1); - }); - test('should allow to create .esquery rule type with logs infrastructure', async () => { - await expect( - alertAuthorization.ensureAuthorized({ - ruleTypeId: '.esQuery', - consumer: 'infrastructure', - operation: WriteOperations.Create, - entity: AlertingAuthorizationEntity.Rule, - }) - ).resolves.toEqual(undefined); - - expect(ruleTypeRegistry.get).toHaveBeenCalledTimes(1); - }); - test('should allow to create .logs-threshold-o11y rule type with alerts consumer', async () => { - await expect( - alertAuthorization.ensureAuthorized({ - ruleTypeId: '.logs-threshold-o11y', - consumer: 'alerts', - operation: WriteOperations.Create, - entity: AlertingAuthorizationEntity.Rule, - }) - ).resolves.toEqual(undefined); - - expect(ruleTypeRegistry.get).toHaveBeenCalledTimes(1); - }); - test('should throw an error to create .threshold-rule-o11y rule type with logs consumer', async () => { - await expect( - alertAuthorization.ensureAuthorized({ - ruleTypeId: '.threshold-rule-o11y', - consumer: 'logs', - operation: WriteOperations.Create, - entity: AlertingAuthorizationEntity.Rule, - }) - ).resolves.toEqual(undefined); - - expect(ruleTypeRegistry.get).toHaveBeenCalledTimes(1); - }); - }); - test('creates a filter based on the privileged types', async () => { - expect( - ( - await alertAuthorization.getFindAuthorizationFilter( - AlertingAuthorizationEntity.Rule, - { - type: AlertingAuthorizationFilterType.KQL, - fieldNames: { - ruleTypeId: 'path.to.rule_type_id', - consumer: 'consumer-field', - }, - }, - new Set(['infrastructure', 'logs']) - ) - ).filter - ).toEqual( - fromKueryExpression( - `(path.to.rule_type_id:.infrastructure-threshold-o11y and consumer-field:(infrastructure or alerts)) or (path.to.rule_type_id:.threshold-rule-o11y and consumer-field:(infrastructure or logs)) or (path.to.rule_type_id:.logs-threshold-o11y and consumer-field:(logs or alerts))` - ) - ); - }); + ] + `); }); - describe('user only access to logs and stackAlerts', () => { - beforeEach(() => { - const { authorization } = mockSecurity(); - const checkPrivileges: jest.MockedFunction< - ReturnType - > = jest.fn(); - authorization.mode.useRbacForRequest.mockReturnValue(true); - - features.getKibanaFeatures.mockClear(); - features.getKibanaFeatures.mockReturnValue([ - mockFeature('stackAlerts', ['.esQuery']), - mockFeature('logs', ['.logs-threshold-o11y', '.threshold-rule-o11y', '.esQuery']), - ]); - checkPrivileges.mockClear(); - checkPrivileges.mockResolvedValue({ - username: 'stackAndLogs', - hasAllRequested: true, - privileges: { - kibana: onlyLogsAndStackAlertsKibanaPrivileges, - }, - }); - authorization.checkPrivilegesDynamicallyWithRequest.mockReturnValue(checkPrivileges); - alertAuthorization = new AlertingAuthorization({ - request, - authorization, - ruleTypeRegistry, - features, - getSpace, - getSpaceId, - }); - }); - - describe('ensureAuthorized', () => { - test('should allow to create .esquery rule type with stackAlerts consumer', async () => { - await expect( - alertAuthorization.ensureAuthorized({ - ruleTypeId: '.esQuery', - consumer: 'stackAlerts', - operation: WriteOperations.Create, - entity: AlertingAuthorizationEntity.Rule, - }) - ).resolves.toEqual(undefined); + it('call checkPrivileges with the correct actions when the rule type does not exist in the feature', async () => { + ruleTypeRegistry.has.mockImplementation((ruleTypeId: string) => true); - expect(ruleTypeRegistry.get).toHaveBeenCalledTimes(1); - }); - test('should allow to create .esquery rule type with discover consumer', async () => { - await expect( - alertAuthorization.ensureAuthorized({ - ruleTypeId: '.esQuery', - consumer: 'discover', - operation: WriteOperations.Create, - entity: AlertingAuthorizationEntity.Rule, - }) - ).resolves.toEqual(undefined); - - expect(ruleTypeRegistry.get).toHaveBeenCalledTimes(1); - }); - test('should allow to create .esquery rule type with logs consumer', async () => { - await expect( - alertAuthorization.ensureAuthorized({ - ruleTypeId: '.esQuery', - consumer: 'logs', - operation: WriteOperations.Create, - entity: AlertingAuthorizationEntity.Rule, - }) - ).resolves.toEqual(undefined); - - expect(ruleTypeRegistry.get).toHaveBeenCalledTimes(1); - }); - test('should allow to create .logs-threshold-o11y rule type with alerts consumer', async () => { - await expect( - alertAuthorization.ensureAuthorized({ - ruleTypeId: '.logs-threshold-o11y', - consumer: 'alerts', - operation: WriteOperations.Create, - entity: AlertingAuthorizationEntity.Rule, - }) - ).resolves.toEqual(undefined); - - expect(ruleTypeRegistry.get).toHaveBeenCalledTimes(1); - }); - test('should throw an error to create .threshold-rule-o11y rule type with logs consumer', async () => { - await expect( - alertAuthorization.ensureAuthorized({ - ruleTypeId: '.threshold-rule-o11y', - consumer: 'logs', - operation: WriteOperations.Create, - entity: AlertingAuthorizationEntity.Rule, - }) - ).resolves.toEqual(undefined); - - expect(ruleTypeRegistry.get).toHaveBeenCalledTimes(1); - }); - test('should throw an error to create .esquery rule type with logs infrastructure', async () => { - await expect( - alertAuthorization.ensureAuthorized({ - ruleTypeId: '.esQuery', - consumer: 'infrastructure', - operation: WriteOperations.Create, - entity: AlertingAuthorizationEntity.Rule, - }) - ).rejects.toThrowErrorMatchingInlineSnapshot( - `"Unauthorized by \\"infrastructure\\" to create \\".esQuery\\" rule"` - ); - - expect(ruleTypeRegistry.get).toHaveBeenCalledTimes(1); - }); - test('should throw an error to create .threshold-rule-o11y rule type with alerts consumer', async () => { - await expect( - alertAuthorization.ensureAuthorized({ - ruleTypeId: '.threshold-rule-o11y', - consumer: 'alerts', - operation: WriteOperations.Create, - entity: AlertingAuthorizationEntity.Rule, - }) - ).rejects.toThrowErrorMatchingInlineSnapshot( - `"Unauthorized by \\"alerts\\" to create \\".threshold-rule-o11y\\" rule"` - ); - - expect(ruleTypeRegistry.get).toHaveBeenCalledTimes(1); - }); - test('should throw an error to create .esquery rule type with infrastructure consumer', async () => { - await expect( - alertAuthorization.ensureAuthorized({ - ruleTypeId: '.esQuery', - consumer: 'infrastructure', - operation: WriteOperations.Create, - entity: AlertingAuthorizationEntity.Rule, - }) - ).rejects.toThrowErrorMatchingInlineSnapshot( - `"Unauthorized by \\"infrastructure\\" to create \\".esQuery\\" rule"` - ); - - expect(ruleTypeRegistry.get).toHaveBeenCalledTimes(1); - }); + const auth = await AlertingAuthorization.create({ + request, + ruleTypeRegistry, + getSpaceId, + features, + getSpace, + authorization: securityStart.authz, }); - test('creates a filter based on the privileged types', async () => { - const filter = ( - await alertAuthorization.getFindAuthorizationFilter(AlertingAuthorizationEntity.Rule, { - type: AlertingAuthorizationFilterType.KQL, - fieldNames: { - ruleTypeId: 'path.to.rule_type_id', - consumer: 'consumer-field', - }, - }) - ).filter; - - expect(toKqlExpression(filter as KueryNode)).toMatchInlineSnapshot( - `"((path.to.rule_type_id: .esQuery AND (consumer-field: alerts OR consumer-field: discover OR consumer-field: stackAlerts OR consumer-field: logs)) OR (path.to.rule_type_id: .logs-threshold-o11y AND (consumer-field: alerts OR consumer-field: discover OR consumer-field: stackAlerts OR consumer-field: logs)) OR (path.to.rule_type_id: .threshold-rule-o11y AND (consumer-field: alerts OR consumer-field: discover OR consumer-field: stackAlerts OR consumer-field: logs)))"` - ); + // @ts-expect-error: need to test the private method + await auth._getAuthorizedRuleTypesWithAuthorizedConsumers({ + ruleTypeIds: ['not-exist'], + operations: [ReadOperations.Get, WriteOperations.Create], + authorizationEntity: AlertingAuthorizationEntity.Rule, }); + + expect(checkPrivileges).toBeCalledTimes(1); + expect(checkPrivileges.mock.calls[0]).toMatchInlineSnapshot(` + Array [ + Object { + "kibana": Array [], + }, + ] + `); }); }); }); diff --git a/x-pack/plugins/alerting/server/authorization/alerting_authorization.ts b/x-pack/plugins/alerting/server/authorization/alerting_authorization.ts index 6b24f2f5de9a4..a7e36590d2217 100644 --- a/x-pack/plugins/alerting/server/authorization/alerting_authorization.ts +++ b/x-pack/plugins/alerting/server/authorization/alerting_authorization.ts @@ -6,61 +6,20 @@ */ import Boom from '@hapi/boom'; -import { has, isEmpty } from 'lodash'; import { KibanaRequest } from '@kbn/core/server'; import { JsonObject } from '@kbn/utility-types'; import { KueryNode } from '@kbn/es-query'; -import { SecurityPluginSetup } from '@kbn/security-plugin/server'; +import { SecurityPluginStart } from '@kbn/security-plugin/server'; import { FeaturesPluginStart } from '@kbn/features-plugin/server'; import { Space } from '@kbn/spaces-plugin/server'; -import { STACK_ALERTS_FEATURE_ID } from '@kbn/rule-data-utils'; import { RegistryRuleType } from '../rule_type_registry'; -import { ALERTING_FEATURE_ID, RuleTypeRegistry } from '../types'; +import { RuleTypeRegistry } from '../types'; import { asFiltersByRuleTypeAndConsumer, asFiltersBySpaceId, AlertingAuthorizationFilterOpts, } from './alerting_authorization_kuery'; - -export enum AlertingAuthorizationEntity { - Rule = 'rule', - Alert = 'alert', -} - -export enum ReadOperations { - Get = 'get', - GetRuleState = 'getRuleState', - GetAlertSummary = 'getAlertSummary', - GetExecutionLog = 'getExecutionLog', - GetActionErrorLog = 'getActionErrorLog', - Find = 'find', - GetAuthorizedAlertsIndices = 'getAuthorizedAlertsIndices', - GetRuleExecutionKPI = 'getRuleExecutionKPI', - GetBackfill = 'getBackfill', - FindBackfill = 'findBackfill', -} - -export enum WriteOperations { - Create = 'create', - Delete = 'delete', - Update = 'update', - UpdateApiKey = 'updateApiKey', - Enable = 'enable', - Disable = 'disable', - MuteAll = 'muteAll', - UnmuteAll = 'unmuteAll', - MuteAlert = 'muteAlert', - UnmuteAlert = 'unmuteAlert', - Snooze = 'snooze', - BulkEdit = 'bulkEdit', - BulkDelete = 'bulkDelete', - BulkEnable = 'bulkEnable', - BulkDisable = 'bulkDisable', - Unsnooze = 'unsnooze', - RunSoon = 'runSoon', - ScheduleBackfill = 'scheduleBackfill', - DeleteBackfill = 'deleteBackfill', -} +import { ReadOperations, WriteOperations, AlertingAuthorizationEntity } from './types'; export interface EnsureAuthorizedOpts { ruleTypeId: string; @@ -74,75 +33,178 @@ interface HasPrivileges { read: boolean; all: boolean; } + type AuthorizedConsumers = Record; export interface RegistryAlertTypeWithAuth extends RegistryRuleType { authorizedConsumers: AuthorizedConsumers; } -type IsAuthorizedAtProducerLevel = boolean; -export interface ConstructorOptions { +export type AuthorizedRuleTypes = Map; + +export interface CreateOptions { ruleTypeRegistry: RuleTypeRegistry; request: KibanaRequest; features: FeaturesPluginStart; getSpace: (request: KibanaRequest) => Promise; getSpaceId: (request: KibanaRequest) => string | undefined; - authorization?: SecurityPluginSetup['authz']; + authorization?: SecurityPluginStart['authz']; +} + +type ConstructorOptions = Pick< + CreateOptions, + 'ruleTypeRegistry' | 'request' | 'authorization' | 'getSpaceId' +> & { + allRegisteredConsumers: Set; + ruleTypesConsumersMap: Map>; +}; + +interface GetAuthorizationFilterParams { + authorizationEntity: AlertingAuthorizationEntity; + filterOpts: AlertingAuthorizationFilterOpts; + operation: WriteOperations | ReadOperations; } -const DISCOVER_FEATURE_ID = 'discover'; +interface GetAuthorizedRuleTypesWithAuthorizedConsumersParams { + ruleTypeIds?: string[]; + operations: Array; + authorizationEntity: AlertingAuthorizationEntity; +} + +interface GetAllAuthorizedRuleTypesFindOperationParams { + authorizationEntity: AlertingAuthorizationEntity; + ruleTypeIds?: string[]; +} + +interface GetFindAuthorizationFilterParams { + authorizationEntity: AlertingAuthorizationEntity; + filterOpts: AlertingAuthorizationFilterOpts; +} + +interface GetAuthorizedRuleTypesParams { + ruleTypeIds?: string[]; + operations: Array; + authorizationEntity: AlertingAuthorizationEntity; +} + +interface GetAllAuthorizedRuleTypes { + operations: Array; + authorizationEntity: AlertingAuthorizationEntity; +} export class AlertingAuthorization { private readonly ruleTypeRegistry: RuleTypeRegistry; private readonly request: KibanaRequest; - private readonly authorization?: SecurityPluginSetup['authz']; - private readonly featuresIds: Promise>; - private readonly allPossibleConsumers: Promise; + private readonly authorization?: SecurityPluginStart['authz']; + private readonly allRegisteredConsumers: Set; + private readonly ruleTypesConsumersMap: Map>; private readonly spaceId: string | undefined; - private readonly features: FeaturesPluginStart; + constructor({ ruleTypeRegistry, request, authorization, - features, - getSpace, getSpaceId, + allRegisteredConsumers, + ruleTypesConsumersMap, }: ConstructorOptions) { this.request = request; this.authorization = authorization; this.ruleTypeRegistry = ruleTypeRegistry; - this.features = features; + this.allRegisteredConsumers = allRegisteredConsumers; + this.ruleTypesConsumersMap = ruleTypesConsumersMap; this.spaceId = getSpaceId(request); + } - this.featuresIds = getSpace(request) - .then((maybeSpace) => new Set(maybeSpace?.disabledFeatures ?? [])) - .then( - (disabledFeatures) => - new Set( - features - .getKibanaFeatures() - .filter( - ({ id, alerting }) => - // ignore features which are disabled in the user's space - !disabledFeatures.has(id) && - // ignore features which don't grant privileges to alerting - (alerting?.length ?? 0 > 0) - ) - .map((feature) => feature.id) - ) - ) - .catch(() => { - // failing to fetch the space means the user is likely not privileged in the - // active space at all, which means that their list of features should be empty - return new Set(); - }); + /** + * Creates an AlertingAuthorization object. + */ + static async create({ + request, + features, + getSpace, + getSpaceId, + authorization, + ruleTypeRegistry, + }: CreateOptions): Promise { + const allRegisteredConsumers = new Set(); + const ruleTypesConsumersMap = new Map>(); + let maybeSpace; + + try { + maybeSpace = await getSpace(request); + } catch (error) { + /** + * Failing to fetch the space with 403 or 404 means the user is likely not privileged in the active space at all + * which means that `allRegisteredConsumers` and `ruleTypesConsumersMap` should be empty. By initializing the alerting authorization + * with empty data structures we ensure that the user will not have access to any rule types in the active space. + * All other errors are treated as server errors and they are surfaced to the upper level. + */ + if (Boom.isBoom(error) && [403, 404].includes(error.output.statusCode)) { + return new AlertingAuthorization({ + request, + authorization, + getSpaceId, + ruleTypeRegistry, + allRegisteredConsumers, + ruleTypesConsumersMap, + }); + } + + if (Boom.isBoom(error)) { + throw error; + } - this.allPossibleConsumers = this.featuresIds.then((featuresIds) => { - return featuresIds.size - ? asAuthorizedConsumers([ALERTING_FEATURE_ID, DISCOVER_FEATURE_ID, ...featuresIds], { - read: true, - all: true, - }) - : {}; + throw new Error(`Failed to create AlertingAuthorization class: ${error}`); + } + + const disabledFeatures = new Set(maybeSpace?.disabledFeatures ?? []); + const featuresWithAlertingConfigured = features.getKibanaFeatures().filter( + ({ id, alerting }) => + // ignore features which are disabled in the user's space + !disabledFeatures.has(id) && + // ignore features which don't grant privileges to alerting + Boolean(alerting?.length) + ); + + /** + * Each feature configures a set of rule types. Each + * rule type configures its valid consumers. For example, + * + * { id: 'my-feature-id-1', alerting: [{ ruleTypeId: 'my-rule-type', consumers: ['consumer-a', 'consumer-b'] }] } + * { id: 'my-feature-id-2', alerting: [{ ruleTypeId: 'my-rule-type-2', consumers: ['consumer-a', 'consumer-d'] }] } + * + * In this loop we iterate over all features and we construct: + * a) a set that contains all registered consumers and + * b) a map that contains all valid consumers per rule type. + * We remove duplicates in the process. For example, + * + * allRegisteredConsumers: Set(1) { 'consumer-a', 'consumer-b', 'consumer-d' } + * ruleTypesConsumersMap: Map(1) { + * 'my-rule-type' => Set(1) { 'consumer-a', 'consumer-b' } + * 'my-rule-type-2' => Set(1) { 'consumer-a', 'consumer-d' } + * } + */ + for (const feature of featuresWithAlertingConfigured) { + if (feature.alerting) { + for (const entry of feature.alerting) { + const consumers = ruleTypesConsumersMap.get(entry.ruleTypeId) ?? new Set(); + + entry.consumers.forEach((consumer) => { + consumers.add(consumer); + allRegisteredConsumers.add(consumer); + }); + ruleTypesConsumersMap.set(entry.ruleTypeId, consumers); + } + } + } + + return new AlertingAuthorization({ + request, + authorization, + getSpaceId, + ruleTypeRegistry, + allRegisteredConsumers, + ruleTypesConsumersMap, }); } @@ -155,42 +217,30 @@ export class AlertingAuthorization { } /* - * This method exposes the private 'augmentRuleTypesWithAuthorization' to be + * This method exposes the private '_getAuthorizedRuleTypesWithAuthorizedConsumers' to be * used by the RAC/Alerts client */ - public async getAugmentedRuleTypesWithAuthorization( - featureIds: readonly string[], - operations: Array, - authorizationEntity: AlertingAuthorizationEntity - ): Promise<{ + public async getAllAuthorizedRuleTypes(params: GetAllAuthorizedRuleTypes): Promise<{ username?: string; hasAllRequested: boolean; - authorizedRuleTypes: Set; + authorizedRuleTypes: AuthorizedRuleTypes; }> { - return this.augmentRuleTypesWithAuthorization( - this.ruleTypeRegistry.list(), - operations, - authorizationEntity, - new Set(featureIds) - ); + return this._getAuthorizedRuleTypesWithAuthorizedConsumers({ + operations: params.operations, + authorizationEntity: params.authorizationEntity, + }); } public async ensureAuthorized({ ruleTypeId, - consumer: legacyConsumer, + consumer, operation, entity, additionalPrivileges = [], }: EnsureAuthorizedOpts) { const { authorization } = this; - const ruleType = this.ruleTypeRegistry.get(ruleTypeId); - const consumer = getValidConsumer({ - validLegacyConsumers: ruleType.validLegacyConsumers, - legacyConsumer, - producer: ruleType.producer, - }); - const isAvailableConsumer = has(await this.allPossibleConsumers, consumer); + const isAvailableConsumer = this.allRegisteredConsumers.has(consumer); if (authorization && this.shouldCheckAuthorization()) { const checkPrivileges = authorization.checkPrivilegesDynamicallyWithRequest(this.request); @@ -209,7 +259,7 @@ export class AlertingAuthorization { * as Privileged. * This check will ensure we don't accidentally let these through */ - throw Boom.forbidden(getUnauthorizedMessage(ruleTypeId, legacyConsumer, operation, entity)); + throw Boom.forbidden(getUnauthorizedMessage(ruleTypeId, consumer, operation, entity)); } if (!hasAllRequested) { @@ -220,274 +270,204 @@ export class AlertingAuthorization { } } - public async getFindAuthorizationFilter( - authorizationEntity: AlertingAuthorizationEntity, - filterOpts: AlertingAuthorizationFilterOpts, - featuresIds?: Set - ): Promise<{ + public async getFindAuthorizationFilter(params: GetFindAuthorizationFilterParams): Promise<{ filter?: KueryNode | JsonObject; ensureRuleTypeIsAuthorized: (ruleTypeId: string, consumer: string, auth: string) => void; }> { - return this.getAuthorizationFilter( - authorizationEntity, - filterOpts, - ReadOperations.Find, - featuresIds - ); + return this.getAuthorizationFilter({ + operation: ReadOperations.Find, + authorizationEntity: params.authorizationEntity, + filterOpts: params.filterOpts, + }); } - public async getAuthorizedRuleTypes( - authorizationEntity: AlertingAuthorizationEntity, - featuresIds?: Set - ): Promise { - const { authorizedRuleTypes } = await this.augmentRuleTypesWithAuthorization( - this.ruleTypeRegistry.list(), - [ReadOperations.Find], - authorizationEntity, - featuresIds - ); - return Array.from(authorizedRuleTypes); + public async getAllAuthorizedRuleTypesFindOperation( + params: GetAllAuthorizedRuleTypesFindOperationParams + ): Promise { + const { authorizedRuleTypes } = await this._getAuthorizedRuleTypesWithAuthorizedConsumers({ + ruleTypeIds: params.ruleTypeIds, + operations: [ReadOperations.Find], + authorizationEntity: params.authorizationEntity, + }); + + return authorizedRuleTypes; } - public async getAuthorizationFilter( - authorizationEntity: AlertingAuthorizationEntity, - filterOpts: AlertingAuthorizationFilterOpts, - operation: WriteOperations | ReadOperations, - featuresIds?: Set - ): Promise<{ + public async getAuthorizationFilter(params: GetAuthorizationFilterParams): Promise<{ filter?: KueryNode | JsonObject; ensureRuleTypeIsAuthorized: (ruleTypeId: string, consumer: string, auth: string) => void; }> { if (this.authorization && this.shouldCheckAuthorization()) { - const { authorizedRuleTypes } = await this.augmentRuleTypesWithAuthorization( - this.ruleTypeRegistry.list(), - [operation], - authorizationEntity, - featuresIds - ); + const { authorizedRuleTypes } = await this._getAuthorizedRuleTypesWithAuthorizedConsumers({ + operations: [params.operation], + authorizationEntity: params.authorizationEntity, + }); if (!authorizedRuleTypes.size) { - throw Boom.forbidden(`Unauthorized to find ${authorizationEntity}s for any rule types`); + throw Boom.forbidden( + `Unauthorized to ${params.operation} ${params.authorizationEntity}s for any rule types` + ); } - const authorizedRuleTypeIdsToConsumers = new Set( - [...authorizedRuleTypes].reduce((ruleTypeIdConsumerPairs, ruleType) => { - for (const consumer of Object.keys(ruleType.authorizedConsumers)) { - ruleTypeIdConsumerPairs.push(`${ruleType.id}/${consumer}/${authorizationEntity}`); - } - return ruleTypeIdConsumerPairs; - }, []) - ); - - const authorizedEntries: Map> = new Map(); return { filter: asFiltersByRuleTypeAndConsumer( authorizedRuleTypes, - filterOpts, + params.filterOpts, this.spaceId ) as JsonObject, ensureRuleTypeIsAuthorized: (ruleTypeId: string, consumer: string, authType: string) => { - if (!authorizedRuleTypeIdsToConsumers.has(`${ruleTypeId}/${consumer}/${authType}`)) { + if (!authorizedRuleTypes.has(ruleTypeId) || authType !== params.authorizationEntity) { + throw Boom.forbidden( + getUnauthorizedMessage(ruleTypeId, consumer, params.operation, authType) + ); + } + + const authorizedRuleType = authorizedRuleTypes.get(ruleTypeId)!; + const authorizedConsumers = authorizedRuleType.authorizedConsumers; + + if (!authorizedConsumers[consumer]) { throw Boom.forbidden( - getUnauthorizedMessage(ruleTypeId, consumer, 'find', authorizationEntity) + getUnauthorizedMessage( + ruleTypeId, + consumer, + params.operation, + params.authorizationEntity + ) ); - } else { - if (authorizedEntries.has(ruleTypeId)) { - authorizedEntries.get(ruleTypeId)!.add(consumer); - } else { - authorizedEntries.set(ruleTypeId, new Set([consumer])); - } } }, }; } return { - filter: asFiltersBySpaceId(filterOpts, this.spaceId) as JsonObject, + filter: asFiltersBySpaceId(params.filterOpts, this.spaceId) as JsonObject, ensureRuleTypeIsAuthorized: (ruleTypeId: string, consumer: string, authType: string) => {}, }; } - public async filterByRuleTypeAuthorization( - ruleTypes: Set, - operations: Array, - authorizationEntity: AlertingAuthorizationEntity - ): Promise> { - const { authorizedRuleTypes } = await this.augmentRuleTypesWithAuthorization( - ruleTypes, - operations, - authorizationEntity - ); + public async getAuthorizedRuleTypes( + params: GetAuthorizedRuleTypesParams + ): Promise { + const { authorizedRuleTypes } = await this._getAuthorizedRuleTypesWithAuthorizedConsumers({ + ruleTypeIds: params.ruleTypeIds, + operations: params.operations, + authorizationEntity: params.authorizationEntity, + }); + return authorizedRuleTypes; } - private async augmentRuleTypesWithAuthorization( - ruleTypes: Set, - operations: Array, - authorizationEntity: AlertingAuthorizationEntity, - featuresIds?: Set + private async _getAuthorizedRuleTypesWithAuthorizedConsumers( + params: GetAuthorizedRuleTypesWithAuthorizedConsumersParams ): Promise<{ username?: string; hasAllRequested: boolean; - authorizedRuleTypes: Set; + authorizedRuleTypes: Map; }> { - const fIds = new Set(featuresIds ?? (await this.featuresIds)); + const { operations, authorizationEntity } = params; + const ruleTypeIds = params.ruleTypeIds + ? new Set(params.ruleTypeIds) + : new Set(this.ruleTypeRegistry.getAllTypes()); - /** - * Temporary hack to fix issues with the discover consumer. - * Issue: https://github.com/elastic/kibana/issues/184595. - * PR https://github.com/elastic/kibana/pull/183756 will - * remove the hack and fix it in a generic way. - * - * The discover consumer should be authorized - * as the stackAlerts consumer. - */ - if (fIds.has(DISCOVER_FEATURE_ID)) { - fIds.delete(DISCOVER_FEATURE_ID); - fIds.add(STACK_ALERTS_FEATURE_ID); - } + const requiredPrivileges = new Map< + string, + { ruleTypeId: string; consumer: string; operation: ReadOperations | WriteOperations } + >(); if (this.authorization && this.shouldCheckAuthorization()) { + const authorizedRuleTypes = new Map(); + const checkPrivileges = this.authorization.checkPrivilegesDynamicallyWithRequest( this.request ); - // add an empty `authorizedConsumers` array on each ruleType - const ruleTypesWithAuthorization = Array.from( - this.augmentWithAuthorizedConsumers(ruleTypes, {}) - ); - const ruleTypesAuthorized: Map = new Map(); - // map from privilege to ruleType which we can refer back to when analyzing the result - // of checkPrivileges - const privilegeToRuleType = new Map< - string, - [RegistryAlertTypeWithAuth, string, HasPrivileges, IsAuthorizedAtProducerLevel] - >(); - const allPossibleConsumers = await this.allPossibleConsumers; - const addLegacyConsumerPrivileges = (legacyConsumer: string) => - legacyConsumer === ALERTING_FEATURE_ID || - legacyConsumer === DISCOVER_FEATURE_ID || - isEmpty(featuresIds); - - for (const feature of fIds) { - const featureDef = this.features - .getKibanaFeatures() - .find((kFeature) => kFeature.id === feature); - - for (const ruleTypeId of featureDef?.alerting ?? []) { - const ruleTypeAuth = ruleTypesWithAuthorization.find((rtwa) => rtwa.id === ruleTypeId); - if (ruleTypeAuth) { - if (!ruleTypesAuthorized.has(ruleTypeId)) { - ruleTypesAuthorized.set(ruleTypeId, ruleTypeAuth); - } - for (const operation of operations) { - privilegeToRuleType.set( - this.authorization!.actions.alerting.get( - ruleTypeId, - feature, - authorizationEntity, - operation - ), - [ - ruleTypeAuth, - feature, - hasPrivilegeByOperation(operation), - ruleTypeAuth.producer === feature, - ] - ); - // FUTURE ENGINEER - // We are just trying to add back the legacy consumers associated - // to the rule type to get back the privileges that was given at one point - if (!isEmpty(ruleTypeAuth.validLegacyConsumers)) { - ruleTypeAuth.validLegacyConsumers.forEach((legacyConsumer) => { - if (addLegacyConsumerPrivileges(legacyConsumer)) { - if (!allPossibleConsumers[legacyConsumer]) { - allPossibleConsumers[legacyConsumer] = { - read: true, - all: true, - }; - } - - privilegeToRuleType.set( - this.authorization!.actions.alerting.get( - ruleTypeId, - legacyConsumer, - authorizationEntity, - operation - ), - [ruleTypeAuth, legacyConsumer, hasPrivilegeByOperation(operation), false] - ); - } - }); + for (const ruleTypeId of ruleTypeIds) { + /** + * Skip if the ruleTypeId is not configured in any feature + * or it is not set in the rule type registry. + */ + if (!this.ruleTypesConsumersMap.has(ruleTypeId) || !this.ruleTypeRegistry.has(ruleTypeId)) { + continue; + } + + const ruleType = this.ruleTypeRegistry.get(ruleTypeId)!; + const ruleTypeConsumers = this.ruleTypesConsumersMap.get(ruleTypeId) ?? new Set(); + + for (const consumerToAuthorize of ruleTypeConsumers) { + for (const operation of operations) { + requiredPrivileges.set( + this.authorization.actions.alerting.get( + ruleTypeId, + consumerToAuthorize, + authorizationEntity, + operation + ), + { + ruleTypeId: ruleType.id, + consumer: consumerToAuthorize, + operation, } - } + ); } } } const { username, hasAllRequested, privileges } = await checkPrivileges({ - kibana: [...privilegeToRuleType.keys()], + kibana: [...requiredPrivileges.keys()], }); + for (const { authorized, privilege } of privileges.kibana) { + if (authorized && requiredPrivileges.has(privilege)) { + const { ruleTypeId, consumer, operation } = requiredPrivileges.get(privilege)!; + + const authorizedRuleType = authorizedRuleTypes.get(ruleTypeId) ?? { + authorizedConsumers: {}, + }; + + const authorizedConsumers = authorizedRuleType.authorizedConsumers; + const mergedOperations = mergeHasPrivileges( + getPrivilegesFromOperation(operation), + authorizedConsumers[consumer] + ); + + authorizedRuleTypes.set(ruleTypeId, { + authorizedConsumers: { + ...authorizedConsumers, + [consumer]: mergedOperations, + }, + }); + } + } + return { username, hasAllRequested, - authorizedRuleTypes: - hasAllRequested && featuresIds === undefined - ? // has access to all features - this.augmentWithAuthorizedConsumers( - new Set(ruleTypesAuthorized.values()), - allPossibleConsumers - ) - : // only has some of the required privileges - privileges.kibana.reduce((authorizedRuleTypes, { authorized, privilege }) => { - if (authorized && privilegeToRuleType.has(privilege)) { - const [ruleType, feature, hasPrivileges, isAuthorizedAtProducerLevel] = - privilegeToRuleType.get(privilege)!; - if (fIds.has(feature)) { - ruleType.authorizedConsumers[feature] = mergeHasPrivileges( - hasPrivileges, - ruleType.authorizedConsumers[feature] - ); - - if (isAuthorizedAtProducerLevel) { - // granting privileges under the producer automatically authorized the Rules Management UI as well - ruleType.validLegacyConsumers.forEach((legacyConsumer) => { - if (addLegacyConsumerPrivileges(legacyConsumer)) { - ruleType.authorizedConsumers[legacyConsumer] = mergeHasPrivileges( - hasPrivileges, - ruleType.authorizedConsumers[legacyConsumer] - ); - } - }); - } - authorizedRuleTypes.add(ruleType); - } - } - return authorizedRuleTypes; - }, new Set()), + authorizedRuleTypes, }; } else { return { hasAllRequested: true, - authorizedRuleTypes: this.augmentWithAuthorizedConsumers( - new Set([...ruleTypes].filter((ruleType) => fIds.has(ruleType.producer))), - await this.allPossibleConsumers - ), + authorizedRuleTypes: this.getRegisteredRuleTypesWithAllRegisteredConsumers(ruleTypeIds), }; } } - private augmentWithAuthorizedConsumers( - ruleTypes: Set, - authorizedConsumers: AuthorizedConsumers - ): Set { - return new Set( - Array.from(ruleTypes).map((ruleType) => ({ - ...ruleType, - authorizedConsumers: { ...authorizedConsumers }, - })) - ); + private getRegisteredRuleTypesWithAllRegisteredConsumers(ruleTypeIds: Set) { + const authorizedRuleTypes = new Map(); + const authorizedConsumers = getConsumersWithPrivileges(this.allRegisteredConsumers, { + all: true, + read: true, + }); + + Array.from(this.ruleTypesConsumersMap.keys()) + .filter((ruleTypeId) => ruleTypeIds.has(ruleTypeId)) + .forEach((ruleTypeId) => { + authorizedRuleTypes.set(ruleTypeId, { + authorizedConsumers, + }); + }); + + return authorizedRuleTypes; } } @@ -498,7 +478,7 @@ function mergeHasPrivileges(left: HasPrivileges, right?: HasPrivileges): HasPriv }; } -function hasPrivilegeByOperation(operation: ReadOperations | WriteOperations): HasPrivileges { +function getPrivilegesFromOperation(operation: ReadOperations | WriteOperations): HasPrivileges { const read = Object.values(ReadOperations).includes(operation as unknown as ReadOperations); const all = Object.values(WriteOperations).includes(operation as unknown as WriteOperations); return { @@ -507,34 +487,21 @@ function hasPrivilegeByOperation(operation: ReadOperations | WriteOperations): H }; } -function asAuthorizedConsumers( - consumers: string[], +function getConsumersWithPrivileges( + consumers: Set, hasPrivileges: HasPrivileges ): AuthorizedConsumers { - return consumers.reduce((acc, feature) => { + return Array.from(consumers).reduce((acc, feature) => { acc[feature] = hasPrivileges; return acc; }, {}); } function getUnauthorizedMessage( - alertTypeId: string, + ruleTypeId: string, scope: string, operation: string, entity: string ): string { - return `Unauthorized by "${scope}" to ${operation} "${alertTypeId}" ${entity}`; + return `Unauthorized by "${scope}" to ${operation} "${ruleTypeId}" ${entity}`; } - -export const getValidConsumer = ({ - validLegacyConsumers, - legacyConsumer, - producer, -}: { - validLegacyConsumers: string[]; - legacyConsumer: string; - producer: string; -}): string => - legacyConsumer === ALERTING_FEATURE_ID || validLegacyConsumers.includes(legacyConsumer) - ? producer - : legacyConsumer; diff --git a/x-pack/plugins/alerting/server/authorization/alerting_authorization_kuery.test.ts b/x-pack/plugins/alerting/server/authorization/alerting_authorization_kuery.test.ts index b433a95a77734..bcc2b37dca7dd 100644 --- a/x-pack/plugins/alerting/server/authorization/alerting_authorization_kuery.test.ts +++ b/x-pack/plugins/alerting/server/authorization/alerting_authorization_kuery.test.ts @@ -5,364 +5,258 @@ * 2.0. */ -import { RecoveredActionGroup } from '../../common'; import { AlertingAuthorizationFilterType, asFiltersByRuleTypeAndConsumer, ensureFieldIsSafeForQuery, asFiltersBySpaceId, } from './alerting_authorization_kuery'; -import { fromKueryExpression } from '@kbn/es-query'; +import { KueryNode, toKqlExpression } from '@kbn/es-query'; describe('asKqlFiltersByRuleTypeAndConsumer', () => { test('constructs KQL filter for single rule type with single authorized consumer', async () => { + const authorizedRuleTypes = new Map([ + [ + 'myAppAlertType', + { + authorizedConsumers: { + myApp: { read: true, all: true }, + }, + }, + ], + ]); + expect( - asFiltersByRuleTypeAndConsumer( - new Set([ + toKqlExpression( + asFiltersByRuleTypeAndConsumer( + authorizedRuleTypes, { - actionGroups: [], - defaultActionGroupId: 'default', - recoveryActionGroup: RecoveredActionGroup, - id: 'myAppAlertType', - name: 'myAppAlertType', - category: 'test', - producer: 'myApp', - minimumLicenseRequired: 'basic', - isExportable: true, - authorizedConsumers: { - myApp: { read: true, all: true }, + type: AlertingAuthorizationFilterType.KQL, + fieldNames: { + ruleTypeId: 'path.to.rule_type_id', + consumer: 'consumer-field', }, - enabledInLicense: true, - hasAlertsMappings: false, - hasFieldsForAAD: false, - validLegacyConsumers: [], - }, - ]), - { - type: AlertingAuthorizationFilterType.KQL, - fieldNames: { - ruleTypeId: 'path.to.rule_type_id', - consumer: 'consumer-field', }, - }, - 'space1' + 'space1' + ) as KueryNode ) - ).toEqual( - fromKueryExpression(`((path.to.rule_type_id:myAppAlertType and consumer-field:(myApp)))`) - ); + ).toMatchInlineSnapshot(`"(path.to.rule_type_id: myAppAlertType AND consumer-field: myApp)"`); }); test('constructs KQL filter for single rule type with multiple authorized consumers', async () => { + const authorizedRuleTypes = new Map([ + [ + 'myAppAlertType', + { + authorizedConsumers: { + alerts: { read: true, all: true }, + myApp: { read: true, all: true }, + myOtherApp: { read: true, all: true }, + }, + }, + ], + ]); + expect( - asFiltersByRuleTypeAndConsumer( - new Set([ + toKqlExpression( + asFiltersByRuleTypeAndConsumer( + authorizedRuleTypes, { - actionGroups: [], - defaultActionGroupId: 'default', - minimumLicenseRequired: 'basic', - isExportable: true, - recoveryActionGroup: RecoveredActionGroup, - id: 'myAppAlertType', - name: 'myAppAlertType', - category: 'test', - producer: 'myApp', - authorizedConsumers: { - alerts: { read: true, all: true }, - myApp: { read: true, all: true }, - myOtherApp: { read: true, all: true }, + type: AlertingAuthorizationFilterType.KQL, + fieldNames: { + ruleTypeId: 'path.to.rule_type_id', + consumer: 'consumer-field', }, - enabledInLicense: true, - hasAlertsMappings: false, - hasFieldsForAAD: false, - validLegacyConsumers: [], }, - ]), - { - type: AlertingAuthorizationFilterType.KQL, - fieldNames: { - ruleTypeId: 'path.to.rule_type_id', - consumer: 'consumer-field', - }, - }, - 'space1' - ) - ).toEqual( - fromKueryExpression( - `((path.to.rule_type_id:myAppAlertType and consumer-field:(alerts or myApp or myOtherApp)))` + 'space1' + ) as KueryNode ) + ).toMatchInlineSnapshot( + `"(path.to.rule_type_id: myAppAlertType AND (consumer-field: alerts OR consumer-field: myApp OR consumer-field: myOtherApp))"` ); }); test('constructs KQL filter for multiple rule types across authorized consumer', async () => { - expect( - asFiltersByRuleTypeAndConsumer( - new Set([ - { - actionGroups: [], - defaultActionGroupId: 'default', - minimumLicenseRequired: 'basic', - isExportable: true, - recoveryActionGroup: RecoveredActionGroup, - id: 'myAppAlertType', - name: 'myAppAlertType', - category: 'test', - producer: 'myApp', - authorizedConsumers: { - alerts: { read: true, all: true }, - myApp: { read: true, all: true }, - myOtherApp: { read: true, all: true }, - myAppWithSubFeature: { read: true, all: true }, - }, - enabledInLicense: true, - hasAlertsMappings: false, - hasFieldsForAAD: false, - validLegacyConsumers: [], + const authorizedRuleTypes = new Map([ + [ + 'myAppAlertType', + { + authorizedConsumers: { + alerts: { read: true, all: true }, + myApp: { read: true, all: true }, + myOtherApp: { read: true, all: true }, + myAppWithSubFeature: { read: true, all: true }, }, - { - actionGroups: [], - defaultActionGroupId: 'default', - minimumLicenseRequired: 'basic', - isExportable: true, - recoveryActionGroup: RecoveredActionGroup, - id: 'myOtherAppAlertType', - name: 'myOtherAppAlertType', - category: 'test', - producer: 'alerts', - authorizedConsumers: { - alerts: { read: true, all: true }, - myApp: { read: true, all: true }, - myOtherApp: { read: true, all: true }, - myAppWithSubFeature: { read: true, all: true }, - }, - enabledInLicense: true, - hasAlertsMappings: false, - hasFieldsForAAD: false, - validLegacyConsumers: [], + }, + ], + [ + 'myOtherAppAlertType', + { + authorizedConsumers: { + alerts: { read: true, all: true }, + myApp: { read: true, all: true }, + myOtherApp: { read: true, all: true }, + myAppWithSubFeature: { read: true, all: true }, }, + }, + ], + ]); + + expect( + toKqlExpression( + asFiltersByRuleTypeAndConsumer( + authorizedRuleTypes, { - actionGroups: [], - defaultActionGroupId: 'default', - minimumLicenseRequired: 'basic', - isExportable: true, - recoveryActionGroup: RecoveredActionGroup, - id: 'mySecondAppAlertType', - name: 'mySecondAppAlertType', - category: 'test', - producer: 'myApp', - authorizedConsumers: { - alerts: { read: true, all: true }, - myApp: { read: true, all: true }, - myOtherApp: { read: true, all: true }, - myAppWithSubFeature: { read: true, all: true }, + type: AlertingAuthorizationFilterType.KQL, + fieldNames: { + ruleTypeId: 'path.to.rule_type_id', + consumer: 'consumer-field', }, - enabledInLicense: true, - hasAlertsMappings: false, - hasFieldsForAAD: false, - validLegacyConsumers: [], }, - ]), - { - type: AlertingAuthorizationFilterType.KQL, - fieldNames: { - ruleTypeId: 'path.to.rule_type_id', - consumer: 'consumer-field', - }, - }, - 'space1' - ) - ).toEqual( - fromKueryExpression( - `((path.to.rule_type_id:myAppAlertType and consumer-field:(alerts or myApp or myOtherApp or myAppWithSubFeature)) or (path.to.rule_type_id:myOtherAppAlertType and consumer-field:(alerts or myApp or myOtherApp or myAppWithSubFeature)) or (path.to.rule_type_id:mySecondAppAlertType and consumer-field:(alerts or myApp or myOtherApp or myAppWithSubFeature)))` + 'space1' + ) as KueryNode ) + ).toMatchInlineSnapshot( + `"((path.to.rule_type_id: myAppAlertType AND (consumer-field: alerts OR consumer-field: myApp OR consumer-field: myOtherApp OR consumer-field: myAppWithSubFeature)) OR (path.to.rule_type_id: myOtherAppAlertType AND (consumer-field: alerts OR consumer-field: myApp OR consumer-field: myOtherApp OR consumer-field: myAppWithSubFeature)))"` ); }); test('constructs KQL filter with spaceId filter when spaceIds field path exists', async () => { - expect( - asFiltersByRuleTypeAndConsumer( - new Set([ - { - actionGroups: [], - defaultActionGroupId: 'default', - minimumLicenseRequired: 'basic', - isExportable: true, - recoveryActionGroup: RecoveredActionGroup, - id: 'myAppAlertType', - name: 'myAppAlertType', - category: 'test', - producer: 'myApp', - authorizedConsumers: { - alerts: { read: true, all: true }, - myApp: { read: true, all: true }, - myOtherApp: { read: true, all: true }, - myAppWithSubFeature: { read: true, all: true }, - }, - enabledInLicense: true, - hasAlertsMappings: false, - hasFieldsForAAD: false, - validLegacyConsumers: [], - }, - { - actionGroups: [], - defaultActionGroupId: 'default', - minimumLicenseRequired: 'basic', - isExportable: true, - recoveryActionGroup: RecoveredActionGroup, - id: 'myOtherAppAlertType', - name: 'myOtherAppAlertType', - category: 'test', - producer: 'alerts', - authorizedConsumers: { - alerts: { read: true, all: true }, - myApp: { read: true, all: true }, - myOtherApp: { read: true, all: true }, - myAppWithSubFeature: { read: true, all: true }, - }, - enabledInLicense: true, - hasAlertsMappings: false, - hasFieldsForAAD: false, - validLegacyConsumers: [], + const authorizedRuleTypes = new Map([ + [ + 'myAppAlertType', + { + authorizedConsumers: { + alerts: { read: true, all: true }, + myApp: { read: true, all: true }, + myOtherApp: { read: true, all: true }, + myAppWithSubFeature: { read: true, all: true }, }, - ]), + }, + ], + [ + 'myOtherAppAlertType', { - type: AlertingAuthorizationFilterType.KQL, - fieldNames: { - ruleTypeId: 'path.to.rule_type_id', - consumer: 'consumer-field', - spaceIds: 'path.to.spaceIds', + authorizedConsumers: { + alerts: { read: true, all: true }, + myApp: { read: true, all: true }, + myOtherApp: { read: true, all: true }, + myAppWithSubFeature: { read: true, all: true }, }, }, - 'space1' - ) - ).toEqual( - fromKueryExpression( - `((path.to.rule_type_id:myAppAlertType and consumer-field:(alerts or myApp or myOtherApp or myAppWithSubFeature) and path.to.spaceIds:space1) or (path.to.rule_type_id:myOtherAppAlertType and consumer-field:(alerts or myApp or myOtherApp or myAppWithSubFeature) and path.to.spaceIds:space1))` - ) - ); - }); + ], + ]); - test('constructs KQL filter without spaceId filter when spaceIds path is specified, but spaceId is undefined', async () => { expect( - asFiltersByRuleTypeAndConsumer( - new Set([ + toKqlExpression( + asFiltersByRuleTypeAndConsumer( + authorizedRuleTypes, { - actionGroups: [], - defaultActionGroupId: 'default', - minimumLicenseRequired: 'basic', - isExportable: true, - recoveryActionGroup: RecoveredActionGroup, - id: 'myAppAlertType', - name: 'myAppAlertType', - category: 'test', - producer: 'myApp', - authorizedConsumers: { - alerts: { read: true, all: true }, - myApp: { read: true, all: true }, - myOtherApp: { read: true, all: true }, - myAppWithSubFeature: { read: true, all: true }, + type: AlertingAuthorizationFilterType.KQL, + fieldNames: { + ruleTypeId: 'path.to.rule_type_id', + consumer: 'consumer-field', + spaceIds: 'path.to.spaceIds', }, - enabledInLicense: true, - hasAlertsMappings: false, - hasFieldsForAAD: false, - validLegacyConsumers: [], }, - { - actionGroups: [], - defaultActionGroupId: 'default', - minimumLicenseRequired: 'basic', - isExportable: true, - recoveryActionGroup: RecoveredActionGroup, - id: 'myOtherAppAlertType', - name: 'myOtherAppAlertType', - category: 'test', - producer: 'alerts', - authorizedConsumers: { - alerts: { read: true, all: true }, - myApp: { read: true, all: true }, - myOtherApp: { read: true, all: true }, - myAppWithSubFeature: { read: true, all: true }, - }, - enabledInLicense: true, - hasAlertsMappings: false, - hasFieldsForAAD: false, - validLegacyConsumers: [], + 'space1' + ) as KueryNode + ) + ).toMatchInlineSnapshot( + `"((path.to.rule_type_id: myAppAlertType AND (consumer-field: alerts OR consumer-field: myApp OR consumer-field: myOtherApp OR consumer-field: myAppWithSubFeature) AND path.to.spaceIds: space1) OR (path.to.rule_type_id: myOtherAppAlertType AND (consumer-field: alerts OR consumer-field: myApp OR consumer-field: myOtherApp OR consumer-field: myAppWithSubFeature) AND path.to.spaceIds: space1))"` + ); + }); + + test('constructs KQL filter without spaceId filter when spaceIds path is specified, but spaceId is undefined', async () => { + const authorizedRuleTypes = new Map([ + [ + 'myAppAlertType', + { + authorizedConsumers: { + alerts: { read: true, all: true }, + myApp: { read: true, all: true }, + myOtherApp: { read: true, all: true }, + myAppWithSubFeature: { read: true, all: true }, }, - ]), + }, + ], + [ + 'myOtherAppAlertType', { - type: AlertingAuthorizationFilterType.KQL, - fieldNames: { - ruleTypeId: 'path.to.rule_type_id', - consumer: 'consumer-field', - spaceIds: 'path.to.spaceIds', + authorizedConsumers: { + alerts: { read: true, all: true }, + myApp: { read: true, all: true }, + myOtherApp: { read: true, all: true }, + myAppWithSubFeature: { read: true, all: true }, }, }, - undefined - ) - ).toEqual( - fromKueryExpression( - `((path.to.rule_type_id:myAppAlertType and consumer-field:(alerts or myApp or myOtherApp or myAppWithSubFeature)) or (path.to.rule_type_id:myOtherAppAlertType and consumer-field:(alerts or myApp or myOtherApp or myAppWithSubFeature)))` + ], + ]); + + expect( + toKqlExpression( + asFiltersByRuleTypeAndConsumer( + authorizedRuleTypes, + { + type: AlertingAuthorizationFilterType.KQL, + fieldNames: { + ruleTypeId: 'path.to.rule_type_id', + consumer: 'consumer-field', + spaceIds: 'path.to.spaceIds', + }, + }, + undefined + ) as KueryNode ) + ).toMatchInlineSnapshot( + `"((path.to.rule_type_id: myAppAlertType AND (consumer-field: alerts OR consumer-field: myApp OR consumer-field: myOtherApp OR consumer-field: myAppWithSubFeature)) OR (path.to.rule_type_id: myOtherAppAlertType AND (consumer-field: alerts OR consumer-field: myApp OR consumer-field: myOtherApp OR consumer-field: myAppWithSubFeature)))"` ); }); test('constructs KQL filter for single rule type with no authorized consumer', async () => { - const result = asFiltersByRuleTypeAndConsumer( - new Set([ + const authorizedRuleTypes = new Map([ + [ + 'myAppAlertType', { - actionGroups: [], - defaultActionGroupId: 'default', - recoveryActionGroup: RecoveredActionGroup, - id: 'myAppAlertType', - name: 'myAppAlertType', - category: 'test', - producer: 'myApp', - minimumLicenseRequired: 'basic', - isExportable: true, authorizedConsumers: {}, - enabledInLicense: true, - hasAlertsMappings: false, - hasFieldsForAAD: false, - validLegacyConsumers: [], }, - ]), - { - type: AlertingAuthorizationFilterType.KQL, - fieldNames: { - ruleTypeId: 'path.to.rule_type_id', - consumer: 'consumer-field', + ], + ]); + + const result = toKqlExpression( + asFiltersByRuleTypeAndConsumer( + authorizedRuleTypes, + { + type: AlertingAuthorizationFilterType.KQL, + fieldNames: { + ruleTypeId: 'path.to.rule_type_id', + consumer: 'consumer-field', + }, }, - }, - 'space1' + 'space1' + ) as KueryNode ); - expect(result).toEqual(fromKueryExpression(`path.to.rule_type_id:myAppAlertType`)); + expect(result).toMatchInlineSnapshot(`"path.to.rule_type_id: myAppAlertType"`); }); }); describe('asEsDslFiltersByRuleTypeAndConsumer', () => { test('constructs ES DSL filter for single rule type with single authorized consumer', async () => { + const authorizedRuleTypes = new Map([ + [ + 'myAppAlertType', + { + authorizedConsumers: { + myApp: { read: true, all: true }, + }, + }, + ], + ]); + expect( asFiltersByRuleTypeAndConsumer( - new Set([ - { - actionGroups: [], - defaultActionGroupId: 'default', - recoveryActionGroup: RecoveredActionGroup, - id: 'myAppAlertType', - name: 'myAppAlertType', - category: 'test', - producer: 'myApp', - minimumLicenseRequired: 'basic', - isExportable: true, - authorizedConsumers: { - myApp: { read: true, all: true }, - }, - enabledInLicense: true, - hasAlertsMappings: false, - hasFieldsForAAD: false, - validLegacyConsumers: [], - }, - ]), + authorizedRuleTypes, { type: AlertingAuthorizationFilterType.ESDSL, fieldNames: { @@ -405,30 +299,22 @@ describe('asEsDslFiltersByRuleTypeAndConsumer', () => { }); test('constructs ES DSL filter for single rule type with multiple authorized consumers', async () => { + const authorizedRuleTypes = new Map([ + [ + 'myAppAlertType', + { + authorizedConsumers: { + alerts: { read: true, all: true }, + myApp: { read: true, all: true }, + myOtherApp: { read: true, all: true }, + }, + }, + ], + ]); + expect( asFiltersByRuleTypeAndConsumer( - new Set([ - { - actionGroups: [], - defaultActionGroupId: 'default', - minimumLicenseRequired: 'basic', - isExportable: true, - recoveryActionGroup: RecoveredActionGroup, - id: 'myAppAlertType', - name: 'myAppAlertType', - category: 'test', - producer: 'myApp', - authorizedConsumers: { - alerts: { read: true, all: true }, - myApp: { read: true, all: true }, - myOtherApp: { read: true, all: true }, - }, - enabledInLicense: true, - hasAlertsMappings: false, - hasFieldsForAAD: false, - validLegacyConsumers: [], - }, - ]), + authorizedRuleTypes, { type: AlertingAuthorizationFilterType.ESDSL, fieldNames: { @@ -478,73 +364,34 @@ describe('asEsDslFiltersByRuleTypeAndConsumer', () => { }); test('constructs ES DSL filter for multiple rule types across authorized consumer', async () => { - expect( - asFiltersByRuleTypeAndConsumer( - new Set([ - { - actionGroups: [], - defaultActionGroupId: 'default', - minimumLicenseRequired: 'basic', - isExportable: true, - recoveryActionGroup: RecoveredActionGroup, - id: 'myAppAlertType', - name: 'myAppAlertType', - category: 'test', - producer: 'myApp', - authorizedConsumers: { - alerts: { read: true, all: true }, - myApp: { read: true, all: true }, - myOtherApp: { read: true, all: true }, - myAppWithSubFeature: { read: true, all: true }, - }, - enabledInLicense: true, - hasAlertsMappings: false, - hasFieldsForAAD: false, - validLegacyConsumers: [], - }, - { - actionGroups: [], - defaultActionGroupId: 'default', - minimumLicenseRequired: 'basic', - isExportable: true, - recoveryActionGroup: RecoveredActionGroup, - id: 'myOtherAppAlertType', - name: 'myOtherAppAlertType', - category: 'test', - producer: 'alerts', - authorizedConsumers: { - alerts: { read: true, all: true }, - myApp: { read: true, all: true }, - myOtherApp: { read: true, all: true }, - myAppWithSubFeature: { read: true, all: true }, - }, - enabledInLicense: true, - hasAlertsMappings: false, - hasFieldsForAAD: false, - validLegacyConsumers: [], + const authorizedRuleTypes = new Map([ + [ + 'myAppAlertType', + { + authorizedConsumers: { + alerts: { read: true, all: true }, + myApp: { read: true, all: true }, + myOtherApp: { read: true, all: true }, + myAppWithSubFeature: { read: true, all: true }, }, - { - actionGroups: [], - defaultActionGroupId: 'default', - minimumLicenseRequired: 'basic', - isExportable: true, - recoveryActionGroup: RecoveredActionGroup, - id: 'mySecondAppAlertType', - name: 'mySecondAppAlertType', - category: 'test', - producer: 'myApp', - authorizedConsumers: { - alerts: { read: true, all: true }, - myApp: { read: true, all: true }, - myOtherApp: { read: true, all: true }, - myAppWithSubFeature: { read: true, all: true }, - }, - enabledInLicense: true, - hasAlertsMappings: false, - hasFieldsForAAD: false, - validLegacyConsumers: [], + }, + ], + [ + 'myOtherAppAlertType', + { + authorizedConsumers: { + alerts: { read: true, all: true }, + myApp: { read: true, all: true }, + myOtherApp: { read: true, all: true }, + myAppWithSubFeature: { read: true, all: true }, }, - ]), + }, + ], + ]); + + expect( + asFiltersByRuleTypeAndConsumer( + authorizedRuleTypes, { type: AlertingAuthorizationFilterType.ESDSL, fieldNames: { @@ -554,164 +401,175 @@ describe('asEsDslFiltersByRuleTypeAndConsumer', () => { }, 'space1' ) - ).toEqual({ - bool: { - should: [ - { - bool: { - filter: [ - { - bool: { - should: [{ match: { 'path.to.rule_type_id': 'myAppAlertType' } }], - minimum_should_match: 1, - }, - }, - { - bool: { - should: [ - { - bool: { - should: [{ match: { 'consumer-field': 'alerts' } }], - minimum_should_match: 1, - }, - }, - { - bool: { - should: [{ match: { 'consumer-field': 'myApp' } }], - minimum_should_match: 1, - }, - }, - { - bool: { - should: [{ match: { 'consumer-field': 'myOtherApp' } }], - minimum_should_match: 1, - }, - }, - { - bool: { - should: [{ match: { 'consumer-field': 'myAppWithSubFeature' } }], - minimum_should_match: 1, + ).toMatchInlineSnapshot(` + Object { + "bool": Object { + "minimum_should_match": 1, + "should": Array [ + Object { + "bool": Object { + "filter": Array [ + Object { + "bool": Object { + "minimum_should_match": 1, + "should": Array [ + Object { + "match": Object { + "path.to.rule_type_id": "myAppAlertType", + }, }, - }, - ], - minimum_should_match: 1, - }, - }, - ], - }, - }, - { - bool: { - filter: [ - { - bool: { - should: [{ match: { 'path.to.rule_type_id': 'myOtherAppAlertType' } }], - minimum_should_match: 1, + ], + }, }, - }, - { - bool: { - should: [ - { - bool: { - should: [{ match: { 'consumer-field': 'alerts' } }], - minimum_should_match: 1, + Object { + "bool": Object { + "minimum_should_match": 1, + "should": Array [ + Object { + "bool": Object { + "minimum_should_match": 1, + "should": Array [ + Object { + "match": Object { + "consumer-field": "alerts", + }, + }, + ], + }, }, - }, - { - bool: { - should: [{ match: { 'consumer-field': 'myApp' } }], - minimum_should_match: 1, + Object { + "bool": Object { + "minimum_should_match": 1, + "should": Array [ + Object { + "match": Object { + "consumer-field": "myApp", + }, + }, + ], + }, }, - }, - { - bool: { - should: [{ match: { 'consumer-field': 'myOtherApp' } }], - minimum_should_match: 1, + Object { + "bool": Object { + "minimum_should_match": 1, + "should": Array [ + Object { + "match": Object { + "consumer-field": "myOtherApp", + }, + }, + ], + }, }, - }, - { - bool: { - should: [{ match: { 'consumer-field': 'myAppWithSubFeature' } }], - minimum_should_match: 1, + Object { + "bool": Object { + "minimum_should_match": 1, + "should": Array [ + Object { + "match": Object { + "consumer-field": "myAppWithSubFeature", + }, + }, + ], + }, }, - }, - ], - minimum_should_match: 1, + ], + }, }, - }, - ], + ], + }, }, - }, - { - bool: { - filter: [ - { - bool: { - should: [{ match: { 'path.to.rule_type_id': 'mySecondAppAlertType' } }], - minimum_should_match: 1, + Object { + "bool": Object { + "filter": Array [ + Object { + "bool": Object { + "minimum_should_match": 1, + "should": Array [ + Object { + "match": Object { + "path.to.rule_type_id": "myOtherAppAlertType", + }, + }, + ], + }, }, - }, - { - bool: { - should: [ - { - bool: { - should: [{ match: { 'consumer-field': 'alerts' } }], - minimum_should_match: 1, + Object { + "bool": Object { + "minimum_should_match": 1, + "should": Array [ + Object { + "bool": Object { + "minimum_should_match": 1, + "should": Array [ + Object { + "match": Object { + "consumer-field": "alerts", + }, + }, + ], + }, }, - }, - { - bool: { - should: [{ match: { 'consumer-field': 'myApp' } }], - minimum_should_match: 1, + Object { + "bool": Object { + "minimum_should_match": 1, + "should": Array [ + Object { + "match": Object { + "consumer-field": "myApp", + }, + }, + ], + }, }, - }, - { - bool: { - should: [{ match: { 'consumer-field': 'myOtherApp' } }], - minimum_should_match: 1, + Object { + "bool": Object { + "minimum_should_match": 1, + "should": Array [ + Object { + "match": Object { + "consumer-field": "myOtherApp", + }, + }, + ], + }, }, - }, - { - bool: { - should: [{ match: { 'consumer-field': 'myAppWithSubFeature' } }], - minimum_should_match: 1, + Object { + "bool": Object { + "minimum_should_match": 1, + "should": Array [ + Object { + "match": Object { + "consumer-field": "myAppWithSubFeature", + }, + }, + ], + }, }, - }, - ], - minimum_should_match: 1, + ], + }, }, - }, - ], + ], + }, }, - }, - ], - minimum_should_match: 1, - }, - }); + ], + }, + } + `); }); test('constructs KQL filter for single rule type with no authorized consumer', async () => { - const result = asFiltersByRuleTypeAndConsumer( - new Set([ + const authorizedRuleTypes = new Map([ + [ + 'myAppAlertType', { - actionGroups: [], - defaultActionGroupId: 'default', - recoveryActionGroup: RecoveredActionGroup, - id: 'myAppAlertType', - name: 'myAppAlertType', - category: 'test', - producer: 'myApp', - minimumLicenseRequired: 'basic', - isExportable: true, authorizedConsumers: {}, - enabledInLicense: true, - hasAlertsMappings: false, - hasFieldsForAAD: false, - validLegacyConsumers: [], }, - ]), + ], + ]); + + const result = asFiltersByRuleTypeAndConsumer( + authorizedRuleTypes, { type: AlertingAuthorizationFilterType.ESDSL, fieldNames: { @@ -760,18 +618,20 @@ describe('asFiltersBySpaceId', () => { test('returns KQL filter of spaceId', () => { expect( - asFiltersBySpaceId( - { - type: AlertingAuthorizationFilterType.KQL, - fieldNames: { - ruleTypeId: 'path.to.rule_type_id', - consumer: 'consumer-field', - spaceIds: 'path.to.space.id', + toKqlExpression( + asFiltersBySpaceId( + { + type: AlertingAuthorizationFilterType.KQL, + fieldNames: { + ruleTypeId: 'path.to.rule_type_id', + consumer: 'consumer-field', + spaceIds: 'path.to.space.id', + }, }, - }, - 'space1' + 'space1' + ) as KueryNode ) - ).toEqual(fromKueryExpression('(path.to.space.id: space1)')); + ).toMatchInlineSnapshot(`"path.to.space.id: space1"`); }); test('returns undefined if no path to spaceIds is provided', () => { diff --git a/x-pack/plugins/alerting/server/authorization/alerting_authorization_kuery.ts b/x-pack/plugins/alerting/server/authorization/alerting_authorization_kuery.ts index 01e30dfb38327..666059c7a7b47 100644 --- a/x-pack/plugins/alerting/server/authorization/alerting_authorization_kuery.ts +++ b/x-pack/plugins/alerting/server/authorization/alerting_authorization_kuery.ts @@ -9,7 +9,7 @@ import { remove } from 'lodash'; import { EsQueryConfig, nodeBuilder, toElasticsearchQuery, KueryNode } from '@kbn/es-query'; import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; -import { RegistryAlertTypeWithAuth } from './alerting_authorization'; +import { AuthorizedRuleTypes } from './alerting_authorization'; export enum AlertingAuthorizationFilterType { KQL = 'kql', @@ -35,36 +35,39 @@ const esQueryConfig: EsQueryConfig = { }; export function asFiltersByRuleTypeAndConsumer( - ruleTypes: Set, + ruleTypes: AuthorizedRuleTypes, opts: AlertingAuthorizationFilterOpts, spaceId: string | undefined ): KueryNode | estypes.QueryDslQueryContainer { const kueryNode = nodeBuilder.or( - Array.from(ruleTypes).reduce((filters, { id, authorizedConsumers }) => { - ensureFieldIsSafeForQuery('ruleTypeId', id); - - const andNodes: KueryNode[] = [nodeBuilder.is(opts.fieldNames.ruleTypeId, id)]; - - const authorizedConsumersKeys = Object.keys(authorizedConsumers); - if (authorizedConsumersKeys.length) { - andNodes.push( - nodeBuilder.or( - authorizedConsumersKeys.map((consumer) => { - ensureFieldIsSafeForQuery('consumer', consumer); - return nodeBuilder.is(opts.fieldNames.consumer, consumer); - }) - ) - ); - } - - if (opts.fieldNames.spaceIds != null && spaceId != null) { - andNodes.push(nodeBuilder.is(opts.fieldNames.spaceIds, spaceId)); - } - - filters.push(nodeBuilder.and(andNodes)); - - return filters; - }, []) + Array.from(ruleTypes.entries()).reduce( + (filters, [id, { authorizedConsumers }]) => { + ensureFieldIsSafeForQuery('ruleTypeId', id); + + const andNodes: KueryNode[] = [nodeBuilder.is(opts.fieldNames.ruleTypeId, id)]; + + const authorizedConsumersKeys = Object.keys(authorizedConsumers); + if (authorizedConsumersKeys.length) { + andNodes.push( + nodeBuilder.or( + authorizedConsumersKeys.map((consumer) => { + ensureFieldIsSafeForQuery('consumer', consumer); + return nodeBuilder.is(opts.fieldNames.consumer, consumer); + }) + ) + ); + } + + if (opts.fieldNames.spaceIds != null && spaceId != null) { + andNodes.push(nodeBuilder.is(opts.fieldNames.spaceIds, spaceId)); + } + + filters.push(nodeBuilder.and(andNodes)); + + return filters; + }, + [] + ) ); if (opts.type === AlertingAuthorizationFilterType.ESDSL) { diff --git a/x-pack/plugins/alerting/server/authorization/index.ts b/x-pack/plugins/alerting/server/authorization/index.ts index 17f0f9f22bbe1..e31dac301cbcb 100644 --- a/x-pack/plugins/alerting/server/authorization/index.ts +++ b/x-pack/plugins/alerting/server/authorization/index.ts @@ -7,3 +7,4 @@ export * from './alerting_authorization'; export * from './alerting_authorization_kuery'; +export * from './types'; diff --git a/x-pack/plugins/alerting/server/authorization/types.ts b/x-pack/plugins/alerting/server/authorization/types.ts new file mode 100644 index 0000000000000..77357456c74b6 --- /dev/null +++ b/x-pack/plugins/alerting/server/authorization/types.ts @@ -0,0 +1,46 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor 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 enum AlertingAuthorizationEntity { + Rule = 'rule', + Alert = 'alert', +} + +export enum ReadOperations { + Get = 'get', + GetRuleState = 'getRuleState', + GetAlertSummary = 'getAlertSummary', + GetExecutionLog = 'getExecutionLog', + GetActionErrorLog = 'getActionErrorLog', + Find = 'find', + GetAuthorizedAlertsIndices = 'getAuthorizedAlertsIndices', + GetRuleExecutionKPI = 'getRuleExecutionKPI', + GetBackfill = 'getBackfill', + FindBackfill = 'findBackfill', +} + +export enum WriteOperations { + Create = 'create', + Delete = 'delete', + Update = 'update', + UpdateApiKey = 'updateApiKey', + Enable = 'enable', + Disable = 'disable', + MuteAll = 'muteAll', + UnmuteAll = 'unmuteAll', + MuteAlert = 'muteAlert', + UnmuteAlert = 'unmuteAlert', + Snooze = 'snooze', + BulkEdit = 'bulkEdit', + BulkDelete = 'bulkDelete', + BulkEnable = 'bulkEnable', + BulkDisable = 'bulkDisable', + Unsnooze = 'unsnooze', + RunSoon = 'runSoon', + ScheduleBackfill = 'scheduleBackfill', + DeleteBackfill = 'deleteBackfill', +} diff --git a/x-pack/plugins/alerting/server/config.test.ts b/x-pack/plugins/alerting/server/config.test.ts index 4b84905a12a6e..0cb75cb6162ce 100644 --- a/x-pack/plugins/alerting/server/config.test.ts +++ b/x-pack/plugins/alerting/server/config.test.ts @@ -21,7 +21,6 @@ describe('config validation', () => { "interval": "5m", "removalDelay": "1h", }, - "maxEphemeralActionsPerAlert": 10, "rules": Object { "maxScheduledPerMinute": 32000, "minimumScheduleInterval": Object { diff --git a/x-pack/plugins/alerting/server/config.ts b/x-pack/plugins/alerting/server/config.ts index be7790cd81888..776576cce2993 100644 --- a/x-pack/plugins/alerting/server/config.ts +++ b/x-pack/plugins/alerting/server/config.ts @@ -60,7 +60,6 @@ const rulesSchema = schema.object({ }), }); -export const DEFAULT_MAX_EPHEMERAL_ACTIONS_PER_ALERT = 10; export const configSchema = schema.object({ healthCheck: schema.object({ interval: schema.string({ validate: validateDurationSchema, defaultValue: '60m' }), @@ -69,9 +68,7 @@ export const configSchema = schema.object({ interval: schema.string({ validate: validateDurationSchema, defaultValue: '5m' }), removalDelay: schema.string({ validate: validateDurationSchema, defaultValue: '1h' }), }), - maxEphemeralActionsPerAlert: schema.number({ - defaultValue: DEFAULT_MAX_EPHEMERAL_ACTIONS_PER_ALERT, - }), + maxEphemeralActionsPerAlert: schema.maybe(schema.number()), enableFrameworkAlerts: schema.boolean({ defaultValue: true }), cancelAlertsOnRuleTimeout: schema.boolean({ defaultValue: true }), rules: rulesSchema, diff --git a/x-pack/plugins/alerting/server/index.ts b/x-pack/plugins/alerting/server/index.ts index 2cb2c212a91ba..fc00d37e6ebc3 100644 --- a/x-pack/plugins/alerting/server/index.ts +++ b/x-pack/plugins/alerting/server/index.ts @@ -36,8 +36,7 @@ export type { export { DEFAULT_AAD_CONFIG } from './types'; export { RULE_SAVED_OBJECT_TYPE, API_KEY_PENDING_INVALIDATION_TYPE } from './saved_objects'; export { RuleNotifyWhen } from '../common'; -export { DEFAULT_MAX_EPHEMERAL_ACTIONS_PER_ALERT } from './config'; -export type { PluginSetupContract, PluginStartContract } from './plugin'; +export type { AlertingServerSetup, AlertingServerStart } from './plugin'; export type { FindResult, BulkEditOperation, BulkOperationError } from './rules_client'; export type { Rule } from './application/rule/types'; export type { PublicAlert as Alert } from './alert'; @@ -45,12 +44,13 @@ export { parseDuration, isRuleSnoozed } from './lib'; export { getEsErrorMessage } from './lib/errors'; export type { AlertingRulesConfig } from './config'; export { - ReadOperations, AlertingAuthorizationFilterType, AlertingAuthorization, + ReadOperations, WriteOperations, AlertingAuthorizationEntity, } from './authorization'; + export { DEFAULT_ALERTS_ILM_POLICY, DEFAULT_ALERTS_ILM_POLICY_NAME, @@ -84,9 +84,9 @@ export const config: PluginConfigDescriptor = { rules: { run: { alerts: { max: true } } }, }, deprecations: ({ renameFromRoot, deprecate }) => [ - deprecate('maxEphemeralActionsPerAlert', 'a future version', { + deprecate('maxEphemeralActionsPerAlert', '9.0.0', { level: 'warning', - message: `Configuring "xpack.alerting.maxEphemeralActionsPerAlert" is deprecated and will be removed in a future version. Remove this setting to increase action execution resiliency.`, + message: `The setting "xpack.alerting.maxEphemeralActionsPerAlert" is deprecated and currently ignored by the system. Please remove this setting.`, }), ], }; diff --git a/x-pack/plugins/alerting/server/mocks.ts b/x-pack/plugins/alerting/server/mocks.ts index 33cbccbaf8c0c..d885cf0721b4e 100644 --- a/x-pack/plugins/alerting/server/mocks.ts +++ b/x-pack/plugins/alerting/server/mocks.ts @@ -14,7 +14,7 @@ import { dataViewPluginMocks } from '@kbn/data-views-plugin/public/mocks'; import { searchSourceCommonMock } from '@kbn/data-plugin/common/search/search_source/mocks'; import { SharePluginStart } from '@kbn/share-plugin/server'; import { rulesClientMock } from './rules_client.mock'; -import { PluginSetupContract, PluginStartContract } from './plugin'; +import { AlertingServerSetup, AlertingServerStart } from './plugin'; import { Alert, AlertFactoryDoneUtils } from './alert'; import { AlertInstanceContext, @@ -27,7 +27,7 @@ import { publicAlertsClientMock } from './alerts_client/alerts_client.mock'; export { rulesClientMock }; const createSetupMock = () => { - const mock: jest.Mocked = { + const mock: jest.Mocked = { registerType: jest.fn(), getSecurityHealth: jest.fn(), getConfig: jest.fn(), @@ -57,7 +57,7 @@ const createShareStartMock = () => { }; const createStartMock = () => { - const mock: jest.Mocked = { + const mock: jest.Mocked = { listTypes: jest.fn(), getType: jest.fn(), getAllTypes: jest.fn(), diff --git a/x-pack/plugins/alerting/server/plugin.test.ts b/x-pack/plugins/alerting/server/plugin.test.ts index 37175ac960412..2938daf8b1ec3 100644 --- a/x-pack/plugins/alerting/server/plugin.test.ts +++ b/x-pack/plugins/alerting/server/plugin.test.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { AlertingPlugin, PluginSetupContract } from './plugin'; +import { AlertingPlugin, AlertingServerSetup } from './plugin'; import { createUsageCollectionSetupMock } from '@kbn/usage-collection-plugin/server/mocks'; import { coreMock, statusServiceMock } from '@kbn/core/server/mocks'; import { licensingMock } from '@kbn/licensing-plugin/server/mocks'; @@ -170,7 +170,7 @@ describe('Alerting Plugin', () => { }); describe('registerType()', () => { - let setup: PluginSetupContract; + let setup: AlertingServerSetup; beforeEach(async () => { const context = coreMock.createPluginInitializerContext( generateAlertingConfig() @@ -209,7 +209,8 @@ describe('Alerting Plugin', () => { ...sampleRuleType, minimumLicenseRequired: 'basic', } as RuleType; - await setup.registerType(ruleType); + + setup.registerType(ruleType); expect(ruleType.ruleTaskTimeout).toBe('5m'); }); @@ -219,7 +220,7 @@ describe('Alerting Plugin', () => { minimumLicenseRequired: 'basic', ruleTaskTimeout: '20h', } as RuleType; - await setup.registerType(ruleType); + setup.registerType(ruleType); expect(ruleType.ruleTaskTimeout).toBe('20h'); }); @@ -228,7 +229,7 @@ describe('Alerting Plugin', () => { ...sampleRuleType, minimumLicenseRequired: 'basic', } as RuleType; - await setup.registerType(ruleType); + setup.registerType(ruleType); expect(ruleType.cancelAlertsOnRuleTimeout).toBe(true); }); @@ -238,13 +239,13 @@ describe('Alerting Plugin', () => { minimumLicenseRequired: 'basic', cancelAlertsOnRuleTimeout: false, } as RuleType; - await setup.registerType(ruleType); + setup.registerType(ruleType); expect(ruleType.cancelAlertsOnRuleTimeout).toBe(false); }); }); describe('registerConnectorAdapter()', () => { - let setup: PluginSetupContract; + let setup: AlertingServerSetup; beforeEach(async () => { const context = coreMock.createPluginInitializerContext( @@ -314,9 +315,9 @@ describe('Alerting Plugin', () => { }); expect(encryptedSavedObjectsSetup.canEncrypt).toEqual(false); - expect(() => + await expect(() => startContract.getRulesClientWithRequest({} as KibanaRequest) - ).toThrowErrorMatchingInlineSnapshot( + ).rejects.toThrowErrorMatchingInlineSnapshot( `"Unable to create alerts client because the Encrypted Saved Objects plugin is missing encryption key. Please set xpack.encryptedSavedObjects.encryptionKey in the kibana.yml or use the bin/kibana-encryption-keys command."` ); }); @@ -380,7 +381,8 @@ describe('Alerting Plugin', () => { }, getSavedObjectsClient: jest.fn(), } as unknown as KibanaRequest; - startContract.getRulesClientWithRequest(fakeRequest); + + await startContract.getRulesClientWithRequest(fakeRequest); }); }); @@ -443,7 +445,8 @@ describe('Alerting Plugin', () => { }, getSavedObjectsClient: jest.fn(), } as unknown as KibanaRequest; - startContract.getAlertingAuthorizationWithRequest(fakeRequest); + + await startContract.getAlertingAuthorizationWithRequest(fakeRequest); }); }); }); diff --git a/x-pack/plugins/alerting/server/plugin.ts b/x-pack/plugins/alerting/server/plugin.ts index 9a12b13eb164c..9d1a15305f7e3 100644 --- a/x-pack/plugins/alerting/server/plugin.ts +++ b/x-pack/plugins/alerting/server/plugin.ts @@ -133,7 +133,7 @@ export const LEGACY_EVENT_LOG_ACTIONS = { resolvedInstance: 'resolved-instance', }; -export interface PluginSetupContract { +export interface AlertingServerSetup { registerConnectorAdapter< RuleActionParams extends ConnectorAdapterParams = ConnectorAdapterParams, ConnectorParams extends ConnectorAdapterParams = ConnectorAdapterParams @@ -168,19 +168,15 @@ export interface PluginSetupContract { getDataStreamAdapter: () => DataStreamAdapter; } -export interface PluginStartContract { +export interface AlertingServerStart { listTypes: RuleTypeRegistry['list']; - getAllTypes: RuleTypeRegistry['getAllTypes']; getType: RuleTypeRegistry['get']; getAlertIndicesAlias: GetAlertIndicesAlias; - - getRulesClientWithRequest(request: KibanaRequest): RulesClientApi; - + getRulesClientWithRequest(request: KibanaRequest): Promise; getAlertingAuthorizationWithRequest( request: KibanaRequest - ): PublicMethodsOf; - + ): Promise>; getFrameworkHealth: () => Promise; } @@ -260,7 +256,7 @@ export class AlertingPlugin { public setup( core: CoreSetup, plugins: AlertingPluginsSetup - ): PluginSetupContract { + ): AlertingServerSetup { this.kibanaBaseUrl = core.http.basePath.publicBaseUrl; this.licenseState = new LicenseState(plugins.licensing.license$); this.security = plugins.security; @@ -491,7 +487,7 @@ export class AlertingPlugin { }; } - public start(core: CoreStart, plugins: AlertingPluginsStart): PluginStartContract { + public start(core: CoreStart, plugins: AlertingPluginsStart): AlertingServerStart { const { isESOCanEncrypt, logger, @@ -518,7 +514,6 @@ export class AlertingPlugin { alertingAuthorizationClientFactory.initialize({ ruleTypeRegistry: ruleTypeRegistry!, - securityPluginSetup: security, securityPluginStart: plugins.security, async getSpace(request: KibanaRequest) { return plugins.spaces?.spacesService.getActiveSpace(request); @@ -572,7 +567,7 @@ export class AlertingPlugin { uiSettings: core.uiSettings, }); - const getRulesClientWithRequest = (request: KibanaRequest) => { + const getRulesClientWithRequest = async (request: KibanaRequest) => { if (isESOCanEncrypt !== true) { throw new Error( `Unable to create alerts client because the Encrypted Saved Objects plugin is missing encryption key. Please set xpack.encryptedSavedObjects.encryptionKey in the kibana.yml or use the bin/kibana-encryption-keys command.` @@ -581,7 +576,7 @@ export class AlertingPlugin { return rulesClientFactory!.create(request, core.savedObjects); }; - const getAlertingAuthorizationWithRequest = (request: KibanaRequest) => { + const getAlertingAuthorizationWithRequest = async (request: KibanaRequest) => { return alertingAuthorizationClientFactory!.create(request); }; @@ -615,7 +610,6 @@ export class AlertingPlugin { logger, }), maxAlerts: this.config.rules.run.alerts.max, - maxEphemeralActionsPerRule: this.config.maxEphemeralActionsPerAlert, ruleTypeRegistry: this.ruleTypeRegistry!, rulesSettingsService: new RulesSettingsService({ cacheInterval: this.config.rulesSettings.cacheInterval, @@ -626,18 +620,19 @@ export class AlertingPlugin { savedObjects: core.savedObjects, share: plugins.share, spaceIdToNamespace, - supportsEphemeralTasks: plugins.taskManager.supportsEphemeralTasks(), uiSettings: core.uiSettings, usageCounter: this.usageCounter, isServerless: this.isServerless, }); this.eventLogService!.registerSavedObjectProvider(RULE_SAVED_OBJECT_TYPE, (request) => { - const client = getRulesClientWithRequest(request); - return (objects?: SavedObjectsBulkGetObject[]) => - objects + return async (objects?: SavedObjectsBulkGetObject[]) => { + const client = await getRulesClientWithRequest(request); + + return objects ? Promise.all(objects.map(async (objectItem) => await client.get({ id: objectItem.id }))) : Promise.resolve([]); + }; }); this.eventLogService!.isEsContextReady() diff --git a/x-pack/plugins/alerting/server/routes/_mock_handler_arguments.ts b/x-pack/plugins/alerting/server/routes/_mock_handler_arguments.ts index b2f25d349ec7f..a24ea147d4113 100644 --- a/x-pack/plugins/alerting/server/routes/_mock_handler_arguments.ts +++ b/x-pack/plugins/alerting/server/routes/_mock_handler_arguments.ts @@ -59,7 +59,7 @@ export function mockHandlerArguments( alerting: { listTypes, getRulesClient() { - return rulesClient || rulesClientMock.create(); + return Promise.resolve(rulesClient || rulesClientMock.create()); }, getRulesSettingsClient() { return rulesSettingsClient || rulesSettingsClientMock.create(); diff --git a/x-pack/plugins/alerting/server/routes/backfill/apis/delete/delete_backfill_route.ts b/x-pack/plugins/alerting/server/routes/backfill/apis/delete/delete_backfill_route.ts index 6c343ac125188..66d90671ac1bd 100644 --- a/x-pack/plugins/alerting/server/routes/backfill/apis/delete/delete_backfill_route.ts +++ b/x-pack/plugins/alerting/server/routes/backfill/apis/delete/delete_backfill_route.ts @@ -29,7 +29,8 @@ export const deleteBackfillRoute = ( }, router.handleLegacyErrors( verifyAccessAndContext(licenseState, async function (context, req, res) { - const rulesClient = (await context.alerting).getRulesClient(); + const alertingContext = await context.alerting; + const rulesClient = await alertingContext.getRulesClient(); const params: DeleteBackfillRequestParamsV1 = req.params; await rulesClient.deleteBackfill(params.id); diff --git a/x-pack/plugins/alerting/server/routes/backfill/apis/find/find_backfill_route.ts b/x-pack/plugins/alerting/server/routes/backfill/apis/find/find_backfill_route.ts index fea2925c0983b..be1ff25ef5932 100644 --- a/x-pack/plugins/alerting/server/routes/backfill/apis/find/find_backfill_route.ts +++ b/x-pack/plugins/alerting/server/routes/backfill/apis/find/find_backfill_route.ts @@ -34,7 +34,8 @@ export const findBackfillRoute = ( }, router.handleLegacyErrors( verifyAccessAndContext(licenseState, async function (context, req, res) { - const rulesClient = (await context.alerting).getRulesClient(); + const alertingContext = await context.alerting; + const rulesClient = await alertingContext.getRulesClient(); const query: FindBackfillRequestQueryV1 = req.query; const result = await rulesClient.findBackfill(transformRequestV1(query)); diff --git a/x-pack/plugins/alerting/server/routes/backfill/apis/get/get_backfill_route.ts b/x-pack/plugins/alerting/server/routes/backfill/apis/get/get_backfill_route.ts index bfb178d875c8b..5758bb6ba805f 100644 --- a/x-pack/plugins/alerting/server/routes/backfill/apis/get/get_backfill_route.ts +++ b/x-pack/plugins/alerting/server/routes/backfill/apis/get/get_backfill_route.ts @@ -31,7 +31,8 @@ export const getBackfillRoute = ( }, router.handleLegacyErrors( verifyAccessAndContext(licenseState, async function (context, req, res) { - const rulesClient = (await context.alerting).getRulesClient(); + const alertingContext = await context.alerting; + const rulesClient = await alertingContext.getRulesClient(); const params: GetBackfillRequestParamsV1 = req.params; const result = await rulesClient.getBackfill(params.id); diff --git a/x-pack/plugins/alerting/server/routes/backfill/apis/schedule/schedule_backfill_route.ts b/x-pack/plugins/alerting/server/routes/backfill/apis/schedule/schedule_backfill_route.ts index 466c69b2b6aa5..77eb5c9355cfb 100644 --- a/x-pack/plugins/alerting/server/routes/backfill/apis/schedule/schedule_backfill_route.ts +++ b/x-pack/plugins/alerting/server/routes/backfill/apis/schedule/schedule_backfill_route.ts @@ -29,7 +29,8 @@ export const scheduleBackfillRoute = ( }, router.handleLegacyErrors( verifyAccessAndContext(licenseState, async function (context, req, res) { - const rulesClient = (await context.alerting).getRulesClient(); + const alertingContext = await context.alerting; + const rulesClient = await alertingContext.getRulesClient(); const body: ScheduleBackfillRequestBodyV1 = req.body; const result = await rulesClient.scheduleBackfill(transformRequestV1(body)); diff --git a/x-pack/plugins/alerting/server/routes/framework/apis/health/health.test.ts b/x-pack/plugins/alerting/server/routes/framework/apis/health/health.test.ts index f726073ed0844..83773ab8531b7 100644 --- a/x-pack/plugins/alerting/server/routes/framework/apis/health/health.test.ts +++ b/x-pack/plugins/alerting/server/routes/framework/apis/health/health.test.ts @@ -25,7 +25,7 @@ jest.mock('../../../../lib/license_api_access', () => ({ const alerting = alertsMock.createStart(); const currentDate = new Date().toISOString(); -const ruleTypes = [ +const ruleTypes: RegistryAlertTypeWithAuth[] = [ { id: '1', name: 'name', @@ -48,12 +48,11 @@ const ruleTypes = [ category: 'test', producer: 'test', enabledInLicense: true, - minimumScheduleInterval: '1m', defaultScheduleInterval: '10m', hasAlertsMappings: false, hasFieldsForAAD: false, validLegacyConsumers: [], - } as RegistryAlertTypeWithAuth, + }, ]; beforeEach(() => { @@ -76,7 +75,7 @@ beforeEach(() => { describe('healthRoute', () => { it('registers the route', async () => { - rulesClient.listRuleTypes.mockResolvedValueOnce(new Set(ruleTypes)); + rulesClient.listRuleTypes.mockResolvedValueOnce(ruleTypes); const router = httpServiceMock.createRouter(); const licenseState = licenseStateMock.create(); @@ -89,7 +88,7 @@ describe('healthRoute', () => { }); it('queries the usage api', async () => { - rulesClient.listRuleTypes.mockResolvedValueOnce(new Set(ruleTypes)); + rulesClient.listRuleTypes.mockResolvedValueOnce(ruleTypes); const router = httpServiceMock.createRouter(); const licenseState = licenseStateMock.create(); @@ -113,7 +112,7 @@ describe('healthRoute', () => { }); it('throws error when user does not have any access to any rule types', async () => { - rulesClient.listRuleTypes.mockResolvedValueOnce(new Set()); + rulesClient.listRuleTypes.mockResolvedValueOnce([]); const router = httpServiceMock.createRouter(); const licenseState = licenseStateMock.create(); @@ -139,7 +138,7 @@ describe('healthRoute', () => { }); it('evaluates whether Encrypted Saved Objects is missing encryption key', async () => { - rulesClient.listRuleTypes.mockResolvedValueOnce(new Set(ruleTypes)); + rulesClient.listRuleTypes.mockResolvedValueOnce(ruleTypes); const router = httpServiceMock.createRouter(); const licenseState = licenseStateMock.create(); @@ -180,7 +179,7 @@ describe('healthRoute', () => { }); test('when ES security status cannot be determined from license state, isSufficientlySecure should return false', async () => { - rulesClient.listRuleTypes.mockResolvedValueOnce(new Set(ruleTypes)); + rulesClient.listRuleTypes.mockResolvedValueOnce(ruleTypes); const router = httpServiceMock.createRouter(); const licenseState = licenseStateMock.create(); const encryptedSavedObjects = encryptedSavedObjectsMock.createSetup({ canEncrypt: true }); @@ -222,7 +221,7 @@ describe('healthRoute', () => { }); test('when ES security is disabled, isSufficientlySecure should return true', async () => { - rulesClient.listRuleTypes.mockResolvedValueOnce(new Set(ruleTypes)); + rulesClient.listRuleTypes.mockResolvedValueOnce(ruleTypes); const router = httpServiceMock.createRouter(); const licenseState = licenseStateMock.create(); const encryptedSavedObjects = encryptedSavedObjectsMock.createSetup({ canEncrypt: true }); @@ -264,7 +263,7 @@ describe('healthRoute', () => { }); test('when ES security is enabled but user cannot generate api keys, isSufficientlySecure should return false', async () => { - rulesClient.listRuleTypes.mockResolvedValueOnce(new Set(ruleTypes)); + rulesClient.listRuleTypes.mockResolvedValueOnce(ruleTypes); const router = httpServiceMock.createRouter(); const licenseState = licenseStateMock.create(); const encryptedSavedObjects = encryptedSavedObjectsMock.createSetup({ canEncrypt: true }); @@ -306,7 +305,7 @@ describe('healthRoute', () => { }); test('when ES security is enabled and user can generate api keys, isSufficientlySecure should return true', async () => { - rulesClient.listRuleTypes.mockResolvedValueOnce(new Set(ruleTypes)); + rulesClient.listRuleTypes.mockResolvedValueOnce(ruleTypes); const router = httpServiceMock.createRouter(); const licenseState = licenseStateMock.create(); const encryptedSavedObjects = encryptedSavedObjectsMock.createSetup({ canEncrypt: true }); diff --git a/x-pack/plugins/alerting/server/routes/framework/apis/health/health.ts b/x-pack/plugins/alerting/server/routes/framework/apis/health/health.ts index 34ef56a51daaa..4daf510b6a64f 100644 --- a/x-pack/plugins/alerting/server/routes/framework/apis/health/health.ts +++ b/x-pack/plugins/alerting/server/routes/framework/apis/health/health.ts @@ -48,8 +48,9 @@ export const healthRoute = ( verifyAccessAndContext(licenseState, async function (context, req, res) { try { const alertingContext = await context.alerting; + const rulesClient = await alertingContext.getRulesClient(); // Verify that user has access to at least one rule type - const ruleTypes = Array.from(await alertingContext.getRulesClient().listRuleTypes()); + const ruleTypes = Array.from(await rulesClient.listRuleTypes()); if (ruleTypes.length > 0) { const alertingFrameworkHealth = await alertingContext.getFrameworkHealth(); diff --git a/x-pack/plugins/alerting/server/routes/get_action_error_log.ts b/x-pack/plugins/alerting/server/routes/get_action_error_log.ts index 5da2189c1d43d..7406d07c3fa24 100644 --- a/x-pack/plugins/alerting/server/routes/get_action_error_log.ts +++ b/x-pack/plugins/alerting/server/routes/get_action_error_log.ts @@ -69,7 +69,8 @@ export const getActionErrorLogRoute = ( }, router.handleLegacyErrors( verifyAccessAndContext(licenseState, async function (context, req, res) { - const rulesClient = (await context.alerting).getRulesClient(); + const alertingContext = await context.alerting; + const rulesClient = await alertingContext.getRulesClient(); const { id } = req.params; const withAuth = req.query.with_auth; const rewrittenReq = rewriteReq({ id, ...req.query }); diff --git a/x-pack/plugins/alerting/server/routes/get_global_execution_kpi.ts b/x-pack/plugins/alerting/server/routes/get_global_execution_kpi.ts index 795b473dc8c66..48ea073369d2b 100644 --- a/x-pack/plugins/alerting/server/routes/get_global_execution_kpi.ts +++ b/x-pack/plugins/alerting/server/routes/get_global_execution_kpi.ts @@ -46,7 +46,8 @@ export const getGlobalExecutionKPIRoute = ( }, router.handleLegacyErrors( verifyAccessAndContext(licenseState, async function (context, req, res) { - const rulesClient = (await context.alerting).getRulesClient(); + const alertingContext = await context.alerting; + const rulesClient = await alertingContext.getRulesClient(); return res.ok({ body: await rulesClient.getGlobalExecutionKpiWithAuth(rewriteReq(req.query)), }); diff --git a/x-pack/plugins/alerting/server/routes/get_global_execution_logs.ts b/x-pack/plugins/alerting/server/routes/get_global_execution_logs.ts index 9c9e09e81bd45..13ea133e21a82 100644 --- a/x-pack/plugins/alerting/server/routes/get_global_execution_logs.ts +++ b/x-pack/plugins/alerting/server/routes/get_global_execution_logs.ts @@ -71,7 +71,8 @@ export const getGlobalExecutionLogRoute = ( }, router.handleLegacyErrors( verifyAccessAndContext(licenseState, async function (context, req, res) { - const rulesClient = (await context.alerting).getRulesClient(); + const alertingContext = await context.alerting; + const rulesClient = await alertingContext.getRulesClient(); return res.ok({ body: await rulesClient.getGlobalExecutionLogWithAuth(rewriteReq(req.query)), }); diff --git a/x-pack/plugins/alerting/server/routes/get_rule_alert_summary.ts b/x-pack/plugins/alerting/server/routes/get_rule_alert_summary.ts index 7eaf5d4645ecb..937db706199e2 100644 --- a/x-pack/plugins/alerting/server/routes/get_rule_alert_summary.ts +++ b/x-pack/plugins/alerting/server/routes/get_rule_alert_summary.ts @@ -75,7 +75,8 @@ export const getRuleAlertSummaryRoute = ( }, router.handleLegacyErrors( verifyAccessAndContext(licenseState, async function (context, req, res) { - const rulesClient = (await context.alerting).getRulesClient(); + const alertingContext = await context.alerting; + const rulesClient = await alertingContext.getRulesClient(); const { id } = req.params; const summary = await rulesClient.getAlertSummary(rewriteReq({ id, ...req.query })); return res.ok({ body: rewriteBodyRes(summary) }); diff --git a/x-pack/plugins/alerting/server/routes/get_rule_execution_kpi.ts b/x-pack/plugins/alerting/server/routes/get_rule_execution_kpi.ts index af15520d3c32f..302ac0293a444 100644 --- a/x-pack/plugins/alerting/server/routes/get_rule_execution_kpi.ts +++ b/x-pack/plugins/alerting/server/routes/get_rule_execution_kpi.ts @@ -48,7 +48,8 @@ export const getRuleExecutionKPIRoute = ( }, router.handleLegacyErrors( verifyAccessAndContext(licenseState, async function (context, req, res) { - const rulesClient = (await context.alerting).getRulesClient(); + const alertingContext = await context.alerting; + const rulesClient = await alertingContext.getRulesClient(); const { id } = req.params; return res.ok({ body: await rulesClient.getRuleExecutionKPI(rewriteReq({ id, ...req.query })), diff --git a/x-pack/plugins/alerting/server/routes/get_rule_execution_log.ts b/x-pack/plugins/alerting/server/routes/get_rule_execution_log.ts index 619bc82bd6378..4eccefd171f0e 100644 --- a/x-pack/plugins/alerting/server/routes/get_rule_execution_log.ts +++ b/x-pack/plugins/alerting/server/routes/get_rule_execution_log.ts @@ -73,7 +73,8 @@ export const getRuleExecutionLogRoute = ( }, router.handleLegacyErrors( verifyAccessAndContext(licenseState, async function (context, req, res) { - const rulesClient = (await context.alerting).getRulesClient(); + const alertingContext = await context.alerting; + const rulesClient = await alertingContext.getRulesClient(); const { id } = req.params; return res.ok({ body: await rulesClient.getExecutionLogForRule(rewriteReq({ id, ...req.query })), diff --git a/x-pack/plugins/alerting/server/routes/get_rule_state.ts b/x-pack/plugins/alerting/server/routes/get_rule_state.ts index 7530f1d4964cd..1a2b17b8f6747 100644 --- a/x-pack/plugins/alerting/server/routes/get_rule_state.ts +++ b/x-pack/plugins/alerting/server/routes/get_rule_state.ts @@ -47,7 +47,8 @@ export const getRuleStateRoute = ( }, router.handleLegacyErrors( verifyAccessAndContext(licenseState, async function (context, req, res) { - const rulesClient = (await context.alerting).getRulesClient(); + const alertingContext = await context.alerting; + const rulesClient = await alertingContext.getRulesClient(); const { id } = req.params; const state = await rulesClient.getAlertState({ id }); return state ? res.ok({ body: rewriteBodyRes(state) }) : res.noContent(); diff --git a/x-pack/plugins/alerting/server/routes/legacy/create.ts b/x-pack/plugins/alerting/server/routes/legacy/create.ts index 10c0fd2941068..8346ec37edf9c 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/create.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/create.ts @@ -84,7 +84,9 @@ export const createAlertRoute = ({ if (!context.alerting) { return res.badRequest({ body: 'RouteHandlerContext is not registered for alerting' }); } - const rulesClient = (await context.alerting).getRulesClient(); + + const alertingContext = await context.alerting; + const rulesClient = await alertingContext.getRulesClient(); const alert = req.body; const params = req.params; const notifyWhen = alert?.notifyWhen ? (alert.notifyWhen as RuleNotifyWhenType) : null; diff --git a/x-pack/plugins/alerting/server/routes/legacy/delete.ts b/x-pack/plugins/alerting/server/routes/legacy/delete.ts index a3ceb1ebccbba..738633c61f745 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/delete.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/delete.ts @@ -52,7 +52,8 @@ export const deleteAlertRoute = ( return res.badRequest({ body: 'RouteHandlerContext is not registered for alerting' }); } trackLegacyRouteUsage('delete', usageCounter); - const rulesClient = (await context.alerting).getRulesClient(); + const alertingContext = await context.alerting; + const rulesClient = await alertingContext.getRulesClient(); const { id } = req.params; await rulesClient.delete({ id }); return res.noContent(); diff --git a/x-pack/plugins/alerting/server/routes/legacy/disable.ts b/x-pack/plugins/alerting/server/routes/legacy/disable.ts index 1d2293b698e42..e69a176776e0c 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/disable.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/disable.ts @@ -53,7 +53,8 @@ export const disableAlertRoute = ( return res.badRequest({ body: 'RouteHandlerContext is not registered for alerting' }); } trackLegacyRouteUsage('disable', usageCounter); - const rulesClient = (await context.alerting).getRulesClient(); + const alertingContext = await context.alerting; + const rulesClient = await alertingContext.getRulesClient(); const { id } = req.params; try { await rulesClient.disableRule({ id }); diff --git a/x-pack/plugins/alerting/server/routes/legacy/enable.ts b/x-pack/plugins/alerting/server/routes/legacy/enable.ts index 8f680a23f89eb..289b4050e059b 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/enable.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/enable.ts @@ -55,7 +55,8 @@ export const enableAlertRoute = ( return res.badRequest({ body: 'RouteHandlerContext is not registered for alerting' }); } trackLegacyRouteUsage('enable', usageCounter); - const rulesClient = (await context.alerting).getRulesClient(); + const alertingContext = await context.alerting; + const rulesClient = await alertingContext.getRulesClient(); const { id } = req.params; try { await rulesClient.enableRule({ id }); diff --git a/x-pack/plugins/alerting/server/routes/legacy/find.ts b/x-pack/plugins/alerting/server/routes/legacy/find.ts index ef4f8a45bcc0f..de1e5f8c226a1 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/find.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/find.ts @@ -104,7 +104,8 @@ export const findAlertRoute = ( ) as string[], usageCounter ); - const rulesClient = (await context.alerting).getRulesClient(); + const alertingContext = await context.alerting; + const rulesClient = await alertingContext.getRulesClient(); const query = req.query; const renameMap = { diff --git a/x-pack/plugins/alerting/server/routes/legacy/get.ts b/x-pack/plugins/alerting/server/routes/legacy/get.ts index 08ecd410adc1f..19fc0f7ff49e6 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/get.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/get.ts @@ -52,7 +52,8 @@ export const getAlertRoute = ( return res.badRequest({ body: 'RouteHandlerContext is not registered for alerting' }); } trackLegacyRouteUsage('get', usageCounter); - const rulesClient = (await context.alerting).getRulesClient(); + const alertingContext = await context.alerting; + const rulesClient = await alertingContext.getRulesClient(); const { id } = req.params; const { systemActions, ...rule } = await rulesClient.get({ id, excludeFromPublicApi: true }); return res.ok({ diff --git a/x-pack/plugins/alerting/server/routes/legacy/get_alert_instance_summary.ts b/x-pack/plugins/alerting/server/routes/legacy/get_alert_instance_summary.ts index 58ab6a5446756..0e50601a1fd4d 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/get_alert_instance_summary.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/get_alert_instance_summary.ts @@ -61,7 +61,8 @@ export const getAlertInstanceSummaryRoute = ( return res.badRequest({ body: 'RouteHandlerContext is not registered for alerting' }); } trackLegacyRouteUsage('instanceSummary', usageCounter); - const rulesClient = (await context.alerting).getRulesClient(); + const alertingContext = await context.alerting; + const rulesClient = await alertingContext.getRulesClient(); const { id } = req.params; const { dateStart } = req.query; const summary = await rulesClient.getAlertSummary({ id, dateStart }); diff --git a/x-pack/plugins/alerting/server/routes/legacy/get_alert_state.ts b/x-pack/plugins/alerting/server/routes/legacy/get_alert_state.ts index ad3d9591c92c4..f9db44c1e9a0c 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/get_alert_state.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/get_alert_state.ts @@ -50,7 +50,8 @@ export const getAlertStateRoute = ( return res.badRequest({ body: 'RouteHandlerContext is not registered for alerting' }); } trackLegacyRouteUsage('state', usageCounter); - const rulesClient = (await context.alerting).getRulesClient(); + const alertingContext = await context.alerting; + const rulesClient = await alertingContext.getRulesClient(); const { id } = req.params; const state = await rulesClient.getAlertState({ id }); return state ? res.ok({ body: state }) : res.noContent(); diff --git a/x-pack/plugins/alerting/server/routes/legacy/health.test.ts b/x-pack/plugins/alerting/server/routes/legacy/health.test.ts index 64c994f9936b3..fea24b831e97d 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/health.test.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/health.test.ts @@ -84,7 +84,7 @@ describe('healthRoute', () => { const docLinks = docLinksServiceMock.createSetupContract(); it('registers the route', async () => { - rulesClient.listRuleTypes.mockResolvedValueOnce(new Set(ruleTypes)); + rulesClient.listRuleTypes.mockResolvedValueOnce(ruleTypes); const router = httpServiceMock.createRouter(); const licenseState = licenseStateMock.create(); @@ -98,7 +98,7 @@ describe('healthRoute', () => { }); it('should have internal access for serverless', async () => { - rulesClient.listRuleTypes.mockResolvedValueOnce(new Set(ruleTypes)); + rulesClient.listRuleTypes.mockResolvedValueOnce(ruleTypes); const router = httpServiceMock.createRouter(); const licenseState = licenseStateMock.create(); @@ -112,7 +112,7 @@ describe('healthRoute', () => { }); it('throws error when user does not have any access to any rule types', async () => { - rulesClient.listRuleTypes.mockResolvedValueOnce(new Set()); + rulesClient.listRuleTypes.mockResolvedValueOnce([]); const router = httpServiceMock.createRouter(); const licenseState = licenseStateMock.create(); @@ -138,7 +138,7 @@ describe('healthRoute', () => { }); it('evaluates whether Encrypted Saved Objects is missing encryption key', async () => { - rulesClient.listRuleTypes.mockResolvedValueOnce(new Set(ruleTypes)); + rulesClient.listRuleTypes.mockResolvedValueOnce(ruleTypes); const router = httpServiceMock.createRouter(); const licenseState = licenseStateMock.create(); @@ -195,7 +195,7 @@ describe('healthRoute', () => { }); test('when ES security status cannot be determined from license state, isSufficientlySecure should return false', async () => { - rulesClient.listRuleTypes.mockResolvedValueOnce(new Set(ruleTypes)); + rulesClient.listRuleTypes.mockResolvedValueOnce(ruleTypes); const router = httpServiceMock.createRouter(); const licenseState = licenseStateMock.create(); const encryptedSavedObjects = encryptedSavedObjectsMock.createSetup({ canEncrypt: true }); @@ -253,7 +253,7 @@ describe('healthRoute', () => { }); test('when ES security is disabled, isSufficientlySecure should return true', async () => { - rulesClient.listRuleTypes.mockResolvedValueOnce(new Set(ruleTypes)); + rulesClient.listRuleTypes.mockResolvedValueOnce(ruleTypes); const router = httpServiceMock.createRouter(); const licenseState = licenseStateMock.create(); const encryptedSavedObjects = encryptedSavedObjectsMock.createSetup({ canEncrypt: true }); @@ -311,7 +311,7 @@ describe('healthRoute', () => { }); test('when ES security is enabled but user cannot generate api keys, isSufficientlySecure should return false', async () => { - rulesClient.listRuleTypes.mockResolvedValueOnce(new Set(ruleTypes)); + rulesClient.listRuleTypes.mockResolvedValueOnce(ruleTypes); const router = httpServiceMock.createRouter(); const licenseState = licenseStateMock.create(); const encryptedSavedObjects = encryptedSavedObjectsMock.createSetup({ canEncrypt: true }); @@ -369,7 +369,7 @@ describe('healthRoute', () => { }); test('when ES security is enabled and user can generate api keys, isSufficientlySecure should return true', async () => { - rulesClient.listRuleTypes.mockResolvedValueOnce(new Set(ruleTypes)); + rulesClient.listRuleTypes.mockResolvedValueOnce(ruleTypes); const router = httpServiceMock.createRouter(); const licenseState = licenseStateMock.create(); const encryptedSavedObjects = encryptedSavedObjectsMock.createSetup({ canEncrypt: true }); @@ -427,7 +427,7 @@ describe('healthRoute', () => { }); it('should track every call', async () => { - rulesClient.listRuleTypes.mockResolvedValueOnce(new Set(ruleTypes)); + rulesClient.listRuleTypes.mockResolvedValueOnce(ruleTypes); const licenseState = licenseStateMock.create(); const router = httpServiceMock.createRouter(); const encryptedSavedObjects = encryptedSavedObjectsMock.createSetup({ canEncrypt: true }); @@ -444,7 +444,7 @@ describe('healthRoute', () => { }); it('should be deprecated', async () => { - rulesClient.listRuleTypes.mockResolvedValueOnce(new Set(ruleTypes)); + rulesClient.listRuleTypes.mockResolvedValueOnce(ruleTypes); const router = httpServiceMock.createRouter(); const licenseState = licenseStateMock.create(); diff --git a/x-pack/plugins/alerting/server/routes/legacy/health.ts b/x-pack/plugins/alerting/server/routes/legacy/health.ts index 223859124072b..b463298837f4e 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/health.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/health.ts @@ -50,8 +50,9 @@ export function healthRoute( trackLegacyRouteUsage('health', usageCounter); try { const alertingContext = await context.alerting; + const rulesClient = await alertingContext.getRulesClient(); // Verify that user has access to at least one rule type - const ruleTypes = Array.from(await alertingContext.getRulesClient().listRuleTypes()); + const ruleTypes = Array.from(await rulesClient.listRuleTypes()); if (ruleTypes.length > 0) { const alertingFrameworkHealth = await alertingContext.getFrameworkHealth(); diff --git a/x-pack/plugins/alerting/server/routes/legacy/list_alert_types.test.ts b/x-pack/plugins/alerting/server/routes/legacy/list_alert_types.test.ts index 3c1be0410f586..27e9d7ce44865 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/list_alert_types.test.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/list_alert_types.test.ts @@ -44,7 +44,7 @@ describe('listAlertTypesRoute', () => { expect(config.path).toMatchInlineSnapshot(`"/api/alerts/list_alert_types"`); expect(config.options?.access).toBe('public'); - const listTypes = [ + const listTypes: RegistryAlertTypeWithAuth[] = [ { id: '1', name: 'name', @@ -69,9 +69,10 @@ describe('listAlertTypesRoute', () => { hasAlertsMappings: false, hasFieldsForAAD: false, validLegacyConsumers: [], - } as RegistryAlertTypeWithAuth, + }, ]; - rulesClient.listRuleTypes.mockResolvedValueOnce(new Set(listTypes)); + + rulesClient.listRuleTypes.mockResolvedValueOnce(listTypes); const [context, req, res] = mockHandlerArguments({ rulesClient }, {}, ['ok']); @@ -167,7 +168,7 @@ describe('listAlertTypesRoute', () => { } as RegistryAlertTypeWithAuth, ]; - rulesClient.listRuleTypes.mockResolvedValueOnce(new Set(listTypes)); + rulesClient.listRuleTypes.mockResolvedValueOnce(listTypes); const [context, req, res] = mockHandlerArguments( { rulesClient }, @@ -224,7 +225,7 @@ describe('listAlertTypesRoute', () => { } as RegistryAlertTypeWithAuth, ]; - rulesClient.listRuleTypes.mockResolvedValueOnce(new Set(listTypes)); + rulesClient.listRuleTypes.mockResolvedValueOnce(listTypes); const [context, req, res] = mockHandlerArguments( { rulesClient }, @@ -245,7 +246,7 @@ describe('listAlertTypesRoute', () => { const mockUsageCountersSetup = usageCountersServiceMock.createSetupContract(); const mockUsageCounter = mockUsageCountersSetup.createUsageCounter('test'); - rulesClient.listRuleTypes.mockResolvedValueOnce(new Set([])); + rulesClient.listRuleTypes.mockResolvedValueOnce([]); listAlertTypesRoute(router, licenseState, docLinks, mockUsageCounter); const [, handler] = router.get.mock.calls[0]; diff --git a/x-pack/plugins/alerting/server/routes/legacy/list_alert_types.ts b/x-pack/plugins/alerting/server/routes/legacy/list_alert_types.ts index ad0f470ae9235..f4f2bc7936b3d 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/list_alert_types.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/list_alert_types.ts @@ -45,8 +45,10 @@ export const listAlertTypesRoute = ( } trackLegacyRouteUsage('listAlertTypes', usageCounter); const alertingContext = await context.alerting; + const rulesClient = await alertingContext.getRulesClient(); + return res.ok({ - body: Array.from(await alertingContext.getRulesClient().listRuleTypes()), + body: Array.from(await rulesClient.listRuleTypes()), }); }) ); diff --git a/x-pack/plugins/alerting/server/routes/legacy/mute_all.ts b/x-pack/plugins/alerting/server/routes/legacy/mute_all.ts index f7cb03a81dcb2..75c860167f21c 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/mute_all.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/mute_all.ts @@ -53,7 +53,8 @@ export const muteAllAlertRoute = ( return res.badRequest({ body: 'RouteHandlerContext is not registered for alerting' }); } trackLegacyRouteUsage('muteAll', usageCounter); - const rulesClient = (await context.alerting).getRulesClient(); + const alertingContext = await context.alerting; + const rulesClient = await alertingContext.getRulesClient(); const { id } = req.params; try { await rulesClient.muteAll({ id }); diff --git a/x-pack/plugins/alerting/server/routes/legacy/mute_instance.ts b/x-pack/plugins/alerting/server/routes/legacy/mute_instance.ts index a8e70ba707b78..23225c387ccaa 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/mute_instance.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/mute_instance.ts @@ -58,7 +58,8 @@ export const muteAlertInstanceRoute = ( trackLegacyRouteUsage('muteInstance', usageCounter); - const rulesClient = (await context.alerting).getRulesClient(); + const alertingContext = await context.alerting; + const rulesClient = await alertingContext.getRulesClient(); const renameMap = { alert_id: 'alertId', diff --git a/x-pack/plugins/alerting/server/routes/legacy/unmute_all.ts b/x-pack/plugins/alerting/server/routes/legacy/unmute_all.ts index bde7bea430fa5..2684ea60d7336 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/unmute_all.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/unmute_all.ts @@ -53,7 +53,8 @@ export const unmuteAllAlertRoute = ( return res.badRequest({ body: 'RouteHandlerContext is not registered for alerting' }); } trackLegacyRouteUsage('unmuteAll', usageCounter); - const rulesClient = (await context.alerting).getRulesClient(); + const alertingContext = await context.alerting; + const rulesClient = await alertingContext.getRulesClient(); const { id } = req.params; try { await rulesClient.unmuteAll({ id }); diff --git a/x-pack/plugins/alerting/server/routes/legacy/unmute_instance.ts b/x-pack/plugins/alerting/server/routes/legacy/unmute_instance.ts index 91774b0df7ac8..e6122a92509b0 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/unmute_instance.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/unmute_instance.ts @@ -54,7 +54,8 @@ export const unmuteAlertInstanceRoute = ( return res.badRequest({ body: 'RouteHandlerContext is not registered for alerting' }); } trackLegacyRouteUsage('unmuteInstance', usageCounter); - const rulesClient = (await context.alerting).getRulesClient(); + const alertingContext = await context.alerting; + const rulesClient = await alertingContext.getRulesClient(); const { alertId, alertInstanceId } = req.params; try { await rulesClient.unmuteInstance({ alertId, alertInstanceId }); diff --git a/x-pack/plugins/alerting/server/routes/legacy/update.ts b/x-pack/plugins/alerting/server/routes/legacy/update.ts index 04f54738e9608..3e3d3b5a480f0 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/update.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/update.ts @@ -81,7 +81,8 @@ export const updateAlertRoute = ( return res.badRequest({ body: 'RouteHandlerContext is not registered for alerting' }); } trackLegacyRouteUsage('update', usageCounter); - const rulesClient = (await context.alerting).getRulesClient(); + const alertingContext = await context.alerting; + const rulesClient = await alertingContext.getRulesClient(); const { id } = req.params; const { name, actions, params, schedule, tags, throttle, notifyWhen } = req.body; try { diff --git a/x-pack/plugins/alerting/server/routes/legacy/update_api_key.ts b/x-pack/plugins/alerting/server/routes/legacy/update_api_key.ts index 0a3b62ebed368..603a321768573 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/update_api_key.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/update_api_key.ts @@ -55,7 +55,8 @@ export const updateApiKeyRoute = ( return res.badRequest({ body: 'RouteHandlerContext is not registered for alerting' }); } trackLegacyRouteUsage('updateApiKey', usageCounter); - const rulesClient = (await context.alerting).getRulesClient(); + const alertingContext = await context.alerting; + const rulesClient = await alertingContext.getRulesClient(); const { id } = req.params; try { await rulesClient.updateRuleApiKey({ id }); diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/aggregate/aggregate_rules_route.test.ts b/x-pack/plugins/alerting/server/routes/rule/apis/aggregate/aggregate_rules_route.test.ts index 77221de2d714b..74a94cbba80a1 100644 --- a/x-pack/plugins/alerting/server/routes/rule/apis/aggregate/aggregate_rules_route.test.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/aggregate/aggregate_rules_route.test.ts @@ -145,6 +145,7 @@ describe('aggregateRulesRoute', () => { { body: { default_search_operator: 'AND', + rule_type_ids: ['foo'], }, }, ['ok'] @@ -237,6 +238,9 @@ describe('aggregateRulesRoute', () => { }, "options": Object { "defaultSearchOperator": "AND", + "ruleTypeIds": Array [ + "foo", + ], }, }, ] diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/aggregate/aggregate_rules_route.ts b/x-pack/plugins/alerting/server/routes/rule/apis/aggregate/aggregate_rules_route.ts index 9b595858793f8..05c5fc2167e11 100644 --- a/x-pack/plugins/alerting/server/routes/rule/apis/aggregate/aggregate_rules_route.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/aggregate/aggregate_rules_route.ts @@ -37,7 +37,8 @@ export const aggregateRulesRoute = ( }, router.handleLegacyErrors( verifyAccessAndContext(licenseState, async function (context, req, res) { - const rulesClient = (await context.alerting).getRulesClient(); + const alertingContext = await context.alerting; + const rulesClient = await alertingContext.getRulesClient(); const body: AggregateRulesRequestBodyV1 = req.body; const options = transformAggregateQueryRequestV1({ ...body, diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/aggregate/transforms/transform_aggregate_query_request/v1.ts b/x-pack/plugins/alerting/server/routes/rule/apis/aggregate/transforms/transform_aggregate_query_request/v1.ts index baa6b9bb46f9c..ae13f08d0afa5 100644 --- a/x-pack/plugins/alerting/server/routes/rule/apis/aggregate/transforms/transform_aggregate_query_request/v1.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/aggregate/transforms/transform_aggregate_query_request/v1.ts @@ -13,13 +13,15 @@ export const transformAggregateQueryRequest: RewriteRequestCase ({ defaultSearchOperator, ...(hasReference ? { hasReference } : {}), ...(searchFields ? { searchFields } : {}), ...(search ? { search } : {}), - ...(filterConsumers ? { filterConsumers } : {}), + ...(ruleTypeIds ? { ruleTypeIds } : {}), + ...(consumers ? { consumers } : {}), ...(filter ? { filter } : {}), }); diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/bulk_delete/bulk_delete_rules_route.ts b/x-pack/plugins/alerting/server/routes/rule/apis/bulk_delete/bulk_delete_rules_route.ts index 8bd6f7fc19916..8548464d44812 100644 --- a/x-pack/plugins/alerting/server/routes/rule/apis/bulk_delete/bulk_delete_rules_route.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/bulk_delete/bulk_delete_rules_route.ts @@ -36,7 +36,8 @@ export const bulkDeleteRulesRoute = ({ handleDisabledApiKeysError( router.handleLegacyErrors( verifyAccessAndContext(licenseState, async (context, req, res) => { - const rulesClient = (await context.alerting).getRulesClient(); + const alertingContext = await context.alerting; + const rulesClient = await alertingContext.getRulesClient(); const body: BulkDeleteRulesRequestBodyV1 = req.body; const { filter, ids } = body; diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/bulk_disable/bulk_disable_rules_route.ts b/x-pack/plugins/alerting/server/routes/rule/apis/bulk_disable/bulk_disable_rules_route.ts index 724eda3ae7b87..315904efa40a7 100644 --- a/x-pack/plugins/alerting/server/routes/rule/apis/bulk_disable/bulk_disable_rules_route.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/bulk_disable/bulk_disable_rules_route.ts @@ -37,7 +37,8 @@ export const bulkDisableRulesRoute = ({ handleDisabledApiKeysError( router.handleLegacyErrors( verifyAccessAndContext(licenseState, async (context, req, res) => { - const rulesClient = (await context.alerting).getRulesClient(); + const alertingContext = await context.alerting; + const rulesClient = await alertingContext.getRulesClient(); const body: BulkDisableRulesRequestBodyV1 = req.body; const { filter, ids, untrack } = body; diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/bulk_edit/bulk_edit_rules_route.ts b/x-pack/plugins/alerting/server/routes/rule/apis/bulk_edit/bulk_edit_rules_route.ts index 4c853beeec250..f516b63031aad 100644 --- a/x-pack/plugins/alerting/server/routes/rule/apis/bulk_edit/bulk_edit_rules_route.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/bulk_edit/bulk_edit_rules_route.ts @@ -41,7 +41,8 @@ const buildBulkEditRulesRoute = ({ licenseState, path, router }: BuildBulkEditRu handleDisabledApiKeysError( router.handleLegacyErrors( verifyAccessAndContext(licenseState, async function (context, req, res) { - const rulesClient = (await context.alerting).getRulesClient(); + const alertingContext = await context.alerting; + const rulesClient = await alertingContext.getRulesClient(); const actionsClient = (await context.actions).getActionsClient(); const bulkEditData: BulkEditRulesRequestBodyV1 = req.body; diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/bulk_enable/bulk_enable_rules_route.ts b/x-pack/plugins/alerting/server/routes/rule/apis/bulk_enable/bulk_enable_rules_route.ts index da97949fd0feb..71932cb6d78bb 100644 --- a/x-pack/plugins/alerting/server/routes/rule/apis/bulk_enable/bulk_enable_rules_route.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/bulk_enable/bulk_enable_rules_route.ts @@ -35,7 +35,8 @@ export const bulkEnableRulesRoute = ({ handleDisabledApiKeysError( router.handleLegacyErrors( verifyAccessAndContext(licenseState, async (context, req, res) => { - const rulesClient = (await context.alerting).getRulesClient(); + const alertingContext = await context.alerting; + const rulesClient = await alertingContext.getRulesClient(); const body: BulkEnableRulesRequestBodyV1 = req.body; try { diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/bulk_untrack/bulk_untrack_alerts_route.ts b/x-pack/plugins/alerting/server/routes/rule/apis/bulk_untrack/bulk_untrack_alerts_route.ts index 622218705b510..a43cc48d95631 100644 --- a/x-pack/plugins/alerting/server/routes/rule/apis/bulk_untrack/bulk_untrack_alerts_route.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/bulk_untrack/bulk_untrack_alerts_route.ts @@ -28,7 +28,8 @@ export const bulkUntrackAlertsRoute = ( }, router.handleLegacyErrors( verifyAccessAndContext(licenseState, async function (context, req, res) { - const rulesClient = (await context.alerting).getRulesClient(); + const alertingContext = await context.alerting; + const rulesClient = await alertingContext.getRulesClient(); const body: BulkUntrackRequestBodyV1 = req.body; try { await rulesClient.bulkUntrackAlerts({ diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/bulk_untrack_by_query/bulk_untrack_alerts_by_query_route.test.ts b/x-pack/plugins/alerting/server/routes/rule/apis/bulk_untrack_by_query/bulk_untrack_alerts_by_query_route.test.ts index 3486005d3b588..ebaab0cb98402 100644 --- a/x-pack/plugins/alerting/server/routes/rule/apis/bulk_untrack_by_query/bulk_untrack_alerts_by_query_route.test.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/bulk_untrack_by_query/bulk_untrack_alerts_by_query_route.test.ts @@ -45,7 +45,7 @@ describe('bulkUntrackAlertsByQueryRoute', () => { }, }, ], - feature_ids: ['o11y'], + rule_type_ids: ['o11y'], }; const [context, req, res] = mockHandlerArguments( @@ -62,7 +62,7 @@ describe('bulkUntrackAlertsByQueryRoute', () => { expect(rulesClient.bulkUntrackAlerts.mock.calls[0]).toEqual([ { query: requestBody.query, - featureIds: requestBody.feature_ids, + ruleTypeIds: requestBody.rule_type_ids, isUsingQuery: true, }, ]); diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/bulk_untrack_by_query/bulk_untrack_alerts_by_query_route.ts b/x-pack/plugins/alerting/server/routes/rule/apis/bulk_untrack_by_query/bulk_untrack_alerts_by_query_route.ts index 5cebdb8c6e7f4..735cd75b7f4a9 100644 --- a/x-pack/plugins/alerting/server/routes/rule/apis/bulk_untrack_by_query/bulk_untrack_alerts_by_query_route.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/bulk_untrack_by_query/bulk_untrack_alerts_by_query_route.ts @@ -29,7 +29,8 @@ export const bulkUntrackAlertsByQueryRoute = ( }, router.handleLegacyErrors( verifyAccessAndContext(licenseState, async function (context, req, res) { - const rulesClient = (await context.alerting).getRulesClient(); + const alertingContext = await context.alerting; + const rulesClient = await alertingContext.getRulesClient(); const body: BulkUntrackByQueryRequestBodyV1 = req.body; try { await rulesClient.bulkUntrackAlerts({ diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/bulk_untrack_by_query/transforms/transform_bulk_untrack_alerts_by_query_body/v1.ts b/x-pack/plugins/alerting/server/routes/rule/apis/bulk_untrack_by_query/transforms/transform_bulk_untrack_alerts_by_query_body/v1.ts index 87c58c48c4c6d..dd346f8cc818e 100644 --- a/x-pack/plugins/alerting/server/routes/rule/apis/bulk_untrack_by_query/transforms/transform_bulk_untrack_alerts_by_query_body/v1.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/bulk_untrack_by_query/transforms/transform_bulk_untrack_alerts_by_query_body/v1.ts @@ -9,8 +9,8 @@ import type { BulkUntrackByQueryRequestBodyV1 } from '../../../../../../../commo export const transformBulkUntrackAlertsByQueryBody = ({ query, - feature_ids: featureIds, + rule_type_ids: ruleTypeIds, }: BulkUntrackByQueryRequestBodyV1) => ({ query, - featureIds, + ruleTypeIds, }); diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/clone/clone_rule_route.ts b/x-pack/plugins/alerting/server/routes/rule/apis/clone/clone_rule_route.ts index ea6460dfb9463..0aa23886a9b4a 100644 --- a/x-pack/plugins/alerting/server/routes/rule/apis/clone/clone_rule_route.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/clone/clone_rule_route.ts @@ -33,7 +33,8 @@ export const cloneRuleRoute = ( handleDisabledApiKeysError( router.handleLegacyErrors( verifyAccessAndContext(licenseState, async function (context, req, res) { - const rulesClient = (await context.alerting).getRulesClient(); + const alertingContext = await context.alerting; + const rulesClient = await alertingContext.getRulesClient(); const params: CloneRuleRequestParamsV1 = req.params; try { // TODO (http-versioning): Remove this cast, this enables us to move forward diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/create/create_rule_route.ts b/x-pack/plugins/alerting/server/routes/rule/apis/create/create_rule_route.ts index 45341fb48e9bd..26775ad0f98d4 100644 --- a/x-pack/plugins/alerting/server/routes/rule/apis/create/create_rule_route.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/create/create_rule_route.ts @@ -62,7 +62,8 @@ export const createRuleRoute = ({ router, licenseState, usageCounter }: RouteOpt handleDisabledApiKeysError( router.handleLegacyErrors( verifyAccessAndContext(licenseState, async function (context, req, res) { - const rulesClient = (await context.alerting).getRulesClient(); + const alertingContext = await context.alerting; + const rulesClient = await alertingContext.getRulesClient(); const actionsClient = (await context.actions).getActionsClient(); const rulesSettingsClient = (await context.alerting).getRulesSettingsClient(true); diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/delete/delete_rule_route.ts b/x-pack/plugins/alerting/server/routes/rule/apis/delete/delete_rule_route.ts index 0452de7f7becd..e1e09403b309a 100644 --- a/x-pack/plugins/alerting/server/routes/rule/apis/delete/delete_rule_route.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/delete/delete_rule_route.ts @@ -48,7 +48,8 @@ export const deleteRuleRoute = ( }, router.handleLegacyErrors( verifyAccessAndContext(licenseState, async function (context, req, res) { - const rulesClient = (await context.alerting).getRulesClient(); + const alertingContext = await context.alerting; + const rulesClient = await alertingContext.getRulesClient(); const params: DeleteRuleRequestParamsV1 = req.params; diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/disable/disable_rule_route.ts b/x-pack/plugins/alerting/server/routes/rule/apis/disable/disable_rule_route.ts index cae82e80be869..e364bc130121d 100644 --- a/x-pack/plugins/alerting/server/routes/rule/apis/disable/disable_rule_route.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/disable/disable_rule_route.ts @@ -51,7 +51,7 @@ export const disableRuleRoute = ( }, router.handleLegacyErrors( verifyAccessAndContext(licenseState, async function (context, req, res) { - const rulesClient = (await context.alerting).getRulesClient(); + const rulesClient = await (await context.alerting).getRulesClient(); const { id }: DisableRuleRequestParamsV1 = req.params; const body: DisableRuleRequestBodyV1 = req.body || {}; const { untrack = false } = body; diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/enable/enable_rule_route.ts b/x-pack/plugins/alerting/server/routes/rule/apis/enable/enable_rule_route.ts index 4843ed932374d..e5f0983bf844b 100644 --- a/x-pack/plugins/alerting/server/routes/rule/apis/enable/enable_rule_route.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/enable/enable_rule_route.ts @@ -48,7 +48,7 @@ export const enableRuleRoute = ( }, router.handleLegacyErrors( verifyAccessAndContext(licenseState, async function (context, req, res) { - const rulesClient = (await context.alerting).getRulesClient(); + const rulesClient = await (await context.alerting).getRulesClient(); const params: EnableRuleRequestParamsV1 = req.params; try { diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/find/find_internal_rules_route.test.ts b/x-pack/plugins/alerting/server/routes/rule/apis/find/find_internal_rules_route.test.ts index 46ff2e8e96e12..53b330a8a2044 100644 --- a/x-pack/plugins/alerting/server/routes/rule/apis/find/find_internal_rules_route.test.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/find/find_internal_rules_route.test.ts @@ -7,6 +7,8 @@ import { httpServiceMock } from '@kbn/core/server/mocks'; import { licenseStateMock } from '../../../../lib/license_state.mock'; import { findInternalRulesRoute } from './find_internal_rules_route'; +import { mockHandlerArguments } from '../../../_mock_handler_arguments'; +import { rulesClientMock } from '../../../../rules_client.mock'; jest.mock('../../../../lib/license_api_access', () => ({ verifyApiAccess: jest.fn(), @@ -20,6 +22,8 @@ beforeEach(() => { jest.resetAllMocks(); }); +const rulesClient = rulesClientMock.create(); + describe('findInternalRulesRoute', () => { it('registers the route without public access', async () => { const licenseState = licenseStateMock.create(); @@ -33,4 +37,78 @@ describe('findInternalRulesRoute', () => { expect.any(Function) ); }); + + it('finds rules with proper parameters', async () => { + const licenseState = licenseStateMock.create(); + const router = httpServiceMock.createRouter(); + + findInternalRulesRoute(router, licenseState); + + const [config, handler] = router.post.mock.calls[0]; + + expect(config.path).toMatchInlineSnapshot(`"/internal/alerting/rules/_find"`); + + const findResult = { + page: 1, + perPage: 1, + total: 0, + data: [], + }; + rulesClient.find.mockResolvedValueOnce(findResult); + + const [context, req, res] = mockHandlerArguments( + { rulesClient }, + { + body: { + per_page: 1, + page: 1, + default_search_operator: 'OR', + rule_type_ids: ['foo'], + consumers: ['bar'], + }, + }, + ['ok'] + ); + + expect(await handler(context, req, res)).toMatchInlineSnapshot(` + Object { + "body": Object { + "data": Array [], + "page": 1, + "per_page": 1, + "total": 0, + }, + } + `); + + expect(rulesClient.find).toHaveBeenCalledTimes(1); + expect(rulesClient.find.mock.calls[0]).toMatchInlineSnapshot(` + Array [ + Object { + "excludeFromPublicApi": false, + "includeSnoozeData": true, + "options": Object { + "consumers": Array [ + "bar", + ], + "defaultSearchOperator": "OR", + "page": 1, + "perPage": 1, + "ruleTypeIds": Array [ + "foo", + ], + }, + }, + ] + `); + + expect(res.ok).toHaveBeenCalledWith({ + body: { + page: 1, + per_page: 1, + total: 0, + data: [], + }, + }); + }); }); diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/find/find_internal_rules_route.ts b/x-pack/plugins/alerting/server/routes/rule/apis/find/find_internal_rules_route.ts index 8ff8ce59192cf..0117d86468f2a 100644 --- a/x-pack/plugins/alerting/server/routes/rule/apis/find/find_internal_rules_route.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/find/find_internal_rules_route.ts @@ -8,10 +8,10 @@ import { IRouter } from '@kbn/core/server'; import { UsageCounter } from '@kbn/usage-collection-plugin/server'; import type { - FindRulesRequestQueryV1, + FindRulesInternalRequestBodyV1, FindRulesResponseV1, } from '../../../../../common/routes/rule/apis/find'; -import { findRulesRequestQuerySchemaV1 } from '../../../../../common/routes/rule/apis/find'; +import { findRulesInternalRequestBodySchemaV1 } from '../../../../../common/routes/rule/apis/find'; import { RuleParamsV1 } from '../../../../../common/routes/rule/response'; import { ILicenseState } from '../../../../lib'; import { @@ -20,7 +20,7 @@ import { } from '../../../../types'; import { verifyAccessAndContext } from '../../../lib'; import { trackLegacyTerminology } from '../../../lib/track_legacy_terminology'; -import { transformFindRulesBodyV1, transformFindRulesResponseV1 } from './transforms'; +import { transformFindRulesInternalBodyV1, transformFindRulesResponseV1 } from './transforms'; export const findInternalRulesRoute = ( router: IRouter, @@ -32,14 +32,14 @@ export const findInternalRulesRoute = ( path: INTERNAL_ALERTING_API_FIND_RULES_PATH, options: { access: 'internal' }, validate: { - body: findRulesRequestQuerySchemaV1, + body: findRulesInternalRequestBodySchemaV1, }, }, router.handleLegacyErrors( verifyAccessAndContext(licenseState, async function (context, req, res) { - const rulesClient = (await context.alerting).getRulesClient(); + const rulesClient = await (await context.alerting).getRulesClient(); - const body: FindRulesRequestQueryV1 = req.body; + const body: FindRulesInternalRequestBodyV1 = req.body; trackLegacyTerminology( [req.body.search, req.body.search_fields, req.body.sort_field].filter( @@ -48,7 +48,7 @@ export const findInternalRulesRoute = ( usageCounter ); - const options = transformFindRulesBodyV1({ + const options = transformFindRulesInternalBodyV1({ ...body, has_reference: body.has_reference || undefined, search_fields: searchFieldsAsArray(body.search_fields), diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/find/find_rules_route.test.ts b/x-pack/plugins/alerting/server/routes/rule/apis/find/find_rules_route.test.ts index 0e1f07a5ce543..27769cf237389 100644 --- a/x-pack/plugins/alerting/server/routes/rule/apis/find/find_rules_route.test.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/find/find_rules_route.test.ts @@ -42,6 +42,7 @@ describe('findRulesRoute', () => { expect.any(Function) ); }); + it('finds rules with proper parameters', async () => { const licenseState = licenseStateMock.create(); const router = httpServiceMock.createRouter(); @@ -446,4 +447,138 @@ describe('findRulesRoute', () => { incrementBy: 1, }); }); + + it('should not support rule_type_ids', async () => { + const licenseState = licenseStateMock.create(); + const router = httpServiceMock.createRouter(); + + findRulesRoute(router, licenseState); + + const [config, handler] = router.get.mock.calls[0]; + + expect(config.path).toMatchInlineSnapshot(`"/api/alerting/rules/_find"`); + + const findResult = { + page: 1, + perPage: 1, + total: 0, + data: [], + }; + rulesClient.find.mockResolvedValueOnce(findResult); + + const [context, req, res] = mockHandlerArguments( + { rulesClient }, + { + query: { + per_page: 1, + page: 1, + default_search_operator: 'OR', + rule_type_ids: ['foo'], + }, + }, + ['ok'] + ); + + expect(await handler(context, req, res)).toMatchInlineSnapshot(` + Object { + "body": Object { + "data": Array [], + "page": 1, + "per_page": 1, + "total": 0, + }, + } + `); + + expect(rulesClient.find).toHaveBeenCalledTimes(1); + expect(rulesClient.find.mock.calls[0]).toMatchInlineSnapshot(` + Array [ + Object { + "excludeFromPublicApi": true, + "includeSnoozeData": true, + "options": Object { + "defaultSearchOperator": "OR", + "page": 1, + "perPage": 1, + }, + }, + ] + `); + + expect(res.ok).toHaveBeenCalledWith({ + body: { + page: 1, + per_page: 1, + total: 0, + data: [], + }, + }); + }); + + it('should not support consumers', async () => { + const licenseState = licenseStateMock.create(); + const router = httpServiceMock.createRouter(); + + findRulesRoute(router, licenseState); + + const [config, handler] = router.get.mock.calls[0]; + + expect(config.path).toMatchInlineSnapshot(`"/api/alerting/rules/_find"`); + + const findResult = { + page: 1, + perPage: 1, + total: 0, + data: [], + }; + rulesClient.find.mockResolvedValueOnce(findResult); + + const [context, req, res] = mockHandlerArguments( + { rulesClient }, + { + query: { + per_page: 1, + page: 1, + default_search_operator: 'OR', + consumers: ['foo'], + }, + }, + ['ok'] + ); + + expect(await handler(context, req, res)).toMatchInlineSnapshot(` + Object { + "body": Object { + "data": Array [], + "page": 1, + "per_page": 1, + "total": 0, + }, + } + `); + + expect(rulesClient.find).toHaveBeenCalledTimes(1); + expect(rulesClient.find.mock.calls[0]).toMatchInlineSnapshot(` + Array [ + Object { + "excludeFromPublicApi": true, + "includeSnoozeData": true, + "options": Object { + "defaultSearchOperator": "OR", + "page": 1, + "perPage": 1, + }, + }, + ] + `); + + expect(res.ok).toHaveBeenCalledWith({ + body: { + page: 1, + per_page: 1, + total: 0, + data: [], + }, + }); + }); }); diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/find/find_rules_route.ts b/x-pack/plugins/alerting/server/routes/rule/apis/find/find_rules_route.ts index 90afde8f20813..37ea13c7983e6 100644 --- a/x-pack/plugins/alerting/server/routes/rule/apis/find/find_rules_route.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/find/find_rules_route.ts @@ -52,7 +52,7 @@ export const findRulesRoute = ( }, router.handleLegacyErrors( verifyAccessAndContext(licenseState, async function (context, req, res) { - const rulesClient = (await context.alerting).getRulesClient(); + const rulesClient = await (await context.alerting).getRulesClient(); const query: FindRulesRequestQueryV1 = req.query; diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/find/transforms/index.ts b/x-pack/plugins/alerting/server/routes/rule/apis/find/transforms/index.ts index 044a845f3f8f3..222215ffb9a31 100644 --- a/x-pack/plugins/alerting/server/routes/rule/apis/find/transforms/index.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/find/transforms/index.ts @@ -8,5 +8,8 @@ export { transformFindRulesBody } from './transform_find_rules_body/latest'; export { transformFindRulesResponse } from './transform_find_rules_response/latest'; -export { transformFindRulesBody as transformFindRulesBodyV1 } from './transform_find_rules_body/v1'; +export { + transformFindRulesBody as transformFindRulesBodyV1, + transformFindRulesInternalBody as transformFindRulesInternalBodyV1, +} from './transform_find_rules_body/v1'; export { transformFindRulesResponse as transformFindRulesResponseV1 } from './transform_find_rules_response/v1'; diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/find/transforms/transform_find_rules_body/v1.ts b/x-pack/plugins/alerting/server/routes/rule/apis/find/transforms/transform_find_rules_body/v1.ts index a2f9d3c99b00d..3248c8f45360a 100644 --- a/x-pack/plugins/alerting/server/routes/rule/apis/find/transforms/transform_find_rules_body/v1.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/find/transforms/transform_find_rules_body/v1.ts @@ -5,7 +5,10 @@ * 2.0. */ -import type { FindRulesRequestQueryV1 } from '../../../../../../../common/routes/rule/apis/find'; +import type { + FindRulesInternalRequestBodyV1, + FindRulesRequestQueryV1, +} from '../../../../../../../common/routes/rule/apis/find'; import { FindRulesOptions } from '../../../../../../application/rule/methods/find'; export const transformFindRulesBody = (params: FindRulesRequestQueryV1): FindRulesOptions => { @@ -29,7 +32,42 @@ export const transformFindRulesBody = (params: FindRulesRequestQueryV1): FindRul ...(filter ? { filter } : {}), ...(defaultSearchOperator ? { defaultSearchOperator } : {}), ...(perPage ? { perPage } : {}), - ...(filterConsumers ? { filterConsumers } : {}), + ...(sortField ? { sortField } : {}), + ...(sortOrder ? { sortOrder } : {}), + ...(hasReference ? { hasReference } : {}), + ...(searchFields + ? { searchFields: Array.isArray(searchFields) ? searchFields : [searchFields] } + : {}), + ...(filterConsumers ? { consumers: filterConsumers } : {}), + }; +}; + +export const transformFindRulesInternalBody = ( + params: FindRulesInternalRequestBodyV1 +): FindRulesOptions => { + const { + per_page: perPage, + page, + search, + default_search_operator: defaultSearchOperator, + search_fields: searchFields, + sort_field: sortField, + sort_order: sortOrder, + has_reference: hasReference, + fields, + filter, + rule_type_ids: ruleTypeIds, + consumers, + } = params; + return { + ...(page ? { page } : {}), + ...(search ? { search } : {}), + ...(fields ? { fields } : {}), + ...(filter ? { filter } : {}), + ...(defaultSearchOperator ? { defaultSearchOperator } : {}), + ...(perPage ? { perPage } : {}), + ...(ruleTypeIds ? { ruleTypeIds } : {}), + ...(consumers ? { consumers } : {}), ...(sortField ? { sortField } : {}), ...(sortOrder ? { sortOrder } : {}), ...(hasReference ? { hasReference } : {}), diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/get/get_rule_route.ts b/x-pack/plugins/alerting/server/routes/rule/apis/get/get_rule_route.ts index 0c19d0c9c4f70..46ccc00e33626 100644 --- a/x-pack/plugins/alerting/server/routes/rule/apis/get/get_rule_route.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/get/get_rule_route.ts @@ -64,7 +64,8 @@ const buildGetRuleRoute = ({ }, router.handleLegacyErrors( verifyAccessAndContext(licenseState, async function (context, req, res) { - const rulesClient = (await context.alerting).getRulesClient(); + const alertingContext = await context.alerting; + const rulesClient = await alertingContext.getRulesClient(); const params: GetRuleRequestParamsV1 = req.params; // TODO (http-versioning): Remove this cast, this enables us to move forward diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/get_schedule_frequency/get_schedule_frequency_route.ts b/x-pack/plugins/alerting/server/routes/rule/apis/get_schedule_frequency/get_schedule_frequency_route.ts index e130679a78437..b91c0841df911 100644 --- a/x-pack/plugins/alerting/server/routes/rule/apis/get_schedule_frequency/get_schedule_frequency_route.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/get_schedule_frequency/get_schedule_frequency_route.ts @@ -24,7 +24,8 @@ export const getScheduleFrequencyRoute = ( }, router.handleLegacyErrors( verifyAccessAndContext(licenseState, async (context, req, res) => { - const rulesClient = (await context.alerting).getRulesClient(); + const alertingContext = await context.alerting; + const rulesClient = await alertingContext.getRulesClient(); const scheduleFrequencyResult = await rulesClient.getScheduleFrequency(); diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/list_types/rule_types.test.ts b/x-pack/plugins/alerting/server/routes/rule/apis/list_types/rule_types.test.ts index e6293a589743b..d32df997eb2c3 100644 --- a/x-pack/plugins/alerting/server/routes/rule/apis/list_types/rule_types.test.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/list_types/rule_types.test.ts @@ -97,7 +97,7 @@ describe('ruleTypesRoute', () => { has_fields_for_a_a_d: false, }, ]; - rulesClient.listRuleTypes.mockResolvedValueOnce(new Set(listTypes)); + rulesClient.listRuleTypes.mockResolvedValueOnce(listTypes); const [context, req, res] = mockHandlerArguments({ rulesClient }, {}, ['ok']); @@ -183,7 +183,7 @@ describe('ruleTypesRoute', () => { } as RegistryAlertTypeWithAuth, ]; - rulesClient.listRuleTypes.mockResolvedValueOnce(new Set(listTypes)); + rulesClient.listRuleTypes.mockResolvedValueOnce(listTypes); const [context, req, res] = mockHandlerArguments( { rulesClient }, @@ -240,7 +240,7 @@ describe('ruleTypesRoute', () => { } as RegistryAlertTypeWithAuth, ]; - rulesClient.listRuleTypes.mockResolvedValueOnce(new Set(listTypes)); + rulesClient.listRuleTypes.mockResolvedValueOnce(listTypes); const [context, req, res] = mockHandlerArguments( { rulesClient }, diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/list_types/rule_types.ts b/x-pack/plugins/alerting/server/routes/rule/apis/list_types/rule_types.ts index da9c62ab5f3f2..a49820704d74a 100644 --- a/x-pack/plugins/alerting/server/routes/rule/apis/list_types/rule_types.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/list_types/rule_types.ts @@ -42,7 +42,7 @@ export const ruleTypesRoute = ( }, router.handleLegacyErrors( verifyAccessAndContext(licenseState, async function (context, req, res) { - const rulesClient = (await context.alerting).getRulesClient(); + const rulesClient = await (await context.alerting).getRulesClient(); const ruleTypes = await rulesClient.listRuleTypes(); const responseBody: TypesRulesResponseBodyV1 = transformRuleTypesResponseV1(ruleTypes); diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/list_types/transforms/transform_rule_types_response/v1.ts b/x-pack/plugins/alerting/server/routes/rule/apis/list_types/transforms/transform_rule_types_response/v1.ts index 54a5874331c86..e331fd9133332 100644 --- a/x-pack/plugins/alerting/server/routes/rule/apis/list_types/transforms/transform_rule_types_response/v1.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/list_types/transforms/transform_rule_types_response/v1.ts @@ -10,9 +10,9 @@ import { RegistryAlertTypeWithAuth } from '../../../../../../authorization'; import type { TypesRulesResponseBodyV1 } from '../../../../../../../common/routes/rule/apis/list_types'; export const transformRuleTypesResponse = ( - ruleTypes: Set + ruleTypes: RegistryAlertTypeWithAuth[] ): TypesRulesResponseBodyV1 => { - return Array.from(ruleTypes).map((ruleType: RegistryAlertTypeWithAuth) => { + return ruleTypes.map((ruleType: RegistryAlertTypeWithAuth) => { return { ...(ruleType.actionGroups ? { action_groups: ruleType.actionGroups } : {}), ...(ruleType.actionVariables ? { action_variables: ruleType.actionVariables } : {}), diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/mute_alert/mute_alert.ts b/x-pack/plugins/alerting/server/routes/rule/apis/mute_alert/mute_alert.ts index 5ce924b445ca7..f9b7fa8bfbf0e 100644 --- a/x-pack/plugins/alerting/server/routes/rule/apis/mute_alert/mute_alert.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/mute_alert/mute_alert.ts @@ -48,7 +48,8 @@ export const muteAlertRoute = ( }, router.handleLegacyErrors( verifyAccessAndContext(licenseState, async function (context, req, res) { - const rulesClient = (await context.alerting).getRulesClient(); + const alertingContext = await context.alerting; + const rulesClient = await alertingContext.getRulesClient(); const params: MuteAlertRequestParamsV1 = req.params; try { await rulesClient.muteInstance(transformRequestParamsToApplicationV1(params)); diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/mute_all/mute_all_rule.ts b/x-pack/plugins/alerting/server/routes/rule/apis/mute_all/mute_all_rule.ts index e9aa0e42a046f..46f108cb3a94e 100644 --- a/x-pack/plugins/alerting/server/routes/rule/apis/mute_all/mute_all_rule.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/mute_all/mute_all_rule.ts @@ -51,7 +51,8 @@ export const muteAllRuleRoute = ( }, router.handleLegacyErrors( verifyAccessAndContext(licenseState, async function (context, req, res) { - const rulesClient = (await context.alerting).getRulesClient(); + const alertingContext = await context.alerting; + const rulesClient = await alertingContext.getRulesClient(); const params: MuteAllRuleRequestParamsV1 = req.params; trackDeprecatedRouteUsage('muteAll', usageCounter); try { diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/resolve/resolve_rule_route.ts b/x-pack/plugins/alerting/server/routes/rule/apis/resolve/resolve_rule_route.ts index f67485279edc5..ad0e846d452e5 100644 --- a/x-pack/plugins/alerting/server/routes/rule/apis/resolve/resolve_rule_route.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/resolve/resolve_rule_route.ts @@ -34,7 +34,8 @@ export const resolveRuleRoute = ( }, router.handleLegacyErrors( verifyAccessAndContext(licenseState, async function (context, req, res) { - const rulesClient = (await context.alerting).getRulesClient(); + const alertingContext = await context.alerting; + const rulesClient = await alertingContext.getRulesClient(); const params: ResolveRuleRequestParamsV1 = req.params; const { id } = params; // TODO (http-versioning): Remove this cast, this enables us to move forward diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/snooze/snooze_rule_route.ts b/x-pack/plugins/alerting/server/routes/rule/apis/snooze/snooze_rule_route.ts index 1de46fd784905..3e0e22070d672 100644 --- a/x-pack/plugins/alerting/server/routes/rule/apis/snooze/snooze_rule_route.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/snooze/snooze_rule_route.ts @@ -33,7 +33,8 @@ export const snoozeRuleRoute = ( }, router.handleLegacyErrors( verifyAccessAndContext(licenseState, async function (context, req, res) { - const rulesClient = (await context.alerting).getRulesClient(); + const alertingContext = await context.alerting; + const rulesClient = await alertingContext.getRulesClient(); const params: SnoozeRuleRequestParamsV1 = req.params; const body = transformSnoozeBodyV1(req.body); try { diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/tags/get_rule_tags.ts b/x-pack/plugins/alerting/server/routes/rule/apis/tags/get_rule_tags.ts index c66bf0d61009a..05e4433f5e53d 100644 --- a/x-pack/plugins/alerting/server/routes/rule/apis/tags/get_rule_tags.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/tags/get_rule_tags.ts @@ -29,7 +29,8 @@ export const getRuleTagsRoute = ( }, router.handleLegacyErrors( verifyAccessAndContext(licenseState, async function (context, req, res) { - const rulesClient = (await context.alerting).getRulesClient(); + const alertingContext = await context.alerting; + const rulesClient = await alertingContext.getRulesClient(); const query: RuleTagsRequestQueryV1 = req.query; const options = transformRuleTagsQueryRequestV1(query); diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/unmute_alert/unmute_alert_route.ts b/x-pack/plugins/alerting/server/routes/rule/apis/unmute_alert/unmute_alert_route.ts index 63560e354dc1b..34108b937cc43 100644 --- a/x-pack/plugins/alerting/server/routes/rule/apis/unmute_alert/unmute_alert_route.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/unmute_alert/unmute_alert_route.ts @@ -49,7 +49,7 @@ export const unmuteAlertRoute = ( }, router.handleLegacyErrors( verifyAccessAndContext(licenseState, async function (context, req, res) { - const rulesClient = (await context.alerting).getRulesClient(); + const rulesClient = await (await context.alerting).getRulesClient(); const params: UnmuteAlertRequestParamsV1 = req.params; try { await rulesClient.unmuteInstance(transformRequestParamsToApplicationV1(params)); diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/unmute_all/unmute_all_rule.ts b/x-pack/plugins/alerting/server/routes/rule/apis/unmute_all/unmute_all_rule.ts index 8409128da6241..bf9d1660d0def 100644 --- a/x-pack/plugins/alerting/server/routes/rule/apis/unmute_all/unmute_all_rule.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/unmute_all/unmute_all_rule.ts @@ -48,7 +48,8 @@ export const unmuteAllRuleRoute = ( }, router.handleLegacyErrors( verifyAccessAndContext(licenseState, async function (context, req, res) { - const rulesClient = (await context.alerting).getRulesClient(); + const alertingContext = await context.alerting; + const rulesClient = await alertingContext.getRulesClient(); const params: UnmuteAllRuleRequestParamsV1 = req.params; try { await rulesClient.unmuteAll(params); diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/unsnooze/unsnooze_rule_route.ts b/x-pack/plugins/alerting/server/routes/rule/apis/unsnooze/unsnooze_rule_route.ts index 69e4c91eeaf35..e5f476cbb2038 100644 --- a/x-pack/plugins/alerting/server/routes/rule/apis/unsnooze/unsnooze_rule_route.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/unsnooze/unsnooze_rule_route.ts @@ -33,7 +33,8 @@ export const unsnoozeRuleRoute = ( }, router.handleLegacyErrors( verifyAccessAndContext(licenseState, async function (context, req, res) { - const rulesClient = (await context.alerting).getRulesClient(); + const alertingContext = await context.alerting; + const rulesClient = await alertingContext.getRulesClient(); const params: UnsnoozeRuleRequestParamsV1 = req.params; const body = transformUnsnoozeBodyV1(req.body); try { diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/update/update_rule_route.ts b/x-pack/plugins/alerting/server/routes/rule/apis/update/update_rule_route.ts index 5c925b05bace3..8fee470cb3bd7 100644 --- a/x-pack/plugins/alerting/server/routes/rule/apis/update/update_rule_route.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/update/update_rule_route.ts @@ -64,7 +64,8 @@ export const updateRuleRoute = ( handleDisabledApiKeysError( router.handleLegacyErrors( verifyAccessAndContext(licenseState, async function (context, req, res) { - const rulesClient = (await context.alerting).getRulesClient(); + const alertingContext = await context.alerting; + const rulesClient = await alertingContext.getRulesClient(); const actionsClient = (await context.actions).getActionsClient(); const rulesSettingsClient = (await context.alerting).getRulesSettingsClient(true); diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/update_api_key/update_rule_api_key_route.ts b/x-pack/plugins/alerting/server/routes/rule/apis/update_api_key/update_rule_api_key_route.ts index 7ba8589412357..4f16d873dfaa8 100644 --- a/x-pack/plugins/alerting/server/routes/rule/apis/update_api_key/update_rule_api_key_route.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/update_api_key/update_rule_api_key_route.ts @@ -51,7 +51,7 @@ export const updateRuleApiKeyRoute = ( }, router.handleLegacyErrors( verifyAccessAndContext(licenseState, async function (context, req, res) { - const rulesClient = (await context.alerting).getRulesClient(); + const rulesClient = await (await context.alerting).getRulesClient(); const { id }: UpdateApiKeyParamsV1 = req.params; try { diff --git a/x-pack/plugins/alerting/server/routes/run_soon.ts b/x-pack/plugins/alerting/server/routes/run_soon.ts index 589724ab57b06..1b7fa271c9587 100644 --- a/x-pack/plugins/alerting/server/routes/run_soon.ts +++ b/x-pack/plugins/alerting/server/routes/run_soon.ts @@ -31,7 +31,8 @@ export const runSoonRoute = ( }, router.handleLegacyErrors( verifyAccessAndContext(licenseState, async function (context, req, res) { - const rulesClient = (await context.alerting).getRulesClient(); + const alertingContext = await context.alerting; + const rulesClient = await alertingContext.getRulesClient(); const message = await rulesClient.runSoon(req.params); return message ? res.ok({ body: message }) : res.noContent(); }) diff --git a/x-pack/plugins/alerting/server/routes/suggestions/values_suggestion_alerts.ts b/x-pack/plugins/alerting/server/routes/suggestions/values_suggestion_alerts.ts index f39615efa7e8d..25dc8add03abf 100644 --- a/x-pack/plugins/alerting/server/routes/suggestions/values_suggestion_alerts.ts +++ b/x-pack/plugins/alerting/server/routes/suggestions/values_suggestion_alerts.ts @@ -11,15 +11,9 @@ import { firstValueFrom, Observable } from 'rxjs'; import { getRequestAbortedSignal } from '@kbn/data-plugin/server'; import { termsAggSuggestions } from '@kbn/unified-search-plugin/server/autocomplete/terms_agg'; import type { ConfigSchema } from '@kbn/unified-search-plugin/server/config'; -import { UsageCounter } from '@kbn/usage-collection-plugin/server'; import { getKbnServerError, reportServerError } from '@kbn/kibana-utils-plugin/server'; import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; -import { - AlertConsumers, - ALERT_RULE_CONSUMER, - ALERT_RULE_TYPE_ID, - SPACE_IDS, -} from '@kbn/rule-data-utils'; +import { ALERT_RULE_CONSUMER, ALERT_RULE_TYPE_ID, SPACE_IDS } from '@kbn/rule-data-utils'; import { verifyAccessAndContext } from '../lib'; import { RuleAuditAction, ruleAuditEvent } from '../../rules_client/common/audit_events'; @@ -27,6 +21,7 @@ import { AlertingAuthorizationEntity, AlertingAuthorizationFilterOpts, AlertingAuthorizationFilterType, + AuthorizedRuleTypes, } from '../../authorization'; import { AlertingRequestHandlerContext } from '../../types'; import { GetAlertIndicesAlias, ILicenseState } from '../../lib'; @@ -45,20 +40,11 @@ export const AlertsSuggestionsSchema = { }), }; -const VALID_FEATURE_IDS = new Set([ - AlertConsumers.APM, - AlertConsumers.INFRASTRUCTURE, - AlertConsumers.LOGS, - AlertConsumers.SLO, - AlertConsumers.UPTIME, -]); - export function registerAlertsValueSuggestionsRoute( router: IRouter, licenseState: ILicenseState, config$: Observable, - getAlertIndicesAlias?: GetAlertIndicesAlias, - usageCounter?: UsageCounter + getAlertIndicesAlias?: GetAlertIndicesAlias ) { router.post( { @@ -73,19 +59,21 @@ export function registerAlertsValueSuggestionsRoute( const abortSignal = getRequestAbortedSignal(request.events.aborted$); const { savedObjects, elasticsearch } = await context.core; - const rulesClient = (await context.alerting).getRulesClient(); + const alertingContext = await context.alerting; + const rulesClient = await alertingContext.getRulesClient(); let authorizationTuple; - let authorizedRuleType = []; + let authorizedRuleType: AuthorizedRuleTypes = new Map(); + try { const authorization = rulesClient.getAuthorization(); - authorizationTuple = await authorization.getFindAuthorizationFilter( - AlertingAuthorizationEntity.Alert, - alertingAuthorizationFilterOpts - ); - authorizedRuleType = await authorization.getAuthorizedRuleTypes( - AlertingAuthorizationEntity.Alert, - VALID_FEATURE_IDS - ); + authorizationTuple = await authorization.getFindAuthorizationFilter({ + authorizationEntity: AlertingAuthorizationEntity.Alert, + filterOpts: alertingAuthorizationFilterOpts, + }); + + authorizedRuleType = await authorization.getAllAuthorizedRuleTypesFindOperation({ + authorizationEntity: AlertingAuthorizationEntity.Alert, + }); } catch (error) { rulesClient.getAuditLogger()?.log( ruleAuditEvent({ @@ -93,8 +81,10 @@ export function registerAlertsValueSuggestionsRoute( error, }) ); + throw error; } + const spaceId = rulesClient.getSpaceId(); const { filter: authorizationFilter } = authorizationTuple; const filters = [ @@ -103,9 +93,10 @@ export function registerAlertsValueSuggestionsRoute( ] as estypes.QueryDslQueryContainer[]; const index = getAlertIndicesAlias!( - authorizedRuleType.map((art) => art.id), + Array.from(authorizedRuleType.keys()).map((id) => id), spaceId ).join(','); + try { const body = await termsAggSuggestions( config, diff --git a/x-pack/plugins/alerting/server/routes/suggestions/values_suggestion_rules.ts b/x-pack/plugins/alerting/server/routes/suggestions/values_suggestion_rules.ts index 6ada2378b3096..420d6473988fa 100644 --- a/x-pack/plugins/alerting/server/routes/suggestions/values_suggestion_rules.ts +++ b/x-pack/plugins/alerting/server/routes/suggestions/values_suggestion_rules.ts @@ -59,15 +59,14 @@ export function registerRulesValueSuggestionsRoute( const abortSignal = getRequestAbortedSignal(request.events.aborted$); const { savedObjects, elasticsearch } = await context.core; - const rulesClient = (await context.alerting).getRulesClient(); + const alertingContext = await context.alerting; + const rulesClient = await alertingContext.getRulesClient(); let authorizationTuple; try { - authorizationTuple = await rulesClient - .getAuthorization() - .getFindAuthorizationFilter( - AlertingAuthorizationEntity.Rule, - alertingAuthorizationFilterOpts - ); + authorizationTuple = await rulesClient.getAuthorization().getFindAuthorizationFilter({ + authorizationEntity: AlertingAuthorizationEntity.Rule, + filterOpts: alertingAuthorizationFilterOpts, + }); } catch (error) { rulesClient.getAuditLogger()?.log( ruleAuditEvent({ 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 e678228660e51..d9d7c1240922c 100644 --- a/x-pack/plugins/alerting/server/rule_type_registry.test.ts +++ b/x-pack/plugins/alerting/server/rule_type_registry.test.ts @@ -856,7 +856,7 @@ describe('Create Lifecycle', () => { test('should return empty when nothing is registered', () => { const registry = new RuleTypeRegistry(ruleTypeRegistryParams); const result = registry.list(); - expect(result).toMatchInlineSnapshot(`Set {}`); + expect(result).toMatchInlineSnapshot(`Map {}`); }); test('should return registered types', () => { @@ -888,8 +888,8 @@ describe('Create Lifecycle', () => { }); const result = registry.list(); expect(result).toMatchInlineSnapshot(` - Set { - Object { + Map { + "test" => Object { "actionGroups": Array [ Object { "id": "testActionGroup", diff --git a/x-pack/plugins/alerting/server/rule_type_registry.ts b/x-pack/plugins/alerting/server/rule_type_registry.ts index 7562942f0262d..40d00acbef598 100644 --- a/x-pack/plugins/alerting/server/rule_type_registry.ts +++ b/x-pack/plugins/alerting/server/rule_type_registry.ts @@ -382,59 +382,40 @@ export class RuleTypeRegistry { >; } - public list(): Set { - const mapRuleTypes: Array<[string, UntypedNormalizedRuleType]> = Array.from(this.ruleTypes); - const tempRegistryRuleType = mapRuleTypes.map( - ([ - id, - { - name, - actionGroups, - recoveryActionGroup, - defaultActionGroupId, - actionVariables, - category, - producer, - minimumLicenseRequired, - isExportable, - ruleTaskTimeout, - defaultScheduleInterval, - doesSetRecoveryContext, - alerts, - fieldsForAAD, - validLegacyConsumers, - }, - ]) => { - // KEEP the type here to be safe if not the map is ignoring it for some reason - const ruleType: RegistryRuleType = { - id, - name, - actionGroups, - recoveryActionGroup, - defaultActionGroupId, - actionVariables, - category, - producer, - minimumLicenseRequired, - isExportable, - ruleTaskTimeout, - defaultScheduleInterval, - doesSetRecoveryContext, - enabledInLicense: !!this.licenseState.getLicenseCheckForRuleType( - id, - name, - minimumLicenseRequired - ).isValid, - fieldsForAAD, - hasFieldsForAAD: Boolean(fieldsForAAD), - hasAlertsMappings: !!alerts, - validLegacyConsumers, - ...(alerts ? { alerts } : {}), - }; - return ruleType; - } - ); - return new Set(tempRegistryRuleType); + public list(): Map { + const ruleTypesMap = new Map(); + + this.ruleTypes.forEach((_ruleType) => { + const ruleType: RegistryRuleType = { + id: _ruleType.id, + name: _ruleType.name, + actionGroups: _ruleType.actionGroups, + recoveryActionGroup: _ruleType.recoveryActionGroup, + defaultActionGroupId: _ruleType.defaultActionGroupId, + actionVariables: _ruleType.actionVariables, + category: _ruleType.category, + producer: _ruleType.producer, + minimumLicenseRequired: _ruleType.minimumLicenseRequired, + isExportable: _ruleType.isExportable, + ruleTaskTimeout: _ruleType.ruleTaskTimeout, + defaultScheduleInterval: _ruleType.defaultScheduleInterval, + doesSetRecoveryContext: _ruleType.doesSetRecoveryContext, + enabledInLicense: !!this.licenseState.getLicenseCheckForRuleType( + _ruleType.id, + _ruleType.name, + _ruleType.minimumLicenseRequired + ).isValid, + fieldsForAAD: _ruleType.fieldsForAAD, + hasFieldsForAAD: Boolean(_ruleType.fieldsForAAD), + hasAlertsMappings: !!_ruleType.alerts, + ...(_ruleType.alerts ? { alerts: _ruleType.alerts } : {}), + validLegacyConsumers: _ruleType.validLegacyConsumers, + }; + + ruleTypesMap.set(ruleType.id, ruleType); + }); + + return ruleTypesMap; } public getAllTypes(): string[] { diff --git a/x-pack/plugins/alerting/server/rules_client.mock.ts b/x-pack/plugins/alerting/server/rules_client.mock.ts index 0616591cbe565..c7577656306d0 100644 --- a/x-pack/plugins/alerting/server/rules_client.mock.ts +++ b/x-pack/plugins/alerting/server/rules_client.mock.ts @@ -5,12 +5,15 @@ * 2.0. */ +import { alertingAuthorizationMock } from './authorization/alerting_authorization.mock'; import { RulesClientApi } from './types'; type Schema = RulesClientApi; export type RulesClientMock = jest.Mocked; const createRulesClientMock = () => { + const alertingAuthorization = alertingAuthorizationMock.create(); + const mocked: RulesClientMock = { aggregate: jest.fn().mockReturnValue({ ruleExecutionStatus: {}, ruleLastRunOutcome: {} }), getTags: jest.fn(), @@ -31,10 +34,7 @@ const createRulesClientMock = () => { listRuleTypes: jest.fn(), getAlertSummary: jest.fn(), getAuditLogger: jest.fn(), - getAuthorization: jest.fn().mockImplementation(() => ({ - getFindAuthorizationFilter: jest.fn().mockReturnValue({ filter: null }), - getAuthorizedRuleTypes: jest.fn().mockResolvedValue([]), - })), + getAuthorization: jest.fn().mockReturnValue(alertingAuthorization), getExecutionLogForRule: jest.fn(), getRuleExecutionKPI: jest.fn(), getGlobalExecutionKpiWithAuth: jest.fn(), diff --git a/x-pack/plugins/alerting/server/rules_client/common/filters.test.ts b/x-pack/plugins/alerting/server/rules_client/common/filters.test.ts new file mode 100644 index 0000000000000..fc14cb19bb803 --- /dev/null +++ b/x-pack/plugins/alerting/server/rules_client/common/filters.test.ts @@ -0,0 +1,463 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor 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 { nodeBuilder } from '@kbn/es-query'; +import { + buildConsumersFilter, + buildFilter, + buildRuleTypeIdsFilter, + combineFilterWithAuthorizationFilter, + combineFilters, +} from './filters'; + +describe('filters', () => { + describe('combineFilterWithAuthorizationFilter', () => { + it('returns undefined if neither a filter or authorizationFilter are passed', () => { + expect(combineFilterWithAuthorizationFilter()).toBeUndefined(); + }); + + it('returns a single KueryNode when only a filter is passed in', () => { + const node = nodeBuilder.is('a', 'hello'); + expect(combineFilterWithAuthorizationFilter(node)).toMatchInlineSnapshot(` + Object { + "arguments": Array [ + Object { + "isQuoted": false, + "type": "literal", + "value": "a", + }, + Object { + "isQuoted": false, + "type": "literal", + "value": "hello", + }, + ], + "function": "is", + "type": "function", + } + `); + }); + + it('returns a single KueryNode when only an authorizationFilter is passed in', () => { + const node = nodeBuilder.is('a', 'hello'); + expect(combineFilterWithAuthorizationFilter(undefined, node)).toMatchInlineSnapshot(` + Object { + "arguments": Array [ + Object { + "isQuoted": false, + "type": "literal", + "value": "a", + }, + Object { + "isQuoted": false, + "type": "literal", + "value": "hello", + }, + ], + "function": "is", + "type": "function", + } + `); + }); + + it("returns a single KueryNode and'ing together the passed in parameters", () => { + const node = nodeBuilder.is('a', 'hello'); + const node2 = nodeBuilder.is('b', 'hi'); + + expect(combineFilterWithAuthorizationFilter(node, node2)).toMatchInlineSnapshot(` + Object { + "arguments": Array [ + Object { + "arguments": Array [ + Object { + "isQuoted": false, + "type": "literal", + "value": "a", + }, + Object { + "isQuoted": false, + "type": "literal", + "value": "hello", + }, + ], + "function": "is", + "type": "function", + }, + Object { + "arguments": Array [ + Object { + "isQuoted": false, + "type": "literal", + "value": "b", + }, + Object { + "isQuoted": false, + "type": "literal", + "value": "hi", + }, + ], + "function": "is", + "type": "function", + }, + ], + "function": "and", + "type": "function", + } + `); + }); + + it("returns a single KueryNode and'ing together the passed in parameters in opposite order", () => { + const node = nodeBuilder.is('a', 'hello'); + const node2 = nodeBuilder.is('b', 'hi'); + + expect(combineFilterWithAuthorizationFilter(node2, node)).toMatchInlineSnapshot(` + Object { + "arguments": Array [ + Object { + "arguments": Array [ + Object { + "isQuoted": false, + "type": "literal", + "value": "b", + }, + Object { + "isQuoted": false, + "type": "literal", + "value": "hi", + }, + ], + "function": "is", + "type": "function", + }, + Object { + "arguments": Array [ + Object { + "isQuoted": false, + "type": "literal", + "value": "a", + }, + Object { + "isQuoted": false, + "type": "literal", + "value": "hello", + }, + ], + "function": "is", + "type": "function", + }, + ], + "function": "and", + "type": "function", + } + `); + }); + }); + + describe('buildFilter', () => { + it('returns undefined if filters is undefined', () => { + expect(buildFilter({ filters: undefined, field: 'abc', operator: 'or' })).toBeUndefined(); + }); + + it('returns undefined if filters is is an empty array', () => { + expect(buildFilter({ filters: [], field: 'abc', operator: 'or' })).toBeUndefined(); + }); + + it('returns a KueryNode using or operator', () => { + expect(buildFilter({ filters: ['value1'], field: 'abc', operator: 'or' })) + .toMatchInlineSnapshot(` + Object { + "arguments": Array [ + Object { + "isQuoted": false, + "type": "literal", + "value": "alert.attributes.abc", + }, + Object { + "isQuoted": false, + "type": "literal", + "value": "value1", + }, + ], + "function": "is", + "type": "function", + } + `); + }); + + it("returns multiple nodes or'd together", () => { + expect(buildFilter({ filters: ['value1', 'value2'], field: 'abc', operator: 'or' })) + .toMatchInlineSnapshot(` + Object { + "arguments": Array [ + Object { + "arguments": Array [ + Object { + "isQuoted": false, + "type": "literal", + "value": "alert.attributes.abc", + }, + Object { + "isQuoted": false, + "type": "literal", + "value": "value1", + }, + ], + "function": "is", + "type": "function", + }, + Object { + "arguments": Array [ + Object { + "isQuoted": false, + "type": "literal", + "value": "alert.attributes.abc", + }, + Object { + "isQuoted": false, + "type": "literal", + "value": "value2", + }, + ], + "function": "is", + "type": "function", + }, + ], + "function": "or", + "type": "function", + } + `); + }); + + it('does not escape special kql characters in the filter values', () => { + const specialCharacters = 'awesome:()\\<>"*'; + + expect(buildFilter({ filters: [specialCharacters], field: 'abc', operator: 'or' })) + .toMatchInlineSnapshot(` + Object { + "arguments": Array [ + Object { + "isQuoted": false, + "type": "literal", + "value": "alert.attributes.abc", + }, + Object { + "isQuoted": false, + "type": "literal", + "value": "awesome:()\\\\<>\\"*", + }, + ], + "function": "is", + "type": "function", + } + `); + }); + }); + + describe('combineFilters', () => { + it('returns undefined if the nodes are undefined or null', () => { + expect(combineFilters([null, undefined])).toBeUndefined(); + }); + + it('combines the filters correctly', () => { + const node = nodeBuilder.is('a', 'hello'); + const node2 = nodeBuilder.is('b', 'hi'); + + expect(combineFilters([node, null, undefined, node2])).toMatchInlineSnapshot(` + Object { + "arguments": Array [ + Object { + "arguments": Array [ + Object { + "isQuoted": false, + "type": "literal", + "value": "a", + }, + Object { + "isQuoted": false, + "type": "literal", + "value": "hello", + }, + ], + "function": "is", + "type": "function", + }, + Object { + "arguments": Array [ + Object { + "isQuoted": false, + "type": "literal", + "value": "b", + }, + Object { + "isQuoted": false, + "type": "literal", + "value": "hi", + }, + ], + "function": "is", + "type": "function", + }, + ], + "function": "and", + "type": "function", + } + `); + }); + + it('combines the filters correctly with an operator', () => { + const node = nodeBuilder.is('a', 'hello'); + const node2 = nodeBuilder.is('b', 'hi'); + + expect(combineFilters([node, null, undefined, node2], 'or')).toMatchInlineSnapshot(` + Object { + "arguments": Array [ + Object { + "arguments": Array [ + Object { + "isQuoted": false, + "type": "literal", + "value": "a", + }, + Object { + "isQuoted": false, + "type": "literal", + "value": "hello", + }, + ], + "function": "is", + "type": "function", + }, + Object { + "arguments": Array [ + Object { + "isQuoted": false, + "type": "literal", + "value": "b", + }, + Object { + "isQuoted": false, + "type": "literal", + "value": "hi", + }, + ], + "function": "is", + "type": "function", + }, + ], + "function": "or", + "type": "function", + } + `); + }); + }); + + describe('buildRuleTypeIdsFilter', () => { + it('returns undefined if ruleTypeIds is undefined', () => { + expect(buildRuleTypeIdsFilter()).toBeUndefined(); + }); + + it('returns undefined if ruleTypeIds is is an empty array', () => { + expect(buildRuleTypeIdsFilter([])).toBeUndefined(); + }); + + it('builds the filter correctly', () => { + expect(buildRuleTypeIdsFilter(['foo', 'bar'])).toMatchInlineSnapshot(` + Object { + "arguments": Array [ + Object { + "arguments": Array [ + Object { + "isQuoted": false, + "type": "literal", + "value": "alert.attributes.alertTypeId", + }, + Object { + "isQuoted": false, + "type": "literal", + "value": "foo", + }, + ], + "function": "is", + "type": "function", + }, + Object { + "arguments": Array [ + Object { + "isQuoted": false, + "type": "literal", + "value": "alert.attributes.alertTypeId", + }, + Object { + "isQuoted": false, + "type": "literal", + "value": "bar", + }, + ], + "function": "is", + "type": "function", + }, + ], + "function": "or", + "type": "function", + } + `); + }); + }); + + describe('buildConsumersFilter', () => { + it('returns undefined if ruleTypeIds is undefined', () => { + expect(buildConsumersFilter()).toBeUndefined(); + }); + + it('returns undefined if ruleTypeIds is is an empty array', () => { + expect(buildConsumersFilter([])).toBeUndefined(); + }); + + it('builds the filter correctly', () => { + expect(buildConsumersFilter(['foo', 'bar'])).toMatchInlineSnapshot(` + Object { + "arguments": Array [ + Object { + "arguments": Array [ + Object { + "isQuoted": false, + "type": "literal", + "value": "alert.attributes.consumer", + }, + Object { + "isQuoted": false, + "type": "literal", + "value": "foo", + }, + ], + "function": "is", + "type": "function", + }, + Object { + "arguments": Array [ + Object { + "isQuoted": false, + "type": "literal", + "value": "alert.attributes.consumer", + }, + Object { + "isQuoted": false, + "type": "literal", + "value": "bar", + }, + ], + "function": "is", + "type": "function", + }, + ], + "function": "or", + "type": "function", + } + `); + }); + }); +}); diff --git a/x-pack/plugins/alerting/server/rules_client/common/filters.ts b/x-pack/plugins/alerting/server/rules_client/common/filters.ts new file mode 100644 index 0000000000000..b0c3ccc5e1ec1 --- /dev/null +++ b/x-pack/plugins/alerting/server/rules_client/common/filters.ts @@ -0,0 +1,92 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor 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 { KueryNode, nodeBuilder } from '@kbn/es-query'; +import { RULE_SAVED_OBJECT_TYPE } from '../..'; + +export const NodeBuilderOperators = { + and: 'and', + or: 'or', +} as const; + +type NodeBuilderOperatorsType = keyof typeof NodeBuilderOperators; + +interface FilterField { + filters?: string | string[]; + field: string; + operator: NodeBuilderOperatorsType; + type?: string; +} + +export const buildFilter = ({ + filters, + field, + operator, + type = RULE_SAVED_OBJECT_TYPE, +}: FilterField): KueryNode | undefined => { + if (filters === undefined) { + return; + } + + const filtersAsArray = Array.isArray(filters) ? filters : [filters]; + + if (filtersAsArray.length === 0) { + return; + } + + return nodeBuilder[operator]( + filtersAsArray.map((filter) => nodeBuilder.is(`${type}.attributes.${field}`, filter)) + ); +}; + +export const buildRuleTypeIdsFilter = (ruleTypeIds?: string[]) => { + if (!ruleTypeIds || !ruleTypeIds?.length) { + return; + } + + return buildFilter({ filters: ruleTypeIds, field: 'alertTypeId', operator: 'or' }); +}; + +export const buildConsumersFilter = (consumers?: string[]) => { + if (!consumers || !consumers?.length) { + return; + } + + return buildFilter({ filters: consumers, field: 'consumer', operator: 'or' }); +}; + +/** + * Combines Kuery nodes and accepts an array with a mixture of undefined and KueryNodes. This will filter out the undefined + * filters and return a KueryNode with the filters combined using the specified operator which defaults to and if not defined. + */ +export function combineFilters( + nodes: Array, + operator: NodeBuilderOperatorsType = NodeBuilderOperators.and +): KueryNode | undefined { + const filters = nodes.filter(Boolean) as KueryNode[]; + + if (filters.length <= 0) { + return; + } + + return nodeBuilder[operator](filters); +} + +export const combineFilterWithAuthorizationFilter = ( + filter?: KueryNode, + authorizationFilter?: KueryNode +) => { + if (!filter && !authorizationFilter) { + return; + } + + const kueries = [ + ...(filter !== undefined ? [filter] : []), + ...(authorizationFilter !== undefined ? [authorizationFilter] : []), + ]; + return nodeBuilder.and(kueries); +}; diff --git a/x-pack/plugins/alerting/server/rules_client/lib/get_authorization_filter.ts b/x-pack/plugins/alerting/server/rules_client/lib/get_authorization_filter.ts index b9cc41a0fd7c4..591602effc474 100644 --- a/x-pack/plugins/alerting/server/rules_client/lib/get_authorization_filter.ts +++ b/x-pack/plugins/alerting/server/rules_client/lib/get_authorization_filter.ts @@ -6,11 +6,11 @@ */ import { withSpan } from '@kbn/apm-utils'; -import { AlertingAuthorizationEntity } from '../../authorization'; import { ruleAuditEvent, RuleAuditAction } from '../common/audit_events'; import { RulesClientContext } from '../types'; import { alertingAuthorizationFilterOpts } from '../common/constants'; import { BulkAction } from '../types'; +import { AlertingAuthorizationEntity } from '../../authorization/types'; export const getAuthorizationFilter = async ( context: RulesClientContext, @@ -20,10 +20,10 @@ export const getAuthorizationFilter = async ( const authorizationTuple = await withSpan( { name: 'authorization.getFindAuthorizationFilter', type: 'rules' }, () => - context.authorization.getFindAuthorizationFilter( - AlertingAuthorizationEntity.Rule, - alertingAuthorizationFilterOpts - ) + context.authorization.getFindAuthorizationFilter({ + authorizationEntity: AlertingAuthorizationEntity.Rule, + filterOpts: alertingAuthorizationFilterOpts, + }) ); return authorizationTuple.filter; } catch (error) { diff --git a/x-pack/plugins/alerting/server/rules_client/methods/get_action_error_log.ts b/x-pack/plugins/alerting/server/rules_client/methods/get_action_error_log.ts index a7d60fc8f8ca4..4d71af6573b57 100644 --- a/x-pack/plugins/alerting/server/rules_client/methods/get_action_error_log.ts +++ b/x-pack/plugins/alerting/server/rules_client/methods/get_action_error_log.ts @@ -108,16 +108,16 @@ export async function getActionErrorLogWithAuth( let authorizationTuple; try { - authorizationTuple = await context.authorization.getFindAuthorizationFilter( - AlertingAuthorizationEntity.Alert, - { + authorizationTuple = await context.authorization.getFindAuthorizationFilter({ + authorizationEntity: AlertingAuthorizationEntity.Alert, + filterOpts: { type: AlertingAuthorizationFilterType.KQL, fieldNames: { ruleTypeId: 'kibana.alert.rule.rule_type_id', consumer: 'kibana.alert.rule.consumer', }, - } - ); + }, + }); } catch (error) { context.auditLogger?.log( ruleAuditEvent({ diff --git a/x-pack/plugins/alerting/server/rules_client/methods/get_execution_kpi.ts b/x-pack/plugins/alerting/server/rules_client/methods/get_execution_kpi.ts index fc2c1298f69ac..4441cc69a5f72 100644 --- a/x-pack/plugins/alerting/server/rules_client/methods/get_execution_kpi.ts +++ b/x-pack/plugins/alerting/server/rules_client/methods/get_execution_kpi.ts @@ -105,16 +105,16 @@ export async function getGlobalExecutionKpiWithAuth( let authorizationTuple; try { - authorizationTuple = await context.authorization.getFindAuthorizationFilter( - AlertingAuthorizationEntity.Alert, - { + authorizationTuple = await context.authorization.getFindAuthorizationFilter({ + authorizationEntity: AlertingAuthorizationEntity.Alert, + filterOpts: { type: AlertingAuthorizationFilterType.KQL, fieldNames: { ruleTypeId: 'kibana.alert.rule.rule_type_id', consumer: 'kibana.alert.rule.consumer', }, - } - ); + }, + }); } catch (error) { context.auditLogger?.log( ruleAuditEvent({ diff --git a/x-pack/plugins/alerting/server/rules_client/methods/get_execution_log.ts b/x-pack/plugins/alerting/server/rules_client/methods/get_execution_log.ts index 18d65c28fc9bb..95d41a02a685b 100644 --- a/x-pack/plugins/alerting/server/rules_client/methods/get_execution_log.ts +++ b/x-pack/plugins/alerting/server/rules_client/methods/get_execution_log.ts @@ -118,16 +118,16 @@ export async function getGlobalExecutionLogWithAuth( let authorizationTuple; try { - authorizationTuple = await context.authorization.getFindAuthorizationFilter( - AlertingAuthorizationEntity.Alert, - { + authorizationTuple = await context.authorization.getFindAuthorizationFilter({ + authorizationEntity: AlertingAuthorizationEntity.Alert, + filterOpts: { type: AlertingAuthorizationFilterType.KQL, fieldNames: { ruleTypeId: 'kibana.alert.rule.rule_type_id', consumer: 'kibana.alert.rule.consumer', }, - } - ); + }, + }); } catch (error) { context.auditLogger?.log( ruleAuditEvent({ diff --git a/x-pack/plugins/alerting/server/rules_client/rules_client.mock.ts b/x-pack/plugins/alerting/server/rules_client/rules_client.mock.ts new file mode 100644 index 0000000000000..f8e2beba7ee67 --- /dev/null +++ b/x-pack/plugins/alerting/server/rules_client/rules_client.mock.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 { ActionsAuthorization } from '@kbn/actions-plugin/server'; +import { loggingSystemMock } from '@kbn/core-logging-server-mocks'; +import { uiSettingsServiceMock } from '@kbn/core-ui-settings-server-mocks'; +import { AlertingAuthorization } from '../authorization'; +import { ConnectorAdapterRegistry } from '../connector_adapters/connector_adapter_registry'; +import type { ConstructorOptions } from './rules_client'; +import { actionsAuthorizationMock } from '@kbn/actions-plugin/server/mocks'; +import { + savedObjectsClientMock, + savedObjectsRepositoryMock, +} from '@kbn/core-saved-objects-api-server-mocks'; +import { auditLoggerMock } from '@kbn/core-security-server-mocks'; +import { encryptedSavedObjectsMock } from '@kbn/encrypted-saved-objects-plugin/server/mocks'; +import { taskManagerMock } from '@kbn/task-manager-plugin/server/mocks'; +import { alertingAuthorizationMock } from '../authorization/alerting_authorization.mock'; +import { backfillClientMock } from '../backfill_client/backfill_client.mock'; +import { ruleTypeRegistryMock } from '../rule_type_registry.mock'; + +const create = () => { + const kibanaVersion = 'v8.17.0'; + const taskManager = taskManagerMock.createStart(); + const ruleTypeRegistry = ruleTypeRegistryMock.create(); + const unsecuredSavedObjectsClient = savedObjectsClientMock.create(); + const encryptedSavedObjects = encryptedSavedObjectsMock.createClient(); + const authorization = alertingAuthorizationMock.create(); + const actionsAuthorization = actionsAuthorizationMock.create(); + const auditLogger = auditLoggerMock.create(); + const internalSavedObjectsRepository = savedObjectsRepositoryMock.create(); + const backfillClient = backfillClientMock.create(); + + const rulesClientParams: jest.Mocked = { + taskManager, + ruleTypeRegistry, + unsecuredSavedObjectsClient, + authorization: authorization as unknown as AlertingAuthorization, + actionsAuthorization: actionsAuthorization as unknown as ActionsAuthorization, + spaceId: 'default', + namespace: 'default', + getUserName: jest.fn(), + createAPIKey: jest.fn(), + logger: loggingSystemMock.create().get(), + internalSavedObjectsRepository, + encryptedSavedObjectsClient: encryptedSavedObjects, + getActionsClient: jest.fn(), + getEventLogClient: jest.fn(), + kibanaVersion, + auditLogger, + maxScheduledPerMinute: 10000, + minimumScheduleInterval: { value: '1m', enforce: false }, + isAuthenticationTypeAPIKey: jest.fn(), + getAuthenticationAPIKey: jest.fn(), + getAlertIndicesAlias: jest.fn(), + alertsService: null, + backfillClient, + isSystemAction: jest.fn(), + connectorAdapterRegistry: new ConnectorAdapterRegistry(), + uiSettings: uiSettingsServiceMock.createStartContract(), + }; + + return rulesClientParams; +}; + +export const rulesClientContextMock = { create }; diff --git a/x-pack/plugins/alerting/server/rules_client/tests/list_rule_types.test.ts b/x-pack/plugins/alerting/server/rules_client/tests/list_rule_types.test.ts index b096ec1c75f7d..7205decb32bb5 100644 --- a/x-pack/plugins/alerting/server/rules_client/tests/list_rule_types.test.ts +++ b/x-pack/plugins/alerting/server/rules_client/tests/list_rule_types.test.ts @@ -17,10 +17,7 @@ import { ruleTypeRegistryMock } from '../../rule_type_registry.mock'; import { alertingAuthorizationMock } from '../../authorization/alerting_authorization.mock'; import { encryptedSavedObjectsMock } from '@kbn/encrypted-saved-objects-plugin/server/mocks'; import { actionsAuthorizationMock } from '@kbn/actions-plugin/server/mocks'; -import { - AlertingAuthorization, - RegistryAlertTypeWithAuth, -} from '../../authorization/alerting_authorization'; +import { AlertingAuthorization } from '../../authorization/alerting_authorization'; import { ActionsAuthorization } from '@kbn/actions-plugin/server'; import { getBeforeSetup } from './lib'; import { RecoveredActionGroup } from '../../../common'; @@ -88,6 +85,7 @@ describe('listRuleTypes', () => { hasFieldsForAAD: false, validLegacyConsumers: [], }; + const myAppAlertType: RegistryRuleType = { actionGroups: [], actionVariables: undefined, @@ -104,7 +102,11 @@ describe('listRuleTypes', () => { hasFieldsForAAD: false, validLegacyConsumers: [], }; - const setOfAlertTypes = new Set([myAppAlertType, alertingAlertType]); + + const setOfAlertTypes = new Map([ + [myAppAlertType.id, myAppAlertType], + [alertingAlertType.id, alertingAlertType], + ]); const authorizedConsumers = { alerts: { read: true, all: true }, @@ -118,62 +120,162 @@ describe('listRuleTypes', () => { test('should return a list of AlertTypes that exist in the registry', async () => { ruleTypeRegistry.list.mockReturnValue(setOfAlertTypes); - authorization.filterByRuleTypeAuthorization.mockResolvedValue( - new Set([ - { ...myAppAlertType, authorizedConsumers }, - { ...alertingAlertType, authorizedConsumers }, + ruleTypeRegistry.has.mockReturnValue(true); + + authorization.getAuthorizedRuleTypes.mockResolvedValue( + new Map([ + [myAppAlertType.id, { authorizedConsumers }], + [alertingAlertType.id, { authorizedConsumers }], ]) ); - expect(await rulesClient.listRuleTypes()).toEqual( - new Set([ - { ...myAppAlertType, authorizedConsumers }, - { ...alertingAlertType, authorizedConsumers }, + + expect(await rulesClient.listRuleTypes()).toMatchInlineSnapshot(` + Array [ + Object { + "actionGroups": Array [], + "actionVariables": undefined, + "authorizedConsumers": Object { + "alerts": Object { + "all": true, + "read": true, + }, + "myApp": Object { + "all": true, + "read": true, + }, + "myOtherApp": Object { + "all": true, + "read": true, + }, + }, + "category": "test", + "defaultActionGroupId": "default", + "enabledInLicense": true, + "hasAlertsMappings": false, + "hasFieldsForAAD": false, + "id": "myAppAlertType", + "isExportable": true, + "minimumLicenseRequired": "basic", + "name": "myAppAlertType", + "producer": "myApp", + "recoveryActionGroup": Object { + "id": "recovered", + "name": "Recovered", + }, + "validLegacyConsumers": Array [], + }, + Object { + "actionGroups": Array [], + "actionVariables": undefined, + "authorizedConsumers": Object { + "alerts": Object { + "all": true, + "read": true, + }, + "myApp": Object { + "all": true, + "read": true, + }, + "myOtherApp": Object { + "all": true, + "read": true, + }, + }, + "category": "test", + "defaultActionGroupId": "default", + "enabledInLicense": true, + "hasAlertsMappings": false, + "hasFieldsForAAD": false, + "id": "alertingAlertType", + "isExportable": true, + "minimumLicenseRequired": "basic", + "name": "alertingAlertType", + "producer": "alerts", + "recoveryActionGroup": Object { + "id": "recovered", + "name": "Recovered", + }, + "validLegacyConsumers": Array [], + }, + ] + `); + }); + + test('should filter out rule types that are not registered in the registry', async () => { + ruleTypeRegistry.list.mockReturnValue(setOfAlertTypes); + ruleTypeRegistry.has.mockImplementation((id: string) => id === myAppAlertType.id); + + authorization.getAuthorizedRuleTypes.mockResolvedValue( + new Map([ + [myAppAlertType.id, { authorizedConsumers }], + [alertingAlertType.id, { authorizedConsumers }], ]) ); + + expect(await rulesClient.listRuleTypes()).toMatchInlineSnapshot(` + Array [ + Object { + "actionGroups": Array [], + "actionVariables": undefined, + "authorizedConsumers": Object { + "alerts": Object { + "all": true, + "read": true, + }, + "myApp": Object { + "all": true, + "read": true, + }, + "myOtherApp": Object { + "all": true, + "read": true, + }, + }, + "category": "test", + "defaultActionGroupId": "default", + "enabledInLicense": true, + "hasAlertsMappings": false, + "hasFieldsForAAD": false, + "id": "myAppAlertType", + "isExportable": true, + "minimumLicenseRequired": "basic", + "name": "myAppAlertType", + "producer": "myApp", + "recoveryActionGroup": Object { + "id": "recovered", + "name": "Recovered", + }, + "validLegacyConsumers": Array [], + }, + ] + `); }); describe('authorization', () => { - const listedTypes = new Set([ - { - actionGroups: [], - actionVariables: undefined, - defaultActionGroupId: 'default', - minimumLicenseRequired: 'basic', - isExportable: true, - recoveryActionGroup: RecoveredActionGroup, - id: 'myType', - name: 'myType', - category: 'test', - producer: 'myApp', - enabledInLicense: true, - hasAlertsMappings: false, - hasFieldsForAAD: false, - validLegacyConsumers: [], - }, - { - id: 'myOtherType', - name: 'Test', - actionGroups: [{ id: 'default', name: 'Default' }], - defaultActionGroupId: 'default', - minimumLicenseRequired: 'basic', - isExportable: true, - recoveryActionGroup: RecoveredActionGroup, - category: 'test', - producer: 'alerts', - enabledInLicense: true, - hasAlertsMappings: false, - hasFieldsForAAD: false, - validLegacyConsumers: [], - }, - ]); - beforeEach(() => { - ruleTypeRegistry.list.mockReturnValue(listedTypes); - }); - - test('should return a list of AlertTypes that exist in the registry only if the user is authorised to get them', async () => { - const authorizedTypes = new Set([ + const listedTypes = new Map([ + [ + 'myType', { + actionGroups: [], + actionVariables: undefined, + defaultActionGroupId: 'default', + minimumLicenseRequired: 'basic', + isExportable: true, + recoveryActionGroup: RecoveredActionGroup, id: 'myType', + name: 'myType', + category: 'test', + producer: 'myApp', + enabledInLicense: true, + hasAlertsMappings: false, + hasFieldsForAAD: false, + validLegacyConsumers: [], + }, + ], + [ + 'myOtherType', + { + id: 'myOtherType', name: 'Test', actionGroups: [{ id: 'default', name: 'Default' }], defaultActionGroupId: 'default', @@ -182,18 +284,62 @@ describe('listRuleTypes', () => { recoveryActionGroup: RecoveredActionGroup, category: 'test', producer: 'alerts', - authorizedConsumers: { - myApp: { read: true, all: true }, - }, enabledInLicense: true, hasAlertsMappings: false, hasFieldsForAAD: false, validLegacyConsumers: [], }, - ]); - authorization.filterByRuleTypeAuthorization.mockResolvedValue(authorizedTypes); + ], + ]); + + beforeEach(() => { + ruleTypeRegistry.list.mockReturnValue(listedTypes); + ruleTypeRegistry.has.mockReturnValue(true); + }); - expect(await rulesClient.listRuleTypes()).toEqual(authorizedTypes); + test('should return a list of AlertTypes that exist in the registry only if the user is authorized to get them', async () => { + authorization.getAuthorizedRuleTypes.mockResolvedValue( + new Map([ + [ + 'myType', + { + authorizedConsumers: { + myApp: { read: true, all: true }, + }, + }, + ], + ]) + ); + + expect(await rulesClient.listRuleTypes()).toMatchInlineSnapshot(` + Array [ + Object { + "actionGroups": Array [], + "actionVariables": undefined, + "authorizedConsumers": Object { + "myApp": Object { + "all": true, + "read": true, + }, + }, + "category": "test", + "defaultActionGroupId": "default", + "enabledInLicense": true, + "hasAlertsMappings": false, + "hasFieldsForAAD": false, + "id": "myType", + "isExportable": true, + "minimumLicenseRequired": "basic", + "name": "myType", + "producer": "myApp", + "recoveryActionGroup": Object { + "id": "recovered", + "name": "Recovered", + }, + "validLegacyConsumers": Array [], + }, + ] + `); }); }); }); diff --git a/x-pack/plugins/alerting/server/rules_client/types.ts b/x-pack/plugins/alerting/server/rules_client/types.ts index 9a701e1c95c81..afcb4e1037a6c 100644 --- a/x-pack/plugins/alerting/server/rules_client/types.ts +++ b/x-pack/plugins/alerting/server/rules_client/types.ts @@ -23,7 +23,6 @@ import { TaskManagerStartContract } from '@kbn/task-manager-plugin/server'; import { IEventLogClient, IEventLogger } from '@kbn/event-log-plugin/server'; import { AuditLogger } from '@kbn/security-plugin/server'; import { DistributiveOmit } from '@elastic/eui'; -import { RegistryRuleType } from '../rule_type_registry'; import { RuleTypeRegistry, IntervalSchedule, @@ -108,9 +107,6 @@ export type NormalizedAlertActionWithGeneratedValues = | NormalizedAlertDefaultActionWithGeneratedValues | NormalizedAlertSystemActionWithGeneratedValues; -export interface RegistryAlertTypeWithAuth extends RegistryRuleType { - authorizedConsumers: string[]; -} export type CreateAPIKeyResult = | { apiKeysEnabled: false } | { apiKeysEnabled: true; result: SecurityPluginGrantAPIKeyResult }; diff --git a/x-pack/plugins/alerting/server/rules_client_factory.test.ts b/x-pack/plugins/alerting/server/rules_client_factory.test.ts index 4cd7ffbcf0c6c..9af5962915d72 100644 --- a/x-pack/plugins/alerting/server/rules_client_factory.test.ts +++ b/x-pack/plugins/alerting/server/rules_client_factory.test.ts @@ -98,11 +98,11 @@ test('creates a rules client with proper constructor arguments when security is const request = mockRouter.createKibanaRequest(); savedObjectsService.getScopedClient.mockReturnValue(savedObjectsClient); - alertingAuthorizationClientFactory.create.mockReturnValue( + alertingAuthorizationClientFactory.create.mockResolvedValue( alertingAuthorization as unknown as AlertingAuthorization ); - factory.create(request, savedObjectsService); + await factory.create(request, savedObjectsService); expect(savedObjectsService.getScopedClient).toHaveBeenCalledWith(request, { excludedExtensions: [SECURITY_EXTENSION_ID], @@ -154,11 +154,11 @@ test('creates a rules client with proper constructor arguments', async () => { const request = mockRouter.createKibanaRequest(); savedObjectsService.getScopedClient.mockReturnValue(savedObjectsClient); - alertingAuthorizationClientFactory.create.mockReturnValue( + alertingAuthorizationClientFactory.create.mockResolvedValue( alertingAuthorization as unknown as AlertingAuthorization ); - factory.create(request, savedObjectsService); + await factory.create(request, savedObjectsService); expect(savedObjectsService.getScopedClient).toHaveBeenCalledWith(request, { excludedExtensions: [SECURITY_EXTENSION_ID], @@ -203,7 +203,7 @@ test('creates a rules client with proper constructor arguments', async () => { test('getUserName() returns null when security is disabled', async () => { const factory = new RulesClientFactory(); factory.initialize(rulesClientFactoryParams); - factory.create(mockRouter.createKibanaRequest(), savedObjectsService); + await factory.create(mockRouter.createKibanaRequest(), savedObjectsService); const constructorCall = jest.requireMock('./rules_client').RulesClient.mock.calls[0][0]; const userNameResult = await constructorCall.getUserName(); @@ -216,7 +216,7 @@ test('getUserName() returns a name when security is enabled', async () => { ...rulesClientFactoryParams, securityService, }); - factory.create(mockRouter.createKibanaRequest(), savedObjectsService); + await factory.create(mockRouter.createKibanaRequest(), savedObjectsService); const constructorCall = jest.requireMock('./rules_client').RulesClient.mock.calls[0][0]; securityService.authc.getCurrentUser.mockReturnValueOnce({ @@ -229,7 +229,7 @@ test('getUserName() returns a name when security is enabled', async () => { test('getActionsClient() returns ActionsClient', async () => { const factory = new RulesClientFactory(); factory.initialize(rulesClientFactoryParams); - factory.create(mockRouter.createKibanaRequest(), savedObjectsService); + await factory.create(mockRouter.createKibanaRequest(), savedObjectsService); const constructorCall = jest.requireMock('./rules_client').RulesClient.mock.calls[0][0]; const actionsClient = await constructorCall.getActionsClient(); @@ -239,7 +239,7 @@ test('getActionsClient() returns ActionsClient', async () => { test('createAPIKey() returns { apiKeysEnabled: false } when security is disabled', async () => { const factory = new RulesClientFactory(); factory.initialize(rulesClientFactoryParams); - factory.create(mockRouter.createKibanaRequest(), savedObjectsService); + await factory.create(mockRouter.createKibanaRequest(), savedObjectsService); const constructorCall = jest.requireMock('./rules_client').RulesClient.mock.calls[0][0]; const createAPIKeyResult = await constructorCall.createAPIKey(); @@ -249,7 +249,7 @@ test('createAPIKey() returns { apiKeysEnabled: false } when security is disabled test('createAPIKey() returns { apiKeysEnabled: false } when security is enabled but ES security is disabled', async () => { const factory = new RulesClientFactory(); factory.initialize(rulesClientFactoryParams); - factory.create(mockRouter.createKibanaRequest(), savedObjectsService); + await factory.create(mockRouter.createKibanaRequest(), savedObjectsService); const constructorCall = jest.requireMock('./rules_client').RulesClient.mock.calls[0][0]; securityPluginStart.authc.apiKeys.grantAsInternalUser.mockResolvedValueOnce(null); @@ -265,7 +265,7 @@ test('createAPIKey() returns an API key when security is enabled', async () => { securityPluginSetup, securityPluginStart, }); - factory.create(mockRouter.createKibanaRequest(), savedObjectsService); + await factory.create(mockRouter.createKibanaRequest(), savedObjectsService); const constructorCall = jest.requireMock('./rules_client').RulesClient.mock.calls[0][0]; securityPluginStart.authc.apiKeys.grantAsInternalUser.mockResolvedValueOnce({ @@ -296,7 +296,7 @@ test('createAPIKey() throws when security plugin createAPIKey throws an error', securityPluginSetup, securityPluginStart, }); - factory.create(mockRouter.createKibanaRequest(), savedObjectsService); + await factory.create(mockRouter.createKibanaRequest(), savedObjectsService); const constructorCall = jest.requireMock('./rules_client').RulesClient.mock.calls[0][0]; securityPluginStart.authc.apiKeys.grantAsInternalUser.mockRejectedValueOnce( diff --git a/x-pack/plugins/alerting/server/rules_client_factory.ts b/x-pack/plugins/alerting/server/rules_client_factory.ts index f28170b277ac4..f56b0840317bb 100644 --- a/x-pack/plugins/alerting/server/rules_client_factory.ts +++ b/x-pack/plugins/alerting/server/rules_client_factory.ts @@ -115,7 +115,10 @@ export class RulesClientFactory { this.securityService = options.securityService; } - public create(request: KibanaRequest, savedObjects: SavedObjectsServiceStart): RulesClient { + public async create( + request: KibanaRequest, + savedObjects: SavedObjectsServiceStart + ): Promise { const { securityPluginSetup, securityService, securityPluginStart, actions, eventLog } = this; const spaceId = this.getSpaceId(request); @@ -123,6 +126,8 @@ export class RulesClientFactory { throw new Error('AlertingAuthorizationClientFactory is not defined'); } + const authorization = await this.authorization.create(request); + return new RulesClient({ spaceId, kibanaVersion: this.kibanaVersion, @@ -139,7 +144,7 @@ export class RulesClientFactory { AD_HOC_RUN_SAVED_OBJECT_TYPE, ], }), - authorization: this.authorization.create(request), + authorization, actionsAuthorization: actions.getActionsAuthorizationWithRequest(request), namespace: this.spaceIdToNamespace(spaceId), internalSavedObjectsRepository: this.internalSavedObjectsRepository, @@ -169,6 +174,7 @@ export class RulesClientFactory { if (!createAPIKeyResult) { return { apiKeysEnabled: false }; } + return { apiKeysEnabled: true, result: createAPIKeyResult, diff --git a/x-pack/plugins/alerting/server/task_runner/action_scheduler/action_scheduler.test.ts b/x-pack/plugins/alerting/server/task_runner/action_scheduler/action_scheduler.test.ts index 00f1a87aefd71..c0eb08e6d582f 100644 --- a/x-pack/plugins/alerting/server/task_runner/action_scheduler/action_scheduler.test.ts +++ b/x-pack/plugins/alerting/server/task_runner/action_scheduler/action_scheduler.test.ts @@ -2617,7 +2617,6 @@ describe('Action Scheduler', () => { }); expect(buildActionParams).not.toHaveBeenCalledWith(); - expect(actionsClient.ephemeralEnqueuedExecution).not.toHaveBeenCalled(); expect(actionsClient.bulkEnqueueExecution).not.toHaveBeenCalled(); expect(alertingEventLogger.logAction).not.toHaveBeenCalled(); expect(executorParams.logger.warn).toHaveBeenCalledWith( @@ -2662,7 +2661,6 @@ describe('Action Scheduler', () => { expect(res).toEqual({ throttledSummaryActions: {} }); expect(buildActionParams).not.toHaveBeenCalled(); expect(alertsClient.getSummarizedAlerts).not.toHaveBeenCalled(); - expect(actionsClient.ephemeralEnqueuedExecution).not.toHaveBeenCalled(); expect(actionsClient.bulkEnqueueExecution).not.toHaveBeenCalled(); expect(alertingEventLogger.logAction).not.toHaveBeenCalled(); }); diff --git a/x-pack/plugins/alerting/server/task_runner/action_scheduler/action_scheduler.ts b/x-pack/plugins/alerting/server/task_runner/action_scheduler/action_scheduler.ts index fa16cfcabb094..9a174dd236cf1 100644 --- a/x-pack/plugins/alerting/server/task_runner/action_scheduler/action_scheduler.ts +++ b/x-pack/plugins/alerting/server/task_runner/action_scheduler/action_scheduler.ts @@ -5,13 +5,8 @@ * 2.0. */ +import { createTaskRunError, TaskErrorSource } from '@kbn/task-manager-plugin/server'; import { - createTaskRunError, - isEphemeralTaskRejectedDueToCapacityError, - TaskErrorSource, -} from '@kbn/task-manager-plugin/server'; -import { - ExecuteOptions as EnqueueExecutionOptions, ExecutionResponseItem, ExecutionResponseType, } from '@kbn/actions-plugin/server/create_execute_function'; @@ -51,8 +46,6 @@ export class ActionScheduler< IActionScheduler > = []; - private ephemeralActionsToSchedule: number; - constructor( private readonly context: ActionSchedulerOptions< Params, @@ -65,7 +58,6 @@ export class ActionScheduler< AlertData > ) { - this.ephemeralActionsToSchedule = context.taskRunnerContext.maxEphemeralActionsPerRule; for (const [_, scheduler] of Object.entries(schedulers)) { this.schedulers.push(new scheduler(context)); } @@ -101,37 +93,28 @@ export class ActionScheduler< return { throttledSummaryActions }; } - const bulkScheduleRequest: EnqueueExecutionOptions[] = []; - - for (const result of allActionsToScheduleResult) { - await this.runActionAsEphemeralOrAddToBulkScheduleRequest({ - enqueueOptions: result.actionToEnqueue, - bulkScheduleRequest, - }); - } - let bulkScheduleResponse: ExecutionResponseItem[] = []; - if (!!bulkScheduleRequest.length) { - for (const c of chunk(bulkScheduleRequest, BULK_SCHEDULE_CHUNK_SIZE)) { - let enqueueResponse; - try { - enqueueResponse = await withAlertingSpan('alerting:bulk-enqueue-actions', () => - this.context.actionsClient!.bulkEnqueueExecution(c) - ); - } catch (e) { - if (e.statusCode === 404) { - throw createTaskRunError(e, TaskErrorSource.USER); - } - throw createTaskRunError(e, TaskErrorSource.FRAMEWORK); - } - if (enqueueResponse.errors) { - bulkScheduleResponse = bulkScheduleResponse.concat( - enqueueResponse.items.filter( - (i) => i.response === ExecutionResponseType.QUEUED_ACTIONS_LIMIT_ERROR - ) - ); + for (const c of chunk(allActionsToScheduleResult, BULK_SCHEDULE_CHUNK_SIZE)) { + let enqueueResponse; + try { + enqueueResponse = await withAlertingSpan('alerting:bulk-enqueue-actions', () => + this.context.actionsClient!.bulkEnqueueExecution( + c.map((actions) => actions.actionToEnqueue) + ) + ); + } catch (e) { + if (e.statusCode === 404) { + throw createTaskRunError(e, TaskErrorSource.USER); } + throw createTaskRunError(e, TaskErrorSource.FRAMEWORK); + } + if (enqueueResponse.errors) { + bulkScheduleResponse = bulkScheduleResponse.concat( + enqueueResponse.items.filter( + (i) => i.response === ExecutionResponseType.QUEUED_ACTIONS_LIMIT_ERROR + ) + ); } } @@ -175,28 +158,4 @@ export class ActionScheduler< return { throttledSummaryActions }; } - - private async runActionAsEphemeralOrAddToBulkScheduleRequest({ - enqueueOptions, - bulkScheduleRequest, - }: { - enqueueOptions: EnqueueExecutionOptions; - bulkScheduleRequest: EnqueueExecutionOptions[]; - }) { - if ( - this.context.taskRunnerContext.supportsEphemeralTasks && - this.ephemeralActionsToSchedule > 0 - ) { - this.ephemeralActionsToSchedule--; - try { - await this.context.actionsClient!.ephemeralEnqueuedExecution(enqueueOptions); - } catch (err) { - if (isEphemeralTaskRejectedDueToCapacityError(err)) { - bulkScheduleRequest.push(enqueueOptions); - } - } - } else { - bulkScheduleRequest.push(enqueueOptions); - } - } } diff --git a/x-pack/plugins/alerting/server/task_runner/ad_hoc_task_runner.test.ts b/x-pack/plugins/alerting/server/task_runner/ad_hoc_task_runner.test.ts index cfc87f8497eae..ae6467d0dcbf8 100644 --- a/x-pack/plugins/alerting/server/task_runner/ad_hoc_task_runner.test.ts +++ b/x-pack/plugins/alerting/server/task_runner/ad_hoc_task_runner.test.ts @@ -168,13 +168,11 @@ const taskRunnerFactoryInitializerParams: TaskRunnerFactoryInitializerParamsType kibanaBaseUrl: 'https://localhost:5601', logger, maxAlerts: 1000, - maxEphemeralActionsPerRule: 10, ruleTypeRegistry, rulesSettingsService, savedObjects: savedObjectsService, share: {} as SharePluginStart, spaceIdToNamespace: jest.fn().mockReturnValue(undefined), - supportsEphemeralTasks: false, uiSettings: uiSettingsService, usageCounter: mockUsageCounter, isServerless: false, diff --git a/x-pack/plugins/alerting/server/task_runner/rule_loader.test.ts b/x-pack/plugins/alerting/server/task_runner/rule_loader.test.ts index 4690ccc653a32..c5e833dee1058 100644 --- a/x-pack/plugins/alerting/server/task_runner/rule_loader.test.ts +++ b/x-pack/plugins/alerting/server/task_runner/rule_loader.test.ts @@ -113,7 +113,7 @@ describe('rule_loader', () => { }); }); - test('throws when rule is not enabled', async () => { + test('throws when rule is not enabled', () => { let outcome = 'success'; try { validateRuleAndCreateFakeRequest({ @@ -128,7 +128,7 @@ describe('rule_loader', () => { expect(outcome).toBe('failure'); }); - test('throws when rule type is not enabled', async () => { + test('throws when rule type is not enabled', () => { ruleTypeRegistry.ensureRuleTypeEnabled.mockImplementation(() => { throw new Error('rule-type-not-enabled: 2112'); }); @@ -148,7 +148,7 @@ describe('rule_loader', () => { expect(outcome).toBe('failure'); }); - test('test throws when rule params fail validation', async () => { + test('test throws when rule params fail validation', () => { mockGetAlertFromRaw.mockReturnValueOnce({ name: ruleName, alertTypeId: ruleTypeId, diff --git a/x-pack/plugins/alerting/server/task_runner/task_runner.test.ts b/x-pack/plugins/alerting/server/task_runner/task_runner.test.ts index da23b9bdce4ed..bbe927833afd0 100644 --- a/x-pack/plugins/alerting/server/task_runner/task_runner.test.ts +++ b/x-pack/plugins/alerting/server/task_runner/task_runner.test.ts @@ -53,7 +53,6 @@ import { generateActionOpts, mockDate, mockedRuleTypeSavedObject, - mockRunNowResponse, ruleType, RULE_NAME, generateRunnerResult, @@ -187,38 +186,16 @@ describe('Task Runner', () => { logger, maintenanceWindowsService, maxAlerts: 1000, - maxEphemeralActionsPerRule: 10, ruleTypeRegistry, rulesSettingsService, savedObjects: savedObjectsService, share: {} as SharePluginStart, spaceIdToNamespace: jest.fn().mockReturnValue(undefined), - supportsEphemeralTasks: false, uiSettings: uiSettingsService, usageCounter: mockUsageCounter, isServerless: false, }; - const ephemeralTestParams: Array< - [ - nameExtension: string, - customTaskRunnerFactoryInitializerParams: TaskRunnerFactoryInitializerParamsType, - enqueueFunction: unknown, - isBulk: boolean - ] - > = [ - ['', taskRunnerFactoryInitializerParams, actionsClient.bulkEnqueueExecution, true], - [ - ' (with ephemeral support)', - { - ...taskRunnerFactoryInitializerParams, - supportsEphemeralTasks: true, - }, - actionsClient.ephemeralEnqueuedExecution, - false, - ], - ]; - beforeEach(() => { jest.resetAllMocks(); jest.restoreAllMocks(); // clear spy mock implementations @@ -363,103 +340,95 @@ describe('Task Runner', () => { ).toHaveBeenCalled(); }); - test.each(ephemeralTestParams)( - 'actionsPlugin.execute is called per alert alert that is scheduled %s', - async (nameExtension, customTaskRunnerFactoryInitializerParams, enqueueFunction, isBulk) => { - customTaskRunnerFactoryInitializerParams.actionsPlugin.isActionTypeEnabled.mockReturnValue( - true - ); - customTaskRunnerFactoryInitializerParams.actionsPlugin.isActionExecutable.mockReturnValue( - true - ); - actionsClient.ephemeralEnqueuedExecution.mockResolvedValue(mockRunNowResponse); - ruleType.executor.mockImplementation( - async ({ - services: executorServices, - }: RuleExecutorOptions< - RuleTypeParams, - RuleTypeState, - AlertInstanceState, - AlertInstanceContext, - string, - RuleAlertData - >) => { - executorServices.alertFactory.create('1').scheduleActions('default'); - return { state: {} }; - } - ); - const taskRunner = new TaskRunner({ - ruleType, - taskInstance: mockedTaskInstance, - context: customTaskRunnerFactoryInitializerParams, - inMemoryMetrics, - internalSavedObjectsRepository, - }); - expect(AlertingEventLogger).toHaveBeenCalledTimes(1); + test('actionsPlugin.execute is called per alert alert that is scheduled', async () => { + taskRunnerFactoryInitializerParams.actionsPlugin.isActionTypeEnabled.mockReturnValue(true); + taskRunnerFactoryInitializerParams.actionsPlugin.isActionExecutable.mockReturnValue(true); + ruleType.executor.mockImplementation( + async ({ + services: executorServices, + }: RuleExecutorOptions< + RuleTypeParams, + RuleTypeState, + AlertInstanceState, + AlertInstanceContext, + string, + RuleAlertData + >) => { + executorServices.alertFactory.create('1').scheduleActions('default'); + return { state: {} }; + } + ); + const taskRunner = new TaskRunner({ + ruleType, + taskInstance: mockedTaskInstance, + context: taskRunnerFactoryInitializerParams, + inMemoryMetrics, + internalSavedObjectsRepository, + }); + expect(AlertingEventLogger).toHaveBeenCalledTimes(1); - mockGetAlertFromRaw.mockReturnValue(mockedRuleTypeSavedObject as Rule); - encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValue(mockedRawRuleSO); - await taskRunner.run(); - expect(enqueueFunction).toHaveBeenCalledTimes(1); - expect(enqueueFunction).toHaveBeenCalledWith( - generateEnqueueFunctionInput({ isBulk, id: '1', foo: true }) - ); + mockGetAlertFromRaw.mockReturnValue(mockedRuleTypeSavedObject as Rule); + encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValue(mockedRawRuleSO); + await taskRunner.run(); + expect(actionsClient.bulkEnqueueExecution).toHaveBeenCalledTimes(1); + expect(actionsClient.bulkEnqueueExecution).toHaveBeenCalledWith( + generateEnqueueFunctionInput({ isBulk: true, id: '1', foo: true }) + ); - expect(logger.debug).toHaveBeenCalledTimes(6); - expect(logger.debug).nthCalledWith(1, 'executing rule test:1 at 1970-01-01T00:00:00.000Z', { - tags: ['1', 'test'], - }); - expect(logger.debug).nthCalledWith( - 2, - `rule test:1: '${RULE_NAME}' has 1 active alerts: [{\"instanceId\":\"1\",\"actionGroup\":\"default\"}]`, - { tags: ['1', 'test'] } - ); - expect(logger.debug).nthCalledWith( - 3, - 'deprecated ruleRunStatus for test:1: {"lastExecutionDate":"1970-01-01T00:00:00.000Z","status":"active"}', - { tags: ['1', 'test'] } - ); - expect(logger.debug).nthCalledWith( - 4, - 'ruleRunStatus for test:1: {"outcome":"succeeded","outcomeOrder":0,"outcomeMsg":null,"warning":null,"alertsCount":{"active":1,"new":1,"recovered":0,"ignored":0}}', - { tags: ['1', 'test'] } - ); - expect(logger.debug).nthCalledWith( - 5, - 'ruleRunMetrics for test:1: {"numSearches":3,"totalSearchDurationMs":23423,"esSearchDurationMs":33,"numberOfTriggeredActions":1,"numberOfGeneratedActions":1,"numberOfActiveAlerts":1,"numberOfRecoveredAlerts":0,"numberOfNewAlerts":1,"numberOfDelayedAlerts":0,"hasReachedAlertLimit":false,"hasReachedQueuedActionsLimit":false,"triggeredActionsStatus":"complete"}', - { tags: ['1', 'test'] } - ); + expect(logger.debug).toHaveBeenCalledTimes(6); + expect(logger.debug).nthCalledWith(1, 'executing rule test:1 at 1970-01-01T00:00:00.000Z', { + tags: ['1', 'test'], + }); + expect(logger.debug).nthCalledWith( + 2, + `rule test:1: '${RULE_NAME}' has 1 active alerts: [{\"instanceId\":\"1\",\"actionGroup\":\"default\"}]`, + { tags: ['1', 'test'] } + ); + expect(logger.debug).nthCalledWith( + 3, + 'deprecated ruleRunStatus for test:1: {"lastExecutionDate":"1970-01-01T00:00:00.000Z","status":"active"}', + { tags: ['1', 'test'] } + ); + expect(logger.debug).nthCalledWith( + 4, + 'ruleRunStatus for test:1: {"outcome":"succeeded","outcomeOrder":0,"outcomeMsg":null,"warning":null,"alertsCount":{"active":1,"new":1,"recovered":0,"ignored":0}}', + { tags: ['1', 'test'] } + ); + expect(logger.debug).nthCalledWith( + 5, + 'ruleRunMetrics for test:1: {"numSearches":3,"totalSearchDurationMs":23423,"esSearchDurationMs":33,"numberOfTriggeredActions":1,"numberOfGeneratedActions":1,"numberOfActiveAlerts":1,"numberOfRecoveredAlerts":0,"numberOfNewAlerts":1,"numberOfDelayedAlerts":0,"hasReachedAlertLimit":false,"hasReachedQueuedActionsLimit":false,"triggeredActionsStatus":"complete"}', + { tags: ['1', 'test'] } + ); - testAlertingEventLogCalls({ - activeAlerts: 1, - generatedActions: 1, - newAlerts: 1, - triggeredActions: 1, - status: 'active', - logAlert: 2, - logAction: 1, - }); - expect(alertingEventLogger.logAlert).toHaveBeenNthCalledWith( - 1, - generateAlertOpts({ - action: EVENT_LOG_ACTIONS.newInstance, - group: 'default', - state: { start: DATE_1970, duration: '0' }, - }) - ); - expect(alertingEventLogger.logAlert).toHaveBeenNthCalledWith( - 2, - generateAlertOpts({ - action: EVENT_LOG_ACTIONS.activeInstance, - group: 'default', - state: { start: DATE_1970, duration: '0' }, - }) - ); - expect(alertingEventLogger.logAction).toHaveBeenNthCalledWith(1, generateActionOpts()); + testAlertingEventLogCalls({ + activeAlerts: 1, + generatedActions: 1, + newAlerts: 1, + triggeredActions: 1, + status: 'active', + logAlert: 2, + logAction: 1, + }); + expect(alertingEventLogger.logAlert).toHaveBeenNthCalledWith( + 1, + generateAlertOpts({ + action: EVENT_LOG_ACTIONS.newInstance, + group: 'default', + state: { start: DATE_1970, duration: '0' }, + }) + ); + expect(alertingEventLogger.logAlert).toHaveBeenNthCalledWith( + 2, + generateAlertOpts({ + action: EVENT_LOG_ACTIONS.activeInstance, + group: 'default', + state: { start: DATE_1970, duration: '0' }, + }) + ); + expect(alertingEventLogger.logAction).toHaveBeenNthCalledWith(1, generateActionOpts()); - expect(mockUsageCounter.incrementCounter).not.toHaveBeenCalled(); - } - ); + expect(mockUsageCounter.incrementCounter).not.toHaveBeenCalled(); + }); test('actionsPlugin.execute is skipped if muteAll is true', async () => { taskRunnerFactoryInitializerParams.actionsPlugin.isActionTypeEnabled.mockReturnValue(true); @@ -494,7 +463,6 @@ describe('Task Runner', () => { }); encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValue(mockedRawRuleSO); await taskRunner.run(); - expect(actionsClient.ephemeralEnqueuedExecution).toHaveBeenCalledTimes(0); expect(logger.debug).toHaveBeenCalledTimes(7); expect(logger.debug).nthCalledWith(1, 'executing rule test:1 at 1970-01-01T00:00:00.000Z', { @@ -633,7 +601,6 @@ describe('Task Runner', () => { const expectedExecutions = shouldBeSnoozed ? 0 : 1; expect(actionsClient.bulkEnqueueExecution).toHaveBeenCalledTimes(expectedExecutions); - expect(actionsClient.ephemeralEnqueuedExecution).toHaveBeenCalledTimes(0); const expectedMessage = `no scheduling of actions for rule test:1: '${RULE_NAME}': rule is snoozed.`; if (expectedExecutions) { @@ -689,7 +656,6 @@ describe('Task Runner', () => { encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValue(mockedRawRuleSO); await taskRunner.run(); - expect(actionsClient.ephemeralEnqueuedExecution).toHaveBeenCalledTimes(0); testAlertingEventLogCalls({ activeAlerts: 1, @@ -761,7 +727,6 @@ describe('Task Runner', () => { encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValue(mockedRawRuleSO); await taskRunner.run(); - expect(actionsClient.ephemeralEnqueuedExecution).toHaveBeenCalledTimes(0); testAlertingEventLogCalls({ activeAlerts: 1, @@ -824,7 +789,6 @@ describe('Task Runner', () => { encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValue(mockedRawRuleSO); await taskRunner.run(); - expect(actionsClient.ephemeralEnqueuedExecution).toHaveBeenCalledTimes(0); testAlertingEventLogCalls({ activeAlerts: 1, @@ -855,202 +819,10 @@ describe('Task Runner', () => { expect(mockUsageCounter.incrementCounter).not.toHaveBeenCalled(); }); - test.each(ephemeralTestParams)( - 'skips firing actions for active alert if alert is muted %s', - async (nameExtension, customTaskRunnerFactoryInitializerParams, enqueueFunction) => { - ( - customTaskRunnerFactoryInitializerParams as TaskRunnerFactoryInitializerParamsType - ).actionsPlugin.isActionTypeEnabled.mockReturnValue(true); - customTaskRunnerFactoryInitializerParams.actionsPlugin.isActionExecutable.mockReturnValue( - true - ); - actionsClient.ephemeralEnqueuedExecution.mockResolvedValue(mockRunNowResponse); - ruleType.executor.mockImplementation( - async ({ - services: executorServices, - }: RuleExecutorOptions< - RuleTypeParams, - RuleTypeState, - AlertInstanceState, - AlertInstanceContext, - string, - RuleAlertData - >) => { - executorServices.alertFactory.create('1').scheduleActions('default'); - executorServices.alertFactory.create('2').scheduleActions('default'); - return { state: {} }; - } - ); - const taskRunner = new TaskRunner({ - ruleType, - taskInstance: mockedTaskInstance, - context: customTaskRunnerFactoryInitializerParams, - inMemoryMetrics, - internalSavedObjectsRepository, - }); - expect(AlertingEventLogger).toHaveBeenCalledTimes(1); - - mockGetAlertFromRaw.mockReturnValue({ - ...(mockedRuleTypeSavedObject as Rule), - mutedInstanceIds: ['2'], - }); - encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValue(mockedRawRuleSO); - await taskRunner.run(); - expect(enqueueFunction).toHaveBeenCalledTimes(1); - - expect(logger.debug).toHaveBeenCalledTimes(7); - expect(logger.debug).nthCalledWith(1, 'executing rule test:1 at 1970-01-01T00:00:00.000Z', { - tags: ['1', 'test'], - }); - expect(logger.debug).nthCalledWith( - 2, - `rule test:1: '${RULE_NAME}' has 2 active alerts: [{\"instanceId\":\"1\",\"actionGroup\":\"default\"},{\"instanceId\":\"2\",\"actionGroup\":\"default\"}]`, - { tags: ['1', 'test'] } - ); - expect(logger.debug).nthCalledWith( - 3, - `skipping scheduling of actions for '2' in rule test:1: '${RULE_NAME}': rule is muted`, - { tags: ['1', 'test'] } - ); - expect(logger.debug).nthCalledWith( - 4, - 'deprecated ruleRunStatus for test:1: {"lastExecutionDate":"1970-01-01T00:00:00.000Z","status":"active"}', - { tags: ['1', 'test'] } - ); - expect(logger.debug).nthCalledWith( - 5, - 'ruleRunStatus for test:1: {"outcome":"succeeded","outcomeOrder":0,"outcomeMsg":null,"warning":null,"alertsCount":{"active":2,"new":2,"recovered":0,"ignored":0}}', - { tags: ['1', 'test'] } - ); - expect(logger.debug).nthCalledWith( - 6, - 'ruleRunMetrics for test:1: {"numSearches":3,"totalSearchDurationMs":23423,"esSearchDurationMs":33,"numberOfTriggeredActions":1,"numberOfGeneratedActions":1,"numberOfActiveAlerts":2,"numberOfRecoveredAlerts":0,"numberOfNewAlerts":2,"numberOfDelayedAlerts":0,"hasReachedAlertLimit":false,"hasReachedQueuedActionsLimit":false,"triggeredActionsStatus":"complete"}', - { tags: ['1', 'test'] } - ); - expect(mockUsageCounter.incrementCounter).not.toHaveBeenCalled(); - } - ); - - test.each(ephemeralTestParams)( - 'skips firing actions for active alert if alert is throttled %s', - async (nameExtension, customTaskRunnerFactoryInitializerParams, enqueueFunction) => { - ( - customTaskRunnerFactoryInitializerParams as TaskRunnerFactoryInitializerParamsType - ).actionsPlugin.isActionTypeEnabled.mockReturnValue(true); - customTaskRunnerFactoryInitializerParams.actionsPlugin.isActionExecutable.mockReturnValue( - true - ); - actionsClient.ephemeralEnqueuedExecution.mockResolvedValue(mockRunNowResponse); - ruleType.executor.mockImplementation( - async ({ - services: executorServices, - }: RuleExecutorOptions< - RuleTypeParams, - RuleTypeState, - AlertInstanceState, - AlertInstanceContext, - string, - RuleAlertData - >) => { - executorServices.alertFactory.create('1').scheduleActions('default'); - executorServices.alertFactory.create('2').scheduleActions('default'); - return { state: {} }; - } - ); - const taskRunner = new TaskRunner({ - ruleType, - internalSavedObjectsRepository, - taskInstance: { - ...mockedTaskInstance, - state: { - ...mockedTaskInstance.state, - alertInstances: { - '2': { - meta: { - lastScheduledActions: { date: moment().toISOString(), group: 'default' }, - }, - state: { - bar: false, - start: DATE_1969, - duration: MOCK_DURATION, - }, - }, - }, - }, - }, - context: taskRunnerFactoryInitializerParams, - inMemoryMetrics, - }); - expect(AlertingEventLogger).toHaveBeenCalledTimes(1); - - mockGetAlertFromRaw.mockReturnValue({ - ...(mockedRuleTypeSavedObject as Rule), - notifyWhen: 'onThrottleInterval', - throttle: '1d', - }); - encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValue(mockedRawRuleSO); - await taskRunner.run(); - // expect(enqueueFunction).toHaveBeenCalledTimes(1); - - // expect(logger.debug).toHaveBeenCalledTimes(5); - expect(logger.debug).nthCalledWith( - 3, - `skipping scheduling of actions for '2' in rule test:1: '${RULE_NAME}': rule is throttled`, - { tags: ['1', 'test'] } - ); - } - ); - - test.each(ephemeralTestParams)( - 'skips firing actions for active alert when alert is muted even if notifyWhen === onActionGroupChange %s', - async (nameExtension, customTaskRunnerFactoryInitializerParams, enqueueFunction) => { - customTaskRunnerFactoryInitializerParams.actionsPlugin.isActionExecutable.mockReturnValue( - true - ); - ruleType.executor.mockImplementation( - async ({ - services: executorServices, - }: RuleExecutorOptions< - RuleTypeParams, - RuleTypeState, - AlertInstanceState, - AlertInstanceContext, - string, - RuleAlertData - >) => { - executorServices.alertFactory.create('1').scheduleActions('default'); - executorServices.alertFactory.create('2').scheduleActions('default'); - return { state: {} }; - } - ); - const taskRunner = new TaskRunner({ - ruleType, - internalSavedObjectsRepository, - taskInstance: mockedTaskInstance, - context: customTaskRunnerFactoryInitializerParams, - inMemoryMetrics, - }); - expect(AlertingEventLogger).toHaveBeenCalledTimes(1); - - mockGetAlertFromRaw.mockReturnValue({ - ...(mockedRuleTypeSavedObject as Rule), - mutedInstanceIds: ['2'], - notifyWhen: 'onActionGroupChange', - }); - encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValue(mockedRawRuleSO); - await taskRunner.run(); - expect(enqueueFunction).toHaveBeenCalledTimes(1); - expect(logger.debug).toHaveBeenCalledTimes(7); - expect(logger.debug).nthCalledWith( - 3, - `skipping scheduling of actions for '2' in rule test:1: '${RULE_NAME}': rule is muted`, - { tags: ['1', 'test'] } - ); - } - ); - - test('actionsPlugin.execute is not called when notifyWhen=onActionGroupChange and alert state does not change', async () => { - taskRunnerFactoryInitializerParams.actionsPlugin.isActionTypeEnabled.mockReturnValue(true); + test('skips firing actions for active alert if alert is muted', async () => { + ( + taskRunnerFactoryInitializerParams as TaskRunnerFactoryInitializerParamsType + ).actionsPlugin.isActionTypeEnabled.mockReturnValue(true); taskRunnerFactoryInitializerParams.actionsPlugin.isActionExecutable.mockReturnValue(true); ruleType.executor.mockImplementation( async ({ @@ -1064,13 +836,188 @@ describe('Task Runner', () => { RuleAlertData >) => { executorServices.alertFactory.create('1').scheduleActions('default'); + executorServices.alertFactory.create('2').scheduleActions('default'); return { state: {} }; } ); const taskRunner = new TaskRunner({ ruleType, - internalSavedObjectsRepository, - taskInstance: { + taskInstance: mockedTaskInstance, + context: taskRunnerFactoryInitializerParams, + inMemoryMetrics, + internalSavedObjectsRepository, + }); + expect(AlertingEventLogger).toHaveBeenCalledTimes(1); + + mockGetAlertFromRaw.mockReturnValue({ + ...(mockedRuleTypeSavedObject as Rule), + mutedInstanceIds: ['2'], + }); + encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValue(mockedRawRuleSO); + await taskRunner.run(); + expect(actionsClient.bulkEnqueueExecution).toHaveBeenCalledTimes(1); + + expect(logger.debug).toHaveBeenCalledTimes(7); + expect(logger.debug).nthCalledWith(1, 'executing rule test:1 at 1970-01-01T00:00:00.000Z', { + tags: ['1', 'test'], + }); + expect(logger.debug).nthCalledWith( + 2, + `rule test:1: '${RULE_NAME}' has 2 active alerts: [{\"instanceId\":\"1\",\"actionGroup\":\"default\"},{\"instanceId\":\"2\",\"actionGroup\":\"default\"}]`, + { tags: ['1', 'test'] } + ); + expect(logger.debug).nthCalledWith( + 3, + `skipping scheduling of actions for '2' in rule test:1: '${RULE_NAME}': rule is muted`, + { tags: ['1', 'test'] } + ); + expect(logger.debug).nthCalledWith( + 4, + 'deprecated ruleRunStatus for test:1: {"lastExecutionDate":"1970-01-01T00:00:00.000Z","status":"active"}', + { tags: ['1', 'test'] } + ); + expect(logger.debug).nthCalledWith( + 5, + 'ruleRunStatus for test:1: {"outcome":"succeeded","outcomeOrder":0,"outcomeMsg":null,"warning":null,"alertsCount":{"active":2,"new":2,"recovered":0,"ignored":0}}', + { tags: ['1', 'test'] } + ); + expect(logger.debug).nthCalledWith( + 6, + 'ruleRunMetrics for test:1: {"numSearches":3,"totalSearchDurationMs":23423,"esSearchDurationMs":33,"numberOfTriggeredActions":1,"numberOfGeneratedActions":1,"numberOfActiveAlerts":2,"numberOfRecoveredAlerts":0,"numberOfNewAlerts":2,"numberOfDelayedAlerts":0,"hasReachedAlertLimit":false,"hasReachedQueuedActionsLimit":false,"triggeredActionsStatus":"complete"}', + { tags: ['1', 'test'] } + ); + expect(mockUsageCounter.incrementCounter).not.toHaveBeenCalled(); + }); + + test('skips firing actions for active alert if alert is throttled', async () => { + ( + taskRunnerFactoryInitializerParams as TaskRunnerFactoryInitializerParamsType + ).actionsPlugin.isActionTypeEnabled.mockReturnValue(true); + taskRunnerFactoryInitializerParams.actionsPlugin.isActionExecutable.mockReturnValue(true); + ruleType.executor.mockImplementation( + async ({ + services: executorServices, + }: RuleExecutorOptions< + RuleTypeParams, + RuleTypeState, + AlertInstanceState, + AlertInstanceContext, + string, + RuleAlertData + >) => { + executorServices.alertFactory.create('1').scheduleActions('default'); + executorServices.alertFactory.create('2').scheduleActions('default'); + return { state: {} }; + } + ); + const taskRunner = new TaskRunner({ + ruleType, + internalSavedObjectsRepository, + taskInstance: { + ...mockedTaskInstance, + state: { + ...mockedTaskInstance.state, + alertInstances: { + '2': { + meta: { + lastScheduledActions: { date: moment().toISOString(), group: 'default' }, + }, + state: { + bar: false, + start: DATE_1969, + duration: MOCK_DURATION, + }, + }, + }, + }, + }, + context: taskRunnerFactoryInitializerParams, + inMemoryMetrics, + }); + expect(AlertingEventLogger).toHaveBeenCalledTimes(1); + + mockGetAlertFromRaw.mockReturnValue({ + ...(mockedRuleTypeSavedObject as Rule), + notifyWhen: 'onThrottleInterval', + throttle: '1d', + }); + encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValue(mockedRawRuleSO); + await taskRunner.run(); + // expect(enqueueFunction).toHaveBeenCalledTimes(1); + + // expect(logger.debug).toHaveBeenCalledTimes(5); + expect(logger.debug).nthCalledWith( + 3, + `skipping scheduling of actions for '2' in rule test:1: '${RULE_NAME}': rule is throttled`, + { tags: ['1', 'test'] } + ); + }); + + test('skips firing actions for active alert when alert is muted even if notifyWhen === onActionGroupChange', async () => { + taskRunnerFactoryInitializerParams.actionsPlugin.isActionExecutable.mockReturnValue(true); + ruleType.executor.mockImplementation( + async ({ + services: executorServices, + }: RuleExecutorOptions< + RuleTypeParams, + RuleTypeState, + AlertInstanceState, + AlertInstanceContext, + string, + RuleAlertData + >) => { + executorServices.alertFactory.create('1').scheduleActions('default'); + executorServices.alertFactory.create('2').scheduleActions('default'); + return { state: {} }; + } + ); + const taskRunner = new TaskRunner({ + ruleType, + internalSavedObjectsRepository, + taskInstance: mockedTaskInstance, + context: taskRunnerFactoryInitializerParams, + inMemoryMetrics, + }); + expect(AlertingEventLogger).toHaveBeenCalledTimes(1); + + mockGetAlertFromRaw.mockReturnValue({ + ...(mockedRuleTypeSavedObject as Rule), + mutedInstanceIds: ['2'], + notifyWhen: 'onActionGroupChange', + }); + encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValue(mockedRawRuleSO); + await taskRunner.run(); + expect(actionsClient.bulkEnqueueExecution).toHaveBeenCalledTimes(1); + expect(logger.debug).toHaveBeenCalledTimes(7); + expect(logger.debug).nthCalledWith( + 3, + `skipping scheduling of actions for '2' in rule test:1: '${RULE_NAME}': rule is muted`, + { tags: ['1', 'test'] } + ); + }); + + test('actionsPlugin.execute is not called when notifyWhen=onActionGroupChange and alert state does not change', async () => { + taskRunnerFactoryInitializerParams.actionsPlugin.isActionTypeEnabled.mockReturnValue(true); + taskRunnerFactoryInitializerParams.actionsPlugin.isActionExecutable.mockReturnValue(true); + ruleType.executor.mockImplementation( + async ({ + services: executorServices, + }: RuleExecutorOptions< + RuleTypeParams, + RuleTypeState, + AlertInstanceState, + AlertInstanceContext, + string, + RuleAlertData + >) => { + executorServices.alertFactory.create('1').scheduleActions('default'); + return { state: {} }; + } + ); + const taskRunner = new TaskRunner({ + ruleType, + internalSavedObjectsRepository, + taskInstance: { ...mockedTaskInstance, state: { ...mockedTaskInstance.state, @@ -1099,7 +1046,6 @@ describe('Task Runner', () => { }); encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValue(mockedRawRuleSO); await taskRunner.run(); - expect(actionsClient.ephemeralEnqueuedExecution).toHaveBeenCalledTimes(0); testAlertingEventLogCalls({ activeAlerts: 1, @@ -1118,690 +1064,620 @@ describe('Task Runner', () => { expect(mockUsageCounter.incrementCounter).not.toHaveBeenCalled(); }); - test.each(ephemeralTestParams)( - 'actionsPlugin.execute is called when notifyWhen=onActionGroupChange and alert state has changed %s', - async (nameExtension, customTaskRunnerFactoryInitializerParams, enqueueFunction) => { - customTaskRunnerFactoryInitializerParams.actionsPlugin.isActionTypeEnabled.mockReturnValue( - true - ); - customTaskRunnerFactoryInitializerParams.actionsPlugin.isActionExecutable.mockReturnValue( - true - ); - ruleType.executor.mockImplementation( - async ({ - services: executorServices, - }: RuleExecutorOptions< - RuleTypeParams, - RuleTypeState, - AlertInstanceState, - AlertInstanceContext, - string, - RuleAlertData - >) => { - executorServices.alertFactory.create('1').scheduleActions('default'); - return { state: {} }; - } - ); - const taskRunner = new TaskRunner({ - ruleType, - internalSavedObjectsRepository, - taskInstance: { - ...mockedTaskInstance, - state: { - ...mockedTaskInstance.state, - alertInstances: { - '1': { - meta: { - lastScheduledActions: { group: 'newGroup', date: new Date().toISOString() }, - }, - state: { bar: false }, + test('actionsPlugin.execute is called when notifyWhen=onActionGroupChange and alert state has changed', async () => { + taskRunnerFactoryInitializerParams.actionsPlugin.isActionTypeEnabled.mockReturnValue(true); + taskRunnerFactoryInitializerParams.actionsPlugin.isActionExecutable.mockReturnValue(true); + ruleType.executor.mockImplementation( + async ({ + services: executorServices, + }: RuleExecutorOptions< + RuleTypeParams, + RuleTypeState, + AlertInstanceState, + AlertInstanceContext, + string, + RuleAlertData + >) => { + executorServices.alertFactory.create('1').scheduleActions('default'); + return { state: {} }; + } + ); + const taskRunner = new TaskRunner({ + ruleType, + internalSavedObjectsRepository, + taskInstance: { + ...mockedTaskInstance, + state: { + ...mockedTaskInstance.state, + alertInstances: { + '1': { + meta: { + lastScheduledActions: { group: 'newGroup', date: new Date().toISOString() }, }, + state: { bar: false }, }, }, }, - context: customTaskRunnerFactoryInitializerParams, - inMemoryMetrics, - }); - expect(AlertingEventLogger).toHaveBeenCalledTimes(1); + }, + context: taskRunnerFactoryInitializerParams, + inMemoryMetrics, + }); + expect(AlertingEventLogger).toHaveBeenCalledTimes(1); - mockGetAlertFromRaw.mockReturnValue({ - ...(mockedRuleTypeSavedObject as Rule), - notifyWhen: 'onActionGroupChange', - }); - encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValue(mockedRawRuleSO); + mockGetAlertFromRaw.mockReturnValue({ + ...(mockedRuleTypeSavedObject as Rule), + notifyWhen: 'onActionGroupChange', + }); + encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValue(mockedRawRuleSO); - await taskRunner.run(); + await taskRunner.run(); - testAlertingEventLogCalls({ - activeAlerts: 1, - triggeredActions: 1, - generatedActions: 1, - status: 'active', - logAlert: 1, - logAction: 1, - }); - expect(alertingEventLogger.logAlert).toHaveBeenNthCalledWith( - 1, - generateAlertOpts({ - action: EVENT_LOG_ACTIONS.activeInstance, - group: 'default', - state: { bar: false }, - }) - ); - expect(alertingEventLogger.logAction).toHaveBeenNthCalledWith(1, generateActionOpts({})); + testAlertingEventLogCalls({ + activeAlerts: 1, + triggeredActions: 1, + generatedActions: 1, + status: 'active', + logAlert: 1, + logAction: 1, + }); + expect(alertingEventLogger.logAlert).toHaveBeenNthCalledWith( + 1, + generateAlertOpts({ + action: EVENT_LOG_ACTIONS.activeInstance, + group: 'default', + state: { bar: false }, + }) + ); + expect(alertingEventLogger.logAction).toHaveBeenNthCalledWith(1, generateActionOpts({})); - expect(enqueueFunction).toHaveBeenCalledTimes(1); - expect(mockUsageCounter.incrementCounter).not.toHaveBeenCalled(); - } - ); + expect(actionsClient.bulkEnqueueExecution).toHaveBeenCalledTimes(1); + expect(mockUsageCounter.incrementCounter).not.toHaveBeenCalled(); + }); - test.each(ephemeralTestParams)( - 'includes the apiKey in the request used to initialize the actionsClient %s', - async (nameExtension, customTaskRunnerFactoryInitializerParams, enqueueFunction, isBulk) => { - customTaskRunnerFactoryInitializerParams.actionsPlugin.isActionTypeEnabled.mockReturnValue( - true - ); - customTaskRunnerFactoryInitializerParams.actionsPlugin.isActionExecutable.mockReturnValue( - true - ); - actionsClient.ephemeralEnqueuedExecution.mockResolvedValue(mockRunNowResponse); - ruleType.executor.mockImplementation( - async ({ - services: executorServices, - }: RuleExecutorOptions< - RuleTypeParams, - RuleTypeState, - AlertInstanceState, - AlertInstanceContext, - string, - RuleAlertData - >) => { - executorServices.alertFactory.create('1').scheduleActions('default'); - return { state: {} }; - } - ); - const taskRunner = new TaskRunner({ - ruleType, - internalSavedObjectsRepository, - taskInstance: mockedTaskInstance, - context: customTaskRunnerFactoryInitializerParams, - inMemoryMetrics, - }); - expect(AlertingEventLogger).toHaveBeenCalled(); + test('includes the apiKey in the request used to initialize the actionsClient', async () => { + taskRunnerFactoryInitializerParams.actionsPlugin.isActionTypeEnabled.mockReturnValue(true); + taskRunnerFactoryInitializerParams.actionsPlugin.isActionExecutable.mockReturnValue(true); + ruleType.executor.mockImplementation( + async ({ + services: executorServices, + }: RuleExecutorOptions< + RuleTypeParams, + RuleTypeState, + AlertInstanceState, + AlertInstanceContext, + string, + RuleAlertData + >) => { + executorServices.alertFactory.create('1').scheduleActions('default'); + return { state: {} }; + } + ); + const taskRunner = new TaskRunner({ + ruleType, + internalSavedObjectsRepository, + taskInstance: mockedTaskInstance, + context: taskRunnerFactoryInitializerParams, + inMemoryMetrics, + }); + expect(AlertingEventLogger).toHaveBeenCalled(); - mockGetAlertFromRaw.mockReturnValue(mockedRuleTypeSavedObject as Rule); - encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValue(mockedRawRuleSO); - await taskRunner.run(); - expect( - customTaskRunnerFactoryInitializerParams.actionsPlugin.getActionsClientWithRequest - ).toHaveBeenCalledWith( - expect.objectContaining({ - headers: { - // base64 encoded "123:abc" - authorization: 'ApiKey MTIzOmFiYw==', - }, - }) - ); + mockGetAlertFromRaw.mockReturnValue(mockedRuleTypeSavedObject as Rule); + encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValue(mockedRawRuleSO); + await taskRunner.run(); + expect( + taskRunnerFactoryInitializerParams.actionsPlugin.getActionsClientWithRequest + ).toHaveBeenCalledWith( + expect.objectContaining({ + headers: { + // base64 encoded "123:abc" + authorization: 'ApiKey MTIzOmFiYw==', + }, + }) + ); - const [request] = - customTaskRunnerFactoryInitializerParams.actionsPlugin.getActionsClientWithRequest.mock - .calls[0]; + const [request] = + taskRunnerFactoryInitializerParams.actionsPlugin.getActionsClientWithRequest.mock.calls[0]; - expect(customTaskRunnerFactoryInitializerParams.basePathService.set).toHaveBeenCalledWith( - request, - '/' - ); + expect(taskRunnerFactoryInitializerParams.basePathService.set).toHaveBeenCalledWith( + request, + '/' + ); - expect(enqueueFunction).toHaveBeenCalledTimes(1); - expect(enqueueFunction).toHaveBeenCalledWith( - generateEnqueueFunctionInput({ isBulk, id: '1', foo: true }) - ); + expect(actionsClient.bulkEnqueueExecution).toHaveBeenCalledTimes(1); + expect(actionsClient.bulkEnqueueExecution).toHaveBeenCalledWith( + generateEnqueueFunctionInput({ isBulk: true, id: '1', foo: true }) + ); - testAlertingEventLogCalls({ - activeAlerts: 1, - newAlerts: 1, - triggeredActions: 1, - generatedActions: 1, - status: 'active', - logAlert: 2, - logAction: 1, - }); - expect(alertingEventLogger.logAlert).toHaveBeenNthCalledWith( - 1, - generateAlertOpts({ - action: EVENT_LOG_ACTIONS.newInstance, - group: 'default', - state: { start: DATE_1970, duration: '0' }, - }) - ); - expect(alertingEventLogger.logAlert).toHaveBeenNthCalledWith( - 2, - generateAlertOpts({ - action: EVENT_LOG_ACTIONS.activeInstance, - group: 'default', - state: { start: DATE_1970, duration: '0' }, - }) - ); - expect(alertingEventLogger.logAction).toHaveBeenNthCalledWith(1, generateActionOpts({})); + testAlertingEventLogCalls({ + activeAlerts: 1, + newAlerts: 1, + triggeredActions: 1, + generatedActions: 1, + status: 'active', + logAlert: 2, + logAction: 1, + }); + expect(alertingEventLogger.logAlert).toHaveBeenNthCalledWith( + 1, + generateAlertOpts({ + action: EVENT_LOG_ACTIONS.newInstance, + group: 'default', + state: { start: DATE_1970, duration: '0' }, + }) + ); + expect(alertingEventLogger.logAlert).toHaveBeenNthCalledWith( + 2, + generateAlertOpts({ + action: EVENT_LOG_ACTIONS.activeInstance, + group: 'default', + state: { start: DATE_1970, duration: '0' }, + }) + ); + expect(alertingEventLogger.logAction).toHaveBeenNthCalledWith(1, generateActionOpts({})); - expect(mockUsageCounter.incrementCounter).not.toHaveBeenCalled(); - } - ); + expect(mockUsageCounter.incrementCounter).not.toHaveBeenCalled(); + }); - test.each(ephemeralTestParams)( - 'fire recovered actions for execution for the alertInstances which is in the recovered state %s', - async (nameExtension, customTaskRunnerFactoryInitializerParams, enqueueFunction, isBulk) => { - customTaskRunnerFactoryInitializerParams.actionsPlugin.isActionTypeEnabled.mockReturnValue( - true - ); - customTaskRunnerFactoryInitializerParams.actionsPlugin.isActionExecutable.mockReturnValue( - true - ); - actionsClient.ephemeralEnqueuedExecution.mockResolvedValue(mockRunNowResponse); + test('fire recovered actions for execution for the alertInstances which is in the recovered state', async () => { + taskRunnerFactoryInitializerParams.actionsPlugin.isActionTypeEnabled.mockReturnValue(true); + taskRunnerFactoryInitializerParams.actionsPlugin.isActionExecutable.mockReturnValue(true); - ruleType.executor.mockImplementation( - async ({ - services: executorServices, - }: RuleExecutorOptions< - RuleTypeParams, - RuleTypeState, - AlertInstanceState, - AlertInstanceContext, - string, - RuleAlertData - >) => { - executorServices.alertFactory.create('1').scheduleActions('default'); - return { state: {} }; - } - ); - const taskRunner = new TaskRunner({ - ruleType, - internalSavedObjectsRepository, - taskInstance: { - ...mockedTaskInstance, - state: { - ...mockedTaskInstance.state, - alertInstances: { - '1': { - meta: {}, - state: { - bar: false, - start: DATE_1969, - duration: '80000000000', - }, + ruleType.executor.mockImplementation( + async ({ + services: executorServices, + }: RuleExecutorOptions< + RuleTypeParams, + RuleTypeState, + AlertInstanceState, + AlertInstanceContext, + string, + RuleAlertData + >) => { + executorServices.alertFactory.create('1').scheduleActions('default'); + return { state: {} }; + } + ); + const taskRunner = new TaskRunner({ + ruleType, + internalSavedObjectsRepository, + taskInstance: { + ...mockedTaskInstance, + state: { + ...mockedTaskInstance.state, + alertInstances: { + '1': { + meta: {}, + state: { + bar: false, + start: DATE_1969, + duration: '80000000000', }, - '2': { - meta: {}, - state: { - bar: false, - start: '1969-12-31T06:00:00.000Z', - duration: '70000000000', - }, + }, + '2': { + meta: {}, + state: { + bar: false, + start: '1969-12-31T06:00:00.000Z', + duration: '70000000000', }, }, }, }, - context: customTaskRunnerFactoryInitializerParams, - inMemoryMetrics, - }); - expect(AlertingEventLogger).toHaveBeenCalled(); + }, + context: taskRunnerFactoryInitializerParams, + inMemoryMetrics, + }); + expect(AlertingEventLogger).toHaveBeenCalled(); - mockGetAlertFromRaw.mockReturnValue(mockedRuleTypeSavedObject as Rule); - encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValue(mockedRawRuleSO); - const runnerResult = await taskRunner.run(); - expect(runnerResult.state.alertInstances).toEqual( - generateAlertInstance({ - id: 1, - duration: MOCK_DURATION, - start: DATE_1969, - flappingHistory: [false], - }) - ); + mockGetAlertFromRaw.mockReturnValue(mockedRuleTypeSavedObject as Rule); + encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValue(mockedRawRuleSO); + const runnerResult = await taskRunner.run(); + expect(runnerResult.state.alertInstances).toEqual( + generateAlertInstance({ + id: 1, + duration: MOCK_DURATION, + start: DATE_1969, + flappingHistory: [false], + }) + ); - expect(logger.debug).toHaveBeenCalledTimes(7); - expect(logger.debug).nthCalledWith(1, 'executing rule test:1 at 1970-01-01T00:00:00.000Z', { - tags: ['1', 'test'], - }); - expect(logger.debug).nthCalledWith( - 2, - `rule test:1: '${RULE_NAME}' has 1 active alerts: [{\"instanceId\":\"1\",\"actionGroup\":\"default\"}]`, - { tags: ['1', 'test'] } - ); - expect(logger.debug).nthCalledWith( - 3, - `rule test:1: '${RULE_NAME}' has 1 recovered alerts: [\"2\"]`, - { tags: ['1', 'test'] } - ); - expect(logger.debug).nthCalledWith( - 4, - 'deprecated ruleRunStatus for test:1: {"lastExecutionDate":"1970-01-01T00:00:00.000Z","status":"active"}', - { tags: ['1', 'test'] } - ); - expect(logger.debug).nthCalledWith( - 5, - 'ruleRunStatus for test:1: {"outcome":"succeeded","outcomeOrder":0,"outcomeMsg":null,"warning":null,"alertsCount":{"active":1,"new":0,"recovered":1,"ignored":0}}', - { tags: ['1', 'test'] } - ); - expect(logger.debug).nthCalledWith( - 6, - 'ruleRunMetrics for test:1: {"numSearches":3,"totalSearchDurationMs":23423,"esSearchDurationMs":33,"numberOfTriggeredActions":2,"numberOfGeneratedActions":2,"numberOfActiveAlerts":1,"numberOfRecoveredAlerts":1,"numberOfNewAlerts":0,"numberOfDelayedAlerts":0,"hasReachedAlertLimit":false,"hasReachedQueuedActionsLimit":false,"triggeredActionsStatus":"complete"}', - { tags: ['1', 'test'] } - ); + expect(logger.debug).toHaveBeenCalledTimes(7); + expect(logger.debug).nthCalledWith(1, 'executing rule test:1 at 1970-01-01T00:00:00.000Z', { + tags: ['1', 'test'], + }); + expect(logger.debug).nthCalledWith( + 2, + `rule test:1: '${RULE_NAME}' has 1 active alerts: [{\"instanceId\":\"1\",\"actionGroup\":\"default\"}]`, + { tags: ['1', 'test'] } + ); + expect(logger.debug).nthCalledWith( + 3, + `rule test:1: '${RULE_NAME}' has 1 recovered alerts: [\"2\"]`, + { tags: ['1', 'test'] } + ); + expect(logger.debug).nthCalledWith( + 4, + 'deprecated ruleRunStatus for test:1: {"lastExecutionDate":"1970-01-01T00:00:00.000Z","status":"active"}', + { tags: ['1', 'test'] } + ); + expect(logger.debug).nthCalledWith( + 5, + 'ruleRunStatus for test:1: {"outcome":"succeeded","outcomeOrder":0,"outcomeMsg":null,"warning":null,"alertsCount":{"active":1,"new":0,"recovered":1,"ignored":0}}', + { tags: ['1', 'test'] } + ); + expect(logger.debug).nthCalledWith( + 6, + 'ruleRunMetrics for test:1: {"numSearches":3,"totalSearchDurationMs":23423,"esSearchDurationMs":33,"numberOfTriggeredActions":2,"numberOfGeneratedActions":2,"numberOfActiveAlerts":1,"numberOfRecoveredAlerts":1,"numberOfNewAlerts":0,"numberOfDelayedAlerts":0,"hasReachedAlertLimit":false,"hasReachedQueuedActionsLimit":false,"triggeredActionsStatus":"complete"}', + { tags: ['1', 'test'] } + ); - testAlertingEventLogCalls({ - activeAlerts: 1, - recoveredAlerts: 1, - triggeredActions: 2, - generatedActions: 2, - status: 'active', - logAlert: 2, - logAction: 2, - }); - expect(alertingEventLogger.logAlert).toHaveBeenNthCalledWith( - 1, - generateAlertOpts({ - action: EVENT_LOG_ACTIONS.recoveredInstance, - id: '2', - state: { - bar: false, - start: '1969-12-31T06:00:00.000Z', - duration: '64800000000000', - end: DATE_1970, - }, - }) - ); - expect(alertingEventLogger.logAlert).toHaveBeenNthCalledWith( - 2, - generateAlertOpts({ - action: EVENT_LOG_ACTIONS.activeInstance, - group: 'default', - state: { bar: false, start: DATE_1969, duration: MOCK_DURATION }, - }) - ); - expect(alertingEventLogger.logAction).toHaveBeenNthCalledWith(1, generateActionOpts({})); - expect(alertingEventLogger.logAction).toHaveBeenNthCalledWith( - 2, - generateActionOpts({ id: '2', alertId: '2', alertGroup: 'recovered', uuid: '222-222' }) - ); + testAlertingEventLogCalls({ + activeAlerts: 1, + recoveredAlerts: 1, + triggeredActions: 2, + generatedActions: 2, + status: 'active', + logAlert: 2, + logAction: 2, + }); + expect(alertingEventLogger.logAlert).toHaveBeenNthCalledWith( + 1, + generateAlertOpts({ + action: EVENT_LOG_ACTIONS.recoveredInstance, + id: '2', + state: { + bar: false, + start: '1969-12-31T06:00:00.000Z', + duration: '64800000000000', + end: DATE_1970, + }, + }) + ); + expect(alertingEventLogger.logAlert).toHaveBeenNthCalledWith( + 2, + generateAlertOpts({ + action: EVENT_LOG_ACTIONS.activeInstance, + group: 'default', + state: { bar: false, start: DATE_1969, duration: MOCK_DURATION }, + }) + ); + expect(alertingEventLogger.logAction).toHaveBeenNthCalledWith(1, generateActionOpts({})); + expect(alertingEventLogger.logAction).toHaveBeenNthCalledWith( + 2, + generateActionOpts({ id: '2', alertId: '2', alertGroup: 'recovered', uuid: '222-222' }) + ); - expect(enqueueFunction).toHaveBeenCalledTimes(isBulk ? 1 : 2); - expect(enqueueFunction).toHaveBeenCalledWith( - isBulk - ? [ - generateEnqueueFunctionInput({ isBulk: false, id: '1', foo: true }), - generateEnqueueFunctionInput({ - isBulk: false, - id: '2', - isResolved: true, - uuid: '222-222', - }), - ] - : generateEnqueueFunctionInput({ isBulk: false, id: '1', foo: true }) - ); - expect(mockUsageCounter.incrementCounter).not.toHaveBeenCalled(); - jest.resetAllMocks(); - } - ); + expect(actionsClient.bulkEnqueueExecution).toHaveBeenCalledTimes(1); + expect(actionsClient.bulkEnqueueExecution).toHaveBeenCalledWith([ + generateEnqueueFunctionInput({ isBulk: false, id: '1', foo: true }), + generateEnqueueFunctionInput({ + isBulk: false, + id: '2', + isResolved: true, + uuid: '222-222', + }), + ]); + expect(mockUsageCounter.incrementCounter).not.toHaveBeenCalled(); + jest.resetAllMocks(); + }); - test.each(ephemeralTestParams)( - "should skip alertInstances which weren't active on the previous execution %s", - async (nameExtension, customTaskRunnerFactoryInitializerParams, enqueueFunction, isBulk) => { - customTaskRunnerFactoryInitializerParams.actionsPlugin.isActionTypeEnabled.mockReturnValue( - true - ); - customTaskRunnerFactoryInitializerParams.actionsPlugin.isActionExecutable.mockReturnValue( - true - ); - actionsClient.ephemeralEnqueuedExecution.mockResolvedValue(mockRunNowResponse); + test("should skip alertInstances which weren't active on the previous execution", async () => { + taskRunnerFactoryInitializerParams.actionsPlugin.isActionTypeEnabled.mockReturnValue(true); + taskRunnerFactoryInitializerParams.actionsPlugin.isActionExecutable.mockReturnValue(true); - ruleType.executor.mockImplementation( - async ({ - services: executorServices, - }: RuleExecutorOptions< - RuleTypeParams, - RuleTypeState, - AlertInstanceState, - AlertInstanceContext, - string, - RuleAlertData - >) => { - executorServices.alertFactory.create('1').scheduleActions('default'); + ruleType.executor.mockImplementation( + async ({ + services: executorServices, + }: RuleExecutorOptions< + RuleTypeParams, + RuleTypeState, + AlertInstanceState, + AlertInstanceContext, + string, + RuleAlertData + >) => { + executorServices.alertFactory.create('1').scheduleActions('default'); - // create an instance, but don't schedule any actions, so it doesn't go active - executorServices.alertFactory.create('3'); - return { state: {} }; - } - ); - const taskRunner = new TaskRunner({ - ruleType, - internalSavedObjectsRepository, - taskInstance: { - ...mockedTaskInstance, - state: { - ...mockedTaskInstance.state, - alertInstances: { - '1': { meta: {}, state: { bar: false } }, - '2': { meta: {}, state: { bar: false } }, - }, + // create an instance, but don't schedule any actions, so it doesn't go active + executorServices.alertFactory.create('3'); + return { state: {} }; + } + ); + const taskRunner = new TaskRunner({ + ruleType, + internalSavedObjectsRepository, + taskInstance: { + ...mockedTaskInstance, + state: { + ...mockedTaskInstance.state, + alertInstances: { + '1': { meta: {}, state: { bar: false } }, + '2': { meta: {}, state: { bar: false } }, }, }, - context: customTaskRunnerFactoryInitializerParams, - inMemoryMetrics, - }); - expect(AlertingEventLogger).toHaveBeenCalled(); - - mockGetAlertFromRaw.mockReturnValue(mockedRuleTypeSavedObject as Rule); - encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValue(mockedRawRuleSO); - const runnerResult = await taskRunner.run(); - expect(runnerResult.state.alertInstances).toEqual( - generateAlertInstance({ - id: 1, - flappingHistory: [false], - }) - ); + }, + context: taskRunnerFactoryInitializerParams, + inMemoryMetrics, + }); + expect(AlertingEventLogger).toHaveBeenCalled(); - expect(logger.debug).toHaveBeenCalledWith( - `rule test:1: '${RULE_NAME}' has 1 active alerts: [{\"instanceId\":\"1\",\"actionGroup\":\"default\"}]`, - { tags: ['1', 'test'] } - ); + mockGetAlertFromRaw.mockReturnValue(mockedRuleTypeSavedObject as Rule); + encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValue(mockedRawRuleSO); + const runnerResult = await taskRunner.run(); + expect(runnerResult.state.alertInstances).toEqual( + generateAlertInstance({ + id: 1, + flappingHistory: [false], + }) + ); - expect(logger.debug).nthCalledWith( - 3, - `rule test:1: '${RULE_NAME}' has 1 recovered alerts: [\"2\"]`, - { tags: ['1', 'test'] } - ); - expect(logger.debug).nthCalledWith( - 4, - `deprecated ruleRunStatus for test:1: {"lastExecutionDate":"1970-01-01T00:00:00.000Z","status":"active"}`, - { tags: ['1', 'test'] } - ); - expect(logger.debug).nthCalledWith( - 5, - 'ruleRunStatus for test:1: {"outcome":"succeeded","outcomeOrder":0,"outcomeMsg":null,"warning":null,"alertsCount":{"active":1,"new":0,"recovered":1,"ignored":0}}', - { tags: ['1', 'test'] } - ); - expect(logger.debug).nthCalledWith( - 6, - `ruleRunMetrics for test:1: {"numSearches":3,"totalSearchDurationMs":23423,"esSearchDurationMs":33,"numberOfTriggeredActions":2,"numberOfGeneratedActions":2,"numberOfActiveAlerts":1,"numberOfRecoveredAlerts":1,"numberOfNewAlerts":0,"numberOfDelayedAlerts":0,"hasReachedAlertLimit":false,"hasReachedQueuedActionsLimit":false,"triggeredActionsStatus":"complete"}`, - { tags: ['1', 'test'] } - ); + expect(logger.debug).toHaveBeenCalledWith( + `rule test:1: '${RULE_NAME}' has 1 active alerts: [{\"instanceId\":\"1\",\"actionGroup\":\"default\"}]`, + { tags: ['1', 'test'] } + ); - testAlertingEventLogCalls({ - activeAlerts: 1, - recoveredAlerts: 1, - triggeredActions: 2, - generatedActions: 2, - status: 'active', - logAlert: 2, - logAction: 2, - }); + expect(logger.debug).nthCalledWith( + 3, + `rule test:1: '${RULE_NAME}' has 1 recovered alerts: [\"2\"]`, + { tags: ['1', 'test'] } + ); + expect(logger.debug).nthCalledWith( + 4, + `deprecated ruleRunStatus for test:1: {"lastExecutionDate":"1970-01-01T00:00:00.000Z","status":"active"}`, + { tags: ['1', 'test'] } + ); + expect(logger.debug).nthCalledWith( + 5, + 'ruleRunStatus for test:1: {"outcome":"succeeded","outcomeOrder":0,"outcomeMsg":null,"warning":null,"alertsCount":{"active":1,"new":0,"recovered":1,"ignored":0}}', + { tags: ['1', 'test'] } + ); + expect(logger.debug).nthCalledWith( + 6, + `ruleRunMetrics for test:1: {"numSearches":3,"totalSearchDurationMs":23423,"esSearchDurationMs":33,"numberOfTriggeredActions":2,"numberOfGeneratedActions":2,"numberOfActiveAlerts":1,"numberOfRecoveredAlerts":1,"numberOfNewAlerts":0,"numberOfDelayedAlerts":0,"hasReachedAlertLimit":false,"hasReachedQueuedActionsLimit":false,"triggeredActionsStatus":"complete"}`, + { tags: ['1', 'test'] } + ); - expect(enqueueFunction).toHaveBeenCalledTimes(isBulk ? 1 : 2); - if (isBulk) { - expect((enqueueFunction as jest.Mock).mock.calls[0][0][0].id).toEqual('1'); - expect((enqueueFunction as jest.Mock).mock.calls[0][0][1].id).toEqual('2'); - } else { - expect((enqueueFunction as jest.Mock).mock.calls[0][0].id).toEqual('1'); - expect((enqueueFunction as jest.Mock).mock.calls[1][0].id).toEqual('2'); - } - expect(mockUsageCounter.incrementCounter).not.toHaveBeenCalled(); - } - ); + testAlertingEventLogCalls({ + activeAlerts: 1, + recoveredAlerts: 1, + triggeredActions: 2, + generatedActions: 2, + status: 'active', + logAlert: 2, + logAction: 2, + }); - test.each(ephemeralTestParams)( - 'fire actions under a custom recovery group when specified on an alert type for alertInstances which are in the recovered state %s', - async (nameExtension, customTaskRunnerFactoryInitializerParams, enqueueFunction, isBulk) => { - customTaskRunnerFactoryInitializerParams.actionsPlugin.isActionTypeEnabled.mockReturnValue( - true - ); - customTaskRunnerFactoryInitializerParams.actionsPlugin.isActionExecutable.mockReturnValue( - true - ); + expect(actionsClient.bulkEnqueueExecution).toHaveBeenCalledTimes(1); + expect((actionsClient.bulkEnqueueExecution as jest.Mock).mock.calls[0][0][0].id).toEqual('1'); + expect((actionsClient.bulkEnqueueExecution as jest.Mock).mock.calls[0][0][1].id).toEqual('2'); + expect(mockUsageCounter.incrementCounter).not.toHaveBeenCalled(); + }); - actionsClient.ephemeralEnqueuedExecution.mockResolvedValue(mockRunNowResponse); + test('fire actions under a custom recovery group when specified on an alert type for alertInstances which are in the recovered state', async () => { + taskRunnerFactoryInitializerParams.actionsPlugin.isActionTypeEnabled.mockReturnValue(true); + taskRunnerFactoryInitializerParams.actionsPlugin.isActionExecutable.mockReturnValue(true); - const recoveryActionGroup = { - id: 'customRecovered', - name: 'Custom Recovered', - }; - const ruleTypeWithCustomRecovery = { - ...ruleType, - recoveryActionGroup, - actionGroups: [{ id: 'default', name: 'Default' }, recoveryActionGroup], - }; + const recoveryActionGroup = { + id: 'customRecovered', + name: 'Custom Recovered', + }; + const ruleTypeWithCustomRecovery = { + ...ruleType, + recoveryActionGroup, + actionGroups: [{ id: 'default', name: 'Default' }, recoveryActionGroup], + }; - ruleTypeWithCustomRecovery.executor.mockImplementation( - async ({ - services: executorServices, - }: RuleExecutorOptions< - RuleTypeParams, - RuleTypeState, - AlertInstanceState, - AlertInstanceContext, - string, - RuleAlertData - >) => { - executorServices.alertFactory.create('1').scheduleActions('default'); - return { state: {} }; - } - ); - const taskRunner = new TaskRunner({ - ruleType: ruleTypeWithCustomRecovery, - internalSavedObjectsRepository, - taskInstance: { - ...mockedTaskInstance, - state: { - ...mockedTaskInstance.state, - alertInstances: { - '1': { meta: {}, state: { bar: false } }, - '2': { meta: {}, state: { bar: false } }, - }, + ruleTypeWithCustomRecovery.executor.mockImplementation( + async ({ + services: executorServices, + }: RuleExecutorOptions< + RuleTypeParams, + RuleTypeState, + AlertInstanceState, + AlertInstanceContext, + string, + RuleAlertData + >) => { + executorServices.alertFactory.create('1').scheduleActions('default'); + return { state: {} }; + } + ); + const taskRunner = new TaskRunner({ + ruleType: ruleTypeWithCustomRecovery, + internalSavedObjectsRepository, + taskInstance: { + ...mockedTaskInstance, + state: { + ...mockedTaskInstance.state, + alertInstances: { + '1': { meta: {}, state: { bar: false } }, + '2': { meta: {}, state: { bar: false } }, }, }, - context: customTaskRunnerFactoryInitializerParams, - inMemoryMetrics, - }); - expect(AlertingEventLogger).toHaveBeenCalled(); + }, + context: taskRunnerFactoryInitializerParams, + inMemoryMetrics, + }); + expect(AlertingEventLogger).toHaveBeenCalled(); - mockGetAlertFromRaw.mockReturnValue({ - ...(mockedRuleTypeSavedObject as Rule), - actions: [ - { - group: 'default', - id: '1', - actionTypeId: 'action', - params: { - foo: true, - }, - uuid: '111-111', + mockGetAlertFromRaw.mockReturnValue({ + ...(mockedRuleTypeSavedObject as Rule), + actions: [ + { + group: 'default', + id: '1', + actionTypeId: 'action', + params: { + foo: true, }, - { - group: recoveryActionGroup.id, - id: '2', - actionTypeId: 'action', - params: { - isResolved: true, - }, - uuid: '222-222', + uuid: '111-111', + }, + { + group: recoveryActionGroup.id, + id: '2', + actionTypeId: 'action', + params: { + isResolved: true, }, - ], - }); - encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValue(mockedRawRuleSO); - const runnerResult = await taskRunner.run(); - expect(runnerResult.state.alertInstances).toEqual( - generateAlertInstance({ - id: 1, - flappingHistory: [false], - }) - ); + uuid: '222-222', + }, + ], + }); + encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValue(mockedRawRuleSO); + const runnerResult = await taskRunner.run(); + expect(runnerResult.state.alertInstances).toEqual( + generateAlertInstance({ + id: 1, + flappingHistory: [false], + }) + ); - testAlertingEventLogCalls({ - ruleTypeDef: ruleTypeWithCustomRecovery, - activeAlerts: 1, - recoveredAlerts: 1, - triggeredActions: 2, - generatedActions: 2, - status: 'active', - logAlert: 2, - logAction: 2, - }); + testAlertingEventLogCalls({ + ruleTypeDef: ruleTypeWithCustomRecovery, + activeAlerts: 1, + recoveredAlerts: 1, + triggeredActions: 2, + generatedActions: 2, + status: 'active', + logAlert: 2, + logAction: 2, + }); - expect(enqueueFunction).toHaveBeenCalledTimes(isBulk ? 1 : 2); - expect(enqueueFunction).toHaveBeenCalledWith( - isBulk - ? [ - generateEnqueueFunctionInput({ isBulk: false, id: '1', foo: true }), - generateEnqueueFunctionInput({ - isBulk: false, - id: '2', - isResolved: true, - uuid: '222-222', - }), - ] - : generateEnqueueFunctionInput({ isBulk: false, id: '1', foo: true }) - ); - expect(mockUsageCounter.incrementCounter).not.toHaveBeenCalled(); - } - ); + expect(actionsClient.bulkEnqueueExecution).toHaveBeenCalledTimes(1); + expect(actionsClient.bulkEnqueueExecution).toHaveBeenCalledWith([ + generateEnqueueFunctionInput({ isBulk: false, id: '1', foo: true }), + generateEnqueueFunctionInput({ + isBulk: false, + id: '2', + isResolved: true, + uuid: '222-222', + }), + ]); + expect(mockUsageCounter.incrementCounter).not.toHaveBeenCalled(); + }); - test.each(ephemeralTestParams)( - 'triggers summary actions (Per rule run)', - async (nameExtension, customTaskRunnerFactoryInitializerParams, enqueueFunction, isBulk) => { - customTaskRunnerFactoryInitializerParams.actionsPlugin.isActionTypeEnabled.mockReturnValue( - true - ); - customTaskRunnerFactoryInitializerParams.actionsPlugin.isActionExecutable.mockReturnValue( - true - ); - actionsClient.ephemeralEnqueuedExecution.mockResolvedValue(mockRunNowResponse); - ruleType.executor.mockImplementation(async () => { - return { state: {} }; - }); + test('triggers summary actions (Per rule run)', async () => { + taskRunnerFactoryInitializerParams.actionsPlugin.isActionTypeEnabled.mockReturnValue(true); + taskRunnerFactoryInitializerParams.actionsPlugin.isActionExecutable.mockReturnValue(true); + ruleType.executor.mockImplementation(async () => { + return { state: {} }; + }); - alertsClient.getProcessedAlerts.mockReturnValue({}); - alertsClient.getSummarizedAlerts.mockResolvedValue({ - new: { - count: 1, - data: [mockAAD], - }, - ongoing: { count: 0, data: [] }, - recovered: { count: 0, data: [] }, - }); - alertsService.createAlertsClient.mockImplementation(() => alertsClient); + alertsClient.getProcessedAlerts.mockReturnValue({}); + alertsClient.getSummarizedAlerts.mockResolvedValue({ + new: { + count: 1, + data: [mockAAD], + }, + ongoing: { count: 0, data: [] }, + recovered: { count: 0, data: [] }, + }); + alertsService.createAlertsClient.mockImplementation(() => alertsClient); - const taskRunner = new TaskRunner({ - ruleType, - internalSavedObjectsRepository, - taskInstance: mockedTaskInstance, - context: customTaskRunnerFactoryInitializerParams, - inMemoryMetrics, - }); - expect(AlertingEventLogger).toHaveBeenCalledTimes(1); + const taskRunner = new TaskRunner({ + ruleType, + internalSavedObjectsRepository, + taskInstance: mockedTaskInstance, + context: taskRunnerFactoryInitializerParams, + inMemoryMetrics, + }); + expect(AlertingEventLogger).toHaveBeenCalledTimes(1); - mockGetAlertFromRaw.mockReturnValue({ - ...(mockedRuleTypeSavedObject as Rule), - actions: [ - { - group: 'default', - id: '1', - actionTypeId: 'slack', - frequency: { - notifyWhen: 'onActiveAlert', - summary: true, - throttle: null, - }, - params: { - foo: true, - }, - uuid: '111-111', + mockGetAlertFromRaw.mockReturnValue({ + ...(mockedRuleTypeSavedObject as Rule), + actions: [ + { + group: 'default', + id: '1', + actionTypeId: 'slack', + frequency: { + notifyWhen: 'onActiveAlert', + summary: true, + throttle: null, }, - ], - }); - encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValue(mockedRawRuleSO); - await taskRunner.run(); + params: { + foo: true, + }, + uuid: '111-111', + }, + ], + }); + encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValue(mockedRawRuleSO); + await taskRunner.run(); - expect(enqueueFunction).toHaveBeenCalledTimes(1); - expect(enqueueFunction).toHaveBeenCalledWith( - generateEnqueueFunctionInput({ isBulk, id: '1', foo: true, actionTypeId: 'slack' }) - ); - } - ); + expect(actionsClient.bulkEnqueueExecution).toHaveBeenCalledTimes(1); + expect(actionsClient.bulkEnqueueExecution).toHaveBeenCalledWith( + generateEnqueueFunctionInput({ isBulk: true, id: '1', foo: true, actionTypeId: 'slack' }) + ); + }); - test.each(ephemeralTestParams)( - 'triggers summary actions (Custom Frequency)', - async (nameExtension, customTaskRunnerFactoryInitializerParams, enqueueFunction, isBulk) => { - customTaskRunnerFactoryInitializerParams.actionsPlugin.isActionTypeEnabled.mockReturnValue( - true - ); - customTaskRunnerFactoryInitializerParams.actionsPlugin.isActionExecutable.mockReturnValue( - true - ); - actionsClient.ephemeralEnqueuedExecution.mockResolvedValue(mockRunNowResponse); - ruleType.executor.mockImplementation(async () => { - return { state: {} }; - }); - alertsClient.getProcessedAlerts.mockReturnValue({}); - alertsClient.getSummarizedAlerts.mockResolvedValue({ - new: { - count: 1, - data: [mockAAD], - }, - ongoing: { count: 0, data: [] }, - recovered: { count: 0, data: [] }, - }); + test('triggers summary actions (Custom Frequency)', async () => { + taskRunnerFactoryInitializerParams.actionsPlugin.isActionTypeEnabled.mockReturnValue(true); + taskRunnerFactoryInitializerParams.actionsPlugin.isActionExecutable.mockReturnValue(true); + ruleType.executor.mockImplementation(async () => { + return { state: {} }; + }); + alertsClient.getProcessedAlerts.mockReturnValue({}); + alertsClient.getSummarizedAlerts.mockResolvedValue({ + new: { + count: 1, + data: [mockAAD], + }, + ongoing: { count: 0, data: [] }, + recovered: { count: 0, data: [] }, + }); - alertsClient.getAlertsToSerialize.mockResolvedValueOnce({ state: {}, meta: {} }); - alertsService.createAlertsClient.mockImplementation(() => alertsClient); + alertsClient.getAlertsToSerialize.mockResolvedValueOnce({ state: {}, meta: {} }); + alertsService.createAlertsClient.mockImplementation(() => alertsClient); - const taskRunner = new TaskRunner({ - ruleType, - internalSavedObjectsRepository, - taskInstance: mockedTaskInstance, - context: customTaskRunnerFactoryInitializerParams, - inMemoryMetrics, - }); - expect(AlertingEventLogger).toHaveBeenCalledTimes(1); + const taskRunner = new TaskRunner({ + ruleType, + internalSavedObjectsRepository, + taskInstance: mockedTaskInstance, + context: taskRunnerFactoryInitializerParams, + inMemoryMetrics, + }); + expect(AlertingEventLogger).toHaveBeenCalledTimes(1); - mockGetAlertFromRaw.mockReturnValue({ - ...(mockedRuleTypeSavedObject as Rule), - actions: [ - { - group: 'default', - id: '1', - actionTypeId: 'slack', - frequency: { - notifyWhen: 'onThrottleInterval', - summary: true, - throttle: '1h', - }, - params: { - foo: true, - }, - uuid: '111-111', + mockGetAlertFromRaw.mockReturnValue({ + ...(mockedRuleTypeSavedObject as Rule), + actions: [ + { + group: 'default', + id: '1', + actionTypeId: 'slack', + frequency: { + notifyWhen: 'onThrottleInterval', + summary: true, + throttle: '1h', }, - ], - }); + params: { + foo: true, + }, + uuid: '111-111', + }, + ], + }); - encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValue(mockedRawRuleSO); - const result = await taskRunner.run(); - - expect(alertsClient.getSummarizedAlerts).toHaveBeenCalledWith({ - start: new Date('1969-12-31T23:00:00.000Z'), - end: new Date(DATE_1970), - ruleId: '1', - spaceId: 'default', - excludedAlertInstanceIds: [], - }); + encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValue(mockedRawRuleSO); + const result = await taskRunner.run(); - expect(enqueueFunction).toHaveBeenCalledTimes(1); - expect(enqueueFunction).toHaveBeenCalledWith( - generateEnqueueFunctionInput({ isBulk, id: '1', foo: true, actionTypeId: 'slack' }) - ); - expect(result.state.summaryActions).toEqual({ - '111-111': { date: new Date(DATE_1970).toISOString() }, - }); - } - ); + expect(alertsClient.getSummarizedAlerts).toHaveBeenCalledWith({ + start: new Date('1969-12-31T23:00:00.000Z'), + end: new Date(DATE_1970), + ruleId: '1', + spaceId: 'default', + excludedAlertInstanceIds: [], + }); + + expect(actionsClient.bulkEnqueueExecution).toHaveBeenCalledTimes(1); + expect(actionsClient.bulkEnqueueExecution).toHaveBeenCalledWith( + generateEnqueueFunctionInput({ isBulk: true, id: '1', foo: true, actionTypeId: 'slack' }) + ); + expect(result.state.summaryActions).toEqual({ + '111-111': { date: new Date(DATE_1970).toISOString() }, + }); + }); test('persists alertInstances passed in from state, only if they are scheduled for execution', async () => { ruleType.executor.mockImplementation( @@ -2629,7 +2505,6 @@ describe('Task Runner', () => { }, context: { ...taskRunnerFactoryInitializerParams, - supportsEphemeralTasks: true, }, inMemoryMetrics, }); diff --git a/x-pack/plugins/alerting/server/task_runner/task_runner_alerts_client.test.ts b/x-pack/plugins/alerting/server/task_runner/task_runner_alerts_client.test.ts index ed8e4a1259e6c..3d0cd5ab05059 100644 --- a/x-pack/plugins/alerting/server/task_runner/task_runner_alerts_client.test.ts +++ b/x-pack/plugins/alerting/server/task_runner/task_runner_alerts_client.test.ts @@ -216,13 +216,11 @@ describe('Task Runner', () => { logger, maintenanceWindowsService, maxAlerts: 1000, - maxEphemeralActionsPerRule: 10, ruleTypeRegistry, rulesSettingsService, savedObjects: savedObjectsService, share: {} as SharePluginStart, spaceIdToNamespace: jest.fn().mockReturnValue(undefined), - supportsEphemeralTasks: false, uiSettings: uiSettingsService, usageCounter: mockUsageCounter, isServerless: false, diff --git a/x-pack/plugins/alerting/server/task_runner/task_runner_cancel.test.ts b/x-pack/plugins/alerting/server/task_runner/task_runner_cancel.test.ts index 066cff2944f26..54faa13de8352 100644 --- a/x-pack/plugins/alerting/server/task_runner/task_runner_cancel.test.ts +++ b/x-pack/plugins/alerting/server/task_runner/task_runner_cancel.test.ts @@ -149,13 +149,11 @@ describe('Task Runner Cancel', () => { logger, maintenanceWindowsService, maxAlerts: 1000, - maxEphemeralActionsPerRule: 10, ruleTypeRegistry, rulesSettingsService, savedObjects: savedObjectsService, share: {} as SharePluginStart, spaceIdToNamespace: jest.fn().mockReturnValue(undefined), - supportsEphemeralTasks: false, uiSettings: uiSettingsService, usageCounter: mockUsageCounter, isServerless: false, diff --git a/x-pack/plugins/alerting/server/task_runner/task_runner_factory.test.ts b/x-pack/plugins/alerting/server/task_runner/task_runner_factory.test.ts index 7aa0105f7c06e..94acd3a0b2db6 100644 --- a/x-pack/plugins/alerting/server/task_runner/task_runner_factory.test.ts +++ b/x-pack/plugins/alerting/server/task_runner/task_runner_factory.test.ts @@ -120,13 +120,11 @@ describe('Task Runner Factory', () => { logger: loggingSystemMock.create().get(), maintenanceWindowsService, maxAlerts: 1000, - maxEphemeralActionsPerRule: 10, ruleTypeRegistry: ruleTypeRegistryMock.create(), rulesSettingsService, savedObjects: savedObjectsService, share: {} as SharePluginStart, spaceIdToNamespace: jest.fn().mockReturnValue(undefined), - supportsEphemeralTasks: true, uiSettings: uiSettingsService, usageCounter: mockUsageCounter, isServerless: false, diff --git a/x-pack/plugins/alerting/server/task_runner/types.ts b/x-pack/plugins/alerting/server/task_runner/types.ts index b401155ab06d7..f3e08aff2c3b7 100644 --- a/x-pack/plugins/alerting/server/task_runner/types.ts +++ b/x-pack/plugins/alerting/server/task_runner/types.ts @@ -172,13 +172,11 @@ export interface TaskRunnerContext { logger: Logger; maintenanceWindowsService: MaintenanceWindowsService; maxAlerts: number; - maxEphemeralActionsPerRule: number; ruleTypeRegistry: RuleTypeRegistry; rulesSettingsService: RulesSettingsService; savedObjects: SavedObjectsServiceStart; share: SharePluginStart; spaceIdToNamespace: SpaceIdToNamespaceFunction; - supportsEphemeralTasks: boolean; uiSettings: UiSettingsServiceStart; usageCounter?: UsageCounter; isServerless: boolean; diff --git a/x-pack/plugins/alerting/server/test_utils/index.ts b/x-pack/plugins/alerting/server/test_utils/index.ts index 036454f2f80c6..401225f171f06 100644 --- a/x-pack/plugins/alerting/server/test_utils/index.ts +++ b/x-pack/plugins/alerting/server/test_utils/index.ts @@ -57,7 +57,6 @@ export function generateAlertingConfig(): AlertingConfig { interval: '5m', removalDelay: '1h', }, - maxEphemeralActionsPerAlert: 10, cancelAlertsOnRuleTimeout: true, rules: { maxScheduledPerMinute: 10000, diff --git a/x-pack/plugins/alerting/server/types.ts b/x-pack/plugins/alerting/server/types.ts index c7ef8f563843c..4c3d9ee57f51d 100644 --- a/x-pack/plugins/alerting/server/types.ts +++ b/x-pack/plugins/alerting/server/types.ts @@ -29,7 +29,7 @@ import { Alert } from '@kbn/alerts-as-data-utils'; import { ActionsApiRequestHandlerContext } from '@kbn/actions-plugin/server'; import { AlertsHealth } from '@kbn/alerting-types'; import { RuleTypeRegistry as OrigruleTypeRegistry } from './rule_type_registry'; -import { PluginSetupContract, PluginStartContract } from './plugin'; +import { AlertingServerSetup, AlertingServerStart } from './plugin'; import { RulesClient } from './rules_client'; import { RulesSettingsClient, @@ -62,7 +62,7 @@ export type { RuleTypeParams }; * @public */ export interface AlertingApiRequestHandlerContext { - getRulesClient: () => RulesClient; + getRulesClient: () => Promise; getRulesSettingsClient: (withoutAuth?: boolean) => RulesSettingsClient; getMaintenanceWindowClient: () => MaintenanceWindowClient; listTypes: RuleTypeRegistry['list']; @@ -362,8 +362,8 @@ export type PartialRuleWithLegacyId = Pic Partial, 'id'>>; export interface AlertingPlugin { - setup: PluginSetupContract; - start: PluginStartContract; + setup: AlertingServerSetup; + start: AlertingServerStart; } export interface AlertsConfigType { diff --git a/x-pack/plugins/alerting/tsconfig.json b/x-pack/plugins/alerting/tsconfig.json index d261a00db74ca..6019f8711d681 100644 --- a/x-pack/plugins/alerting/tsconfig.json +++ b/x-pack/plugins/alerting/tsconfig.json @@ -70,9 +70,11 @@ "@kbn/search-types", "@kbn/alerting-state-types", "@kbn/core-security-server", + "@kbn/security-plugin-types-server", "@kbn/core-http-server", "@kbn/zod", "@kbn/core-saved-objects-base-server-internal", + "@kbn/core-security-server-mocks", "@kbn/response-ops-rule-params", "@kbn/core-http-server-utils" ], diff --git a/x-pack/plugins/asset_inventory/README.md b/x-pack/plugins/asset_inventory/README.md new file mode 100755 index 0000000000000..e1dd9d4ac8900 --- /dev/null +++ b/x-pack/plugins/asset_inventory/README.md @@ -0,0 +1,13 @@ +# Asset Inventory Kibana Plugin + +Centralized asset inventory experience within the Elastic Security solution. A central place for users to view and manage all their assets from different environments. + +--- + +## Development + +See the [kibana contributing guide](https://github.com/elastic/kibana/blob/main/CONTRIBUTING.md) for instructions setting up your development environment. + +## Testing + +For general guidelines, read [Kibana Testing Guide](https://www.elastic.co/guide/en/kibana/current/development-tests.html) for more details diff --git a/x-pack/plugins/asset_inventory/common/index.ts b/x-pack/plugins/asset_inventory/common/index.ts new file mode 100644 index 0000000000000..9f5311be877cc --- /dev/null +++ b/x-pack/plugins/asset_inventory/common/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 const PLUGIN_ID = 'assetInventory'; +export const PLUGIN_NAME = 'assetInventory'; diff --git a/x-pack/plugins/asset_inventory/kibana.jsonc b/x-pack/plugins/asset_inventory/kibana.jsonc new file mode 100644 index 0000000000000..dbb813be7aa4e --- /dev/null +++ b/x-pack/plugins/asset_inventory/kibana.jsonc @@ -0,0 +1,17 @@ +{ + "type": "plugin", + "id": "@kbn/asset-inventory-plugin", + "owner": ["@elastic/kibana-cloud-security-posture"], + "group": "security", + "visibility": "private", + "description": "Centralized asset inventory experience within the Elastic Security solution. A central place for users to view and manage all their assets from different environments", + "plugin": { + "id": "assetInventory", + "browser": true, + "server": true, + "configPath": ["xpack", "assetInventory"], + "requiredPlugins": [], + "requiredBundles": [], + "optionalPlugins": [] + } +} diff --git a/x-pack/plugins/asset_inventory/package.json b/x-pack/plugins/asset_inventory/package.json new file mode 100644 index 0000000000000..7abfb7bf63378 --- /dev/null +++ b/x-pack/plugins/asset_inventory/package.json @@ -0,0 +1,7 @@ +{ + "author": "Elastic", + "name": "@kbn/asset-inventory-plugin", + "version": "1.0.0", + "private": true, + "license": "Elastic License 2.0" +} diff --git a/x-pack/plugins/asset_inventory/public/application.tsx b/x-pack/plugins/asset_inventory/public/application.tsx new file mode 100644 index 0000000000000..f442f01d17f7c --- /dev/null +++ b/x-pack/plugins/asset_inventory/public/application.tsx @@ -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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import React from 'react'; +import ReactDOM from 'react-dom'; +import type { AppMountParameters, CoreStart } from '@kbn/core/public'; +import type { AppPluginStartDependencies } from './types'; +import { AssetInventoryApp } from './components/app'; + +export const renderApp = ( + { notifications, http }: CoreStart, + {}: AppPluginStartDependencies, + { appBasePath, element }: AppMountParameters +) => { + ReactDOM.render( + , + element + ); + + return () => ReactDOM.unmountComponentAtNode(element); +}; diff --git a/x-pack/plugins/asset_inventory/public/components/app.tsx b/x-pack/plugins/asset_inventory/public/components/app.tsx new file mode 100644 index 0000000000000..924091034353b --- /dev/null +++ b/x-pack/plugins/asset_inventory/public/components/app.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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import React from 'react'; +import { FormattedMessage, I18nProvider } from '@kbn/i18n-react'; +import { BrowserRouter as Router } from '@kbn/shared-ux-router'; +import { EuiPageTemplate, EuiTitle } from '@elastic/eui'; +import type { CoreStart } from '@kbn/core/public'; + +interface AssetInventoryAppDeps { + basename: string; + notifications: CoreStart['notifications']; + http: CoreStart['http']; +} + +export const AssetInventoryApp = ({ basename }: AssetInventoryAppDeps) => { + return ( + + + <> + + + +

        + +

        +
        +
        + +
        + +
        +
        + ); +}; diff --git a/x-pack/plugins/asset_inventory/public/index.ts b/x-pack/plugins/asset_inventory/public/index.ts new file mode 100644 index 0000000000000..269cab2ad181a --- /dev/null +++ b/x-pack/plugins/asset_inventory/public/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. + */ +import { AssetInventoryPlugin } from './plugin'; + +// This exports static code and TypeScript types, +// as well as, Kibana Platform `plugin()` initializer. +export function plugin() { + return new AssetInventoryPlugin(); +} +export type { AssetInventoryPluginSetup, AssetInventoryPluginStart } from './types'; diff --git a/x-pack/plugins/asset_inventory/public/plugin.ts b/x-pack/plugins/asset_inventory/public/plugin.ts new file mode 100644 index 0000000000000..fd2841f5b2335 --- /dev/null +++ b/x-pack/plugins/asset_inventory/public/plugin.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 type { AppMountParameters, CoreSetup, CoreStart, Plugin } from '@kbn/core/public'; +import type { + AssetInventoryPluginSetup, + AssetInventoryPluginStart, + AppPluginStartDependencies, +} from './types'; + +export class AssetInventoryPlugin + implements Plugin +{ + public setup(core: CoreSetup): AssetInventoryPluginSetup { + return {}; + } + public start( + coreStart: CoreStart, + depsStart: AppPluginStartDependencies + ): AssetInventoryPluginStart { + return { + getAssetInventoryPage: async (params: AppMountParameters) => { + // Load application bundle + const { renderApp } = await import('./application'); + // Render the application + return renderApp(coreStart, depsStart as AppPluginStartDependencies, params); + }, + }; + } + + public stop() {} +} diff --git a/x-pack/plugins/asset_inventory/public/types.ts b/x-pack/plugins/asset_inventory/public/types.ts new file mode 100644 index 0000000000000..a551b4d231c3d --- /dev/null +++ b/x-pack/plugins/asset_inventory/public/types.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. + */ + +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface AssetInventoryPluginSetup {} + +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface AssetInventoryPluginStart {} + +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface AppPluginStartDependencies {} diff --git a/x-pack/plugins/asset_inventory/server/create_transforms/create_transforms.ts b/x-pack/plugins/asset_inventory/server/create_transforms/create_transforms.ts new file mode 100644 index 0000000000000..0d3d0e8f8e0c4 --- /dev/null +++ b/x-pack/plugins/asset_inventory/server/create_transforms/create_transforms.ts @@ -0,0 +1,142 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor 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 { transformError } from '@kbn/securitysolution-es-utils'; +import { TransformPutTransformRequest } from '@elastic/elasticsearch/lib/api/types'; +import type { ElasticsearchClient, Logger } from '@kbn/core/server'; +import { errors } from '@elastic/elasticsearch'; + +// TODO: Move transforms to integration package +export const initializeTransforms = async ( + esClient: ElasticsearchClient, + logger: Logger +): Promise => { + // Deletes old assets from previous versions as part of upgrade process + await deletePreviousTransformsVersions(esClient, logger); + // TODO initialize transforms here + // await initializeTransform(esClient, , logger); +}; + +export const initializeTransform = async ( + esClient: ElasticsearchClient, + transform: TransformPutTransformRequest, + logger: Logger +) => { + const success = await createTransformIfNotExists(esClient, transform, logger); + + if (success) { + await startTransformIfNotStarted(esClient, transform.transform_id, logger); + } +}; + +/** + * Checks if a transform exists, And if not creates it + * + * @param transform - the transform to create. If a transform with the same transform_id already exists, nothing is created or updated. + * + * @return true if the transform exits or created, false otherwise. + */ +export const createTransformIfNotExists = async ( + esClient: ElasticsearchClient, + transform: TransformPutTransformRequest, + logger: Logger +) => { + try { + await esClient.transform.getTransform({ + transform_id: transform.transform_id, + }); + return true; + } catch (existErr) { + const existError = transformError(existErr); + if (existError.statusCode === 404) { + try { + await esClient.transform.putTransform(transform); + return true; + } catch (createErr) { + const createError = transformError(createErr); + logger.error( + `Failed to create transform ${transform.transform_id}: ${createError.message}` + ); + } + } else { + logger.error( + `Failed to check if transform ${transform.transform_id} exists: ${existError.message}` + ); + } + } + return false; +}; + +export const startTransformIfNotStarted = async ( + esClient: ElasticsearchClient, + transformId: string, + logger: Logger +) => { + try { + const transformStats = await esClient.transform.getTransformStats({ + transform_id: transformId, + }); + + if (transformStats.count <= 0) { + logger.error(`Failed starting transform ${transformId}: couldn't find transform`); + return; + } + + const fetchedTransformStats = transformStats.transforms[0]; + + // trying to restart the transform in case it comes to a full stop or failure + if (fetchedTransformStats.state === 'stopped' || fetchedTransformStats.state === 'failed') { + try { + return await esClient.transform.startTransform({ transform_id: transformId }); + } catch (startErr) { + const startError = transformError(startErr); + logger.error( + `Failed to start transform ${transformId}. Transform State: Transform State: ${fetchedTransformStats.state}. Error: ${startError.message}` + ); + } + } + + if (fetchedTransformStats.state === 'stopping' || fetchedTransformStats.state === 'aborting') { + logger.error( + `Not starting transform ${transformId} since it's state is: ${fetchedTransformStats.state}` + ); + } + } catch (statsErr) { + const statsError = transformError(statsErr); + logger.error(`Failed to check if transform ${transformId} is started: ${statsError.message}`); + } +}; + +const deletePreviousTransformsVersions = async (esClient: ElasticsearchClient, logger: Logger) => { + // TODO Concat all deprecated transforms versions + const deprecatedTransforms: string[] = []; + + for (const transform of deprecatedTransforms) { + const response = await deleteTransformSafe(esClient, logger, transform); + if (response) return; + } +}; + +const deleteTransformSafe = async ( + esClient: ElasticsearchClient, + logger: Logger, + name: string +): Promise => { + try { + await esClient.transform.deleteTransform({ transform_id: name, force: true }); + logger.info(`Deleted transform successfully [Name: ${name}]`); + return true; + } catch (e) { + if (e instanceof errors.ResponseError && e.statusCode === 404) { + logger.trace(`Transform not exists [Name: ${name}]`); + return false; + } else { + logger.error(`Failed to delete transform [Name: ${name}]`); + logger.error(e); + return false; + } + } +}; diff --git a/x-pack/plugins/asset_inventory/server/index.ts b/x-pack/plugins/asset_inventory/server/index.ts new file mode 100644 index 0000000000000..6306618078898 --- /dev/null +++ b/x-pack/plugins/asset_inventory/server/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 type { PluginInitializerContext } from '@kbn/core/server'; + +// This exports static code and TypeScript types, +// as well as, Kibana Platform `plugin()` initializer. + +export async function plugin(initializerContext: PluginInitializerContext) { + const { AssetInventoryPlugin } = await import('./plugin'); + return new AssetInventoryPlugin(initializerContext); +} + +export type { AssetInventoryPluginSetup, AssetInventoryPluginStart } from './types'; diff --git a/x-pack/plugins/asset_inventory/server/plugin.ts b/x-pack/plugins/asset_inventory/server/plugin.ts new file mode 100644 index 0000000000000..3f35991c379d5 --- /dev/null +++ b/x-pack/plugins/asset_inventory/server/plugin.ts @@ -0,0 +1,63 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor 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 { + PluginInitializerContext, + CoreSetup, + CoreStart, + Plugin, + Logger, +} from '@kbn/core/server'; + +import type { AssetInventoryPluginSetup, AssetInventoryPluginStart } from './types'; +import { defineRoutes } from './routes'; +// TODO Uncomment this line when initialize() is enabled +// import { initializeTransforms } from './create_transforms/create_transforms'; + +export class AssetInventoryPlugin + implements Plugin +{ + private readonly logger: Logger; + + // TODO Uncomment this line when initialize() is enabled + // private isInitialized: boolean = false; + + constructor(initializerContext: PluginInitializerContext) { + this.logger = initializerContext.logger.get(); + } + + public setup(core: CoreSetup) { + this.logger.debug('assetInventory: Setup'); + const router = core.http.createRouter(); + + // Register server side APIs + defineRoutes(router); + + return {}; + } + + public start(core: CoreStart) { + this.logger.debug('assetInventory: Started'); + + // TODO Invoke initialize() when it's due + // this.initialize(core).catch(() => {}); + + return {}; + } + + public stop() {} + + /** + * Initialization is idempotent and required for (re)creating indices and transforms. + */ + // TODO Uncomment these lines when initialize() is enabled + // async initialize(core: CoreStart): Promise { + // this.logger.debug('initialize'); + // const esClient = core.elasticsearch.client.asInternalUser; + // await initializeTransforms(esClient, this.logger); + // this.isInitialized = true; + // } +} diff --git a/x-pack/plugins/asset_inventory/server/routes/index.ts b/x-pack/plugins/asset_inventory/server/routes/index.ts new file mode 100644 index 0000000000000..f577bfa19f719 --- /dev/null +++ b/x-pack/plugins/asset_inventory/server/routes/index.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 { IRouter } from '@kbn/core/server'; + +export function defineRoutes(router: IRouter) { + router.get( + { + path: '/api/asset_inventory/example', + validate: false, + }, + async (context, request, response) => { + return response.ok({ + body: { + time: new Date().toISOString(), + }, + }); + } + ); +} diff --git a/x-pack/plugins/asset_inventory/server/types.ts b/x-pack/plugins/asset_inventory/server/types.ts new file mode 100644 index 0000000000000..1d9380e8514f8 --- /dev/null +++ b/x-pack/plugins/asset_inventory/server/types.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. + */ +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface AssetInventoryPluginSetup {} +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface AssetInventoryPluginStart {} diff --git a/x-pack/plugins/asset_inventory/tsconfig.json b/x-pack/plugins/asset_inventory/tsconfig.json new file mode 100644 index 0000000000000..dc669eb3a6943 --- /dev/null +++ b/x-pack/plugins/asset_inventory/tsconfig.json @@ -0,0 +1,23 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "outDir": "target/types" + }, + "include": [ + "common/**/*.ts", + "common/**/*.json", + "public/**/*.ts", + "public/**/*.tsx", + "public/**/*.json", + "server/**/*.ts", + "server/**/*.json", + "../../../typings/**/*" + ], + "exclude": ["target/**/*"], + "kbn_references": [ + "@kbn/core", + "@kbn/i18n-react", + "@kbn/shared-ux-router", + "@kbn/securitysolution-es-utils" + ] +} diff --git a/x-pack/plugins/cases/common/constants/owner.test.ts b/x-pack/plugins/cases/common/constants/owner.test.ts index 07b6866f857a4..b53f177dd7d29 100644 --- a/x-pack/plugins/cases/common/constants/owner.test.ts +++ b/x-pack/plugins/cases/common/constants/owner.test.ts @@ -10,7 +10,11 @@ import { OWNER_INFO } from './owners'; describe('OWNER_INFO', () => { it('should use all available rule consumers', () => { - const allConsumers = new Set(Object.values(AlertConsumers)); + const allConsumers = new Set( + // Alerts consumer fallbacks to producer so it is not counted as valid one + Object.values(AlertConsumers).filter((consumer) => consumer !== AlertConsumers.ALERTS) + ); + const ownersMappingConsumers = new Set( Object.values(OWNER_INFO) .map((value) => value.validRuleConsumers ?? []) diff --git a/x-pack/plugins/cases/common/constants/owners.ts b/x-pack/plugins/cases/common/constants/owners.ts index a7628628a7dcc..79db38345e566 100644 --- a/x-pack/plugins/cases/common/constants/owners.ts +++ b/x-pack/plugins/cases/common/constants/owners.ts @@ -59,6 +59,11 @@ export const OWNER_INFO: Record = { label: 'Management', iconType: 'managementApp', appRoute: '/app/management/insightsAndAlerting', - validRuleConsumers: [AlertConsumers.ML, AlertConsumers.STACK_ALERTS, AlertConsumers.EXAMPLE], + validRuleConsumers: [ + AlertConsumers.ML, + AlertConsumers.STACK_ALERTS, + AlertConsumers.EXAMPLE, + AlertConsumers.DISCOVER, + ], }, } as const; diff --git a/x-pack/plugins/cases/common/utils/owner.test.ts b/x-pack/plugins/cases/common/utils/owner.test.ts index a6f7c99f540bb..4e005750ad36f 100644 --- a/x-pack/plugins/cases/common/utils/owner.test.ts +++ b/x-pack/plugins/cases/common/utils/owner.test.ts @@ -40,7 +40,7 @@ describe('owner utils', () => { validRuleConsumers: item.validRuleConsumers, })); - it.each(owners)('returns owner %s correctly for consumer', (owner) => { + it.each(owners)('returns owner %j correctly for consumer', (owner) => { for (const consumer of owner.validRuleConsumers ?? []) { const result = getOwnerFromRuleConsumerProducer({ consumer }); @@ -48,7 +48,7 @@ describe('owner utils', () => { } }); - it.each(owners)('returns owner %s correctly for producer', (owner) => { + it.each(owners)('returns owner %j correctly for producer', (owner) => { for (const producer of owner.validRuleConsumers ?? []) { const result = getOwnerFromRuleConsumerProducer({ producer }); @@ -80,5 +80,14 @@ describe('owner utils', () => { expect(owner).toBe(OWNER_INFO.securitySolution.id); }); + + it('fallbacks to producer when the consumer is alerts', () => { + const owner = getOwnerFromRuleConsumerProducer({ + consumer: AlertConsumers.ALERTS, + producer: AlertConsumers.OBSERVABILITY, + }); + + expect(owner).toBe(OWNER_INFO.observability.id); + }); }); }); diff --git a/x-pack/plugins/cases/common/utils/owner.ts b/x-pack/plugins/cases/common/utils/owner.ts index 7bde7220233db..d159a3d55ee7a 100644 --- a/x-pack/plugins/cases/common/utils/owner.ts +++ b/x-pack/plugins/cases/common/utils/owner.ts @@ -5,6 +5,7 @@ * 2.0. */ +import { AlertConsumers } from '@kbn/rule-data-utils'; import { OWNER_INFO } from '../constants'; import type { Owner } from '../constants/types'; @@ -29,9 +30,12 @@ export const getOwnerFromRuleConsumerProducer = ({ return OWNER_INFO.securitySolution.id; } + // Fallback to producer if the consumer is alerts + const consumerValue = consumer === AlertConsumers.ALERTS ? producer : consumer; + for (const value of Object.values(OWNER_INFO)) { const foundConsumer = value.validRuleConsumers?.find( - (validConsumer) => validConsumer === consumer || validConsumer === producer + (validConsumer) => validConsumer === consumerValue || validConsumer === producer ); if (foundConsumer) { diff --git a/x-pack/plugins/cases/public/components/case_view/components/case_view_alerts.test.tsx b/x-pack/plugins/cases/public/components/case_view/components/case_view_alerts.test.tsx index fe2deb74dfa10..7366acf6e051f 100644 --- a/x-pack/plugins/cases/public/components/case_view/components/case_view_alerts.test.tsx +++ b/x-pack/plugins/cases/public/components/case_view/components/case_view_alerts.test.tsx @@ -15,6 +15,7 @@ import type { CaseUI } from '../../../../common'; import { CaseViewAlerts } from './case_view_alerts'; import * as api from '../../../containers/api'; import type { FeatureIdsResponse } from '../../../containers/types'; +import { SECURITY_SOLUTION_RULE_TYPE_IDS } from '@kbn/securitysolution-rules'; jest.mock('../../../containers/api'); @@ -54,7 +55,7 @@ describe('CaseUI View Page activity tab', () => { expect(getAlertsStateTableMock).toHaveBeenCalledWith({ alertsTableConfigurationRegistry: expect.anything(), configurationId: 'securitySolution-case', - featureIds: ['siem'], + ruleTypeIds: SECURITY_SOLUTION_RULE_TYPE_IDS, id: 'case-details-alerts-securitySolution', query: { ids: { @@ -88,7 +89,8 @@ describe('CaseUI View Page activity tab', () => { expect(getAlertsStateTableMock).toHaveBeenCalledWith({ alertsTableConfigurationRegistry: expect.anything(), configurationId: 'case-details-alerts-observability', - featureIds: ['observability'], + ruleTypeIds: ['log-threshold'], + consumers: ['observability'], id: 'case-details-alerts-observability', query: { ids: { diff --git a/x-pack/plugins/cases/public/components/case_view/components/case_view_alerts.tsx b/x-pack/plugins/cases/public/components/case_view/components/case_view_alerts.tsx index 9570bee46b3fe..6f8223b5305f1 100644 --- a/x-pack/plugins/cases/public/components/case_view/components/case_view_alerts.tsx +++ b/x-pack/plugins/cases/public/components/case_view/components/case_view_alerts.tsx @@ -8,8 +8,8 @@ import React, { useMemo } from 'react'; import { EuiFlexItem, EuiFlexGroup, EuiProgress } from '@elastic/eui'; -import type { ValidFeatureId } from '@kbn/rule-registry-plugin/common/technical_rule_data_field_names'; -import { AlertConsumers } from '@kbn/rule-registry-plugin/common/technical_rule_data_field_names'; +import type { AlertsTableStateProps } from '@kbn/triggers-actions-ui-plugin/public/application/sections/alerts_table/alerts_table_state'; +import { SECURITY_SOLUTION_RULE_TYPE_IDS } from '@kbn/securitysolution-rules'; import { SECURITY_SOLUTION_OWNER } from '../../../../common/constants'; import type { CaseUI } from '../../../../common'; import { useKibana } from '../../../common/lib/kibana'; @@ -49,14 +49,16 @@ export const CaseViewAlerts = ({ caseData, onAlertsTableLoaded }: CaseViewAlerts ) : ''; - const alertStateProps = useMemo( + const alertStateProps: AlertsTableStateProps = useMemo( () => ({ alertsTableConfigurationRegistry: triggersActionsUi.alertsTableConfigurationRegistry, configurationId: configId, id: `case-details-alerts-${caseData.owner}`, - featureIds: (caseData.owner === SECURITY_SOLUTION_OWNER - ? [AlertConsumers.SIEM] - : alertData?.featureIds ?? []) as ValidFeatureId[], + ruleTypeIds: + caseData.owner === SECURITY_SOLUTION_OWNER + ? SECURITY_SOLUTION_RULE_TYPE_IDS + : alertData?.ruleTypeIds ?? [], + consumers: alertData?.featureIds, query: alertIdsQuery, showAlertStatusWithFlapping: caseData.owner !== SECURITY_SOLUTION_OWNER, onLoaded: onAlertsTableLoaded, @@ -65,6 +67,7 @@ export const CaseViewAlerts = ({ caseData, onAlertsTableLoaded }: CaseViewAlerts triggersActionsUi.alertsTableConfigurationRegistry, configId, caseData.owner, + alertData?.ruleTypeIds, alertData?.featureIds, alertIdsQuery, onAlertsTableLoaded, diff --git a/x-pack/plugins/cases/public/components/custom_fields/number/create.test.tsx b/x-pack/plugins/cases/public/components/custom_fields/number/create.test.tsx index 2a8a515df01ee..17bbcbfa045e4 100644 --- a/x-pack/plugins/cases/public/components/custom_fields/number/create.test.tsx +++ b/x-pack/plugins/cases/public/components/custom_fields/number/create.test.tsx @@ -12,7 +12,8 @@ import { FormTestComponent } from '../../../common/test_utils'; import { Create } from './create'; import { customFieldsConfigurationMock } from '../../../containers/mock'; -describe('Create ', () => { +// FLAKY: https://github.com/elastic/kibana/issues/202115 +describe.skip('Create ', () => { const onSubmit = jest.fn(); beforeEach(() => { diff --git a/x-pack/plugins/cases/public/components/system_actions/cases/cases_params.tsx b/x-pack/plugins/cases/public/components/system_actions/cases/cases_params.tsx index 9fabf39db0bc4..e77e8313c6963 100644 --- a/x-pack/plugins/cases/public/components/system_actions/cases/cases_params.tsx +++ b/x-pack/plugins/cases/public/components/system_actions/cases/cases_params.tsx @@ -8,7 +8,6 @@ import React, { memo, useCallback, useEffect, useMemo } from 'react'; import type { ActionParamsProps } from '@kbn/triggers-actions-ui-plugin/public/types'; -import type { AlertConsumers, ValidFeatureId } from '@kbn/rule-data-utils'; import type { EuiComboBoxOptionOption } from '@elastic/eui'; import { EuiCheckbox, @@ -37,7 +36,7 @@ const DEFAULT_EMPTY_TEMPLATE_KEY = 'defaultEmptyTemplateKey'; export const CasesParamsFieldsComponent: React.FunctionComponent< ActionParamsProps -> = ({ actionParams, editAction, errors, index, producerId, featureId }) => { +> = ({ actionParams, editAction, errors, index, producerId, featureId, ruleTypeId }) => { const { cloud, data: { dataViews: dataViewsService }, @@ -58,9 +57,7 @@ export const CasesParamsFieldsComponent: React.FunctionComponent< http, toasts, dataViewsService, - featureIds: producerId - ? [producerId as Exclude] - : [], + ruleTypeIds: ruleTypeId ? [ruleTypeId] : [], }); const { data: configurations, isLoading: isLoadingCaseConfiguration } = diff --git a/x-pack/plugins/cases/public/components/user_actions/user_actions_list.test.tsx b/x-pack/plugins/cases/public/components/user_actions/user_actions_list.test.tsx index d09ebc9d747a7..d2874ad20246b 100644 --- a/x-pack/plugins/cases/public/components/user_actions/user_actions_list.test.tsx +++ b/x-pack/plugins/cases/public/components/user_actions/user_actions_list.test.tsx @@ -31,7 +31,8 @@ const defaultProps = { jest.mock('../../common/lib/kibana'); -describe(`UserActionsList`, () => { +// FLAKY: https://github.com/elastic/kibana/issues/176524 +describe.skip(`UserActionsList`, () => { let appMockRender: AppMockRenderer; beforeEach(() => { diff --git a/x-pack/plugins/cases/server/connectors/cases/index.test.ts b/x-pack/plugins/cases/server/connectors/cases/index.test.ts index 7b6d244d165b3..c0480d694184f 100644 --- a/x-pack/plugins/cases/server/connectors/cases/index.test.ts +++ b/x-pack/plugins/cases/server/connectors/cases/index.test.ts @@ -366,7 +366,7 @@ describe('getCasesConnectorType', () => { expect( adapter.getKibanaPrivileges?.({ - consumer: 'alerting', + consumer: 'not-exist', producer: AlertConsumers.LOGS, }) ).toEqual([ @@ -387,7 +387,7 @@ describe('getCasesConnectorType', () => { expect( adapter.getKibanaPrivileges?.({ - consumer: 'alerting', + consumer: 'alerts', producer: AlertConsumers.LOGS, }) ).toEqual([ diff --git a/x-pack/plugins/cases/server/connectors/cases/index.ts b/x-pack/plugins/cases/server/connectors/cases/index.ts index 07b4ab5e29551..b630de5209e2d 100644 --- a/x-pack/plugins/cases/server/connectors/cases/index.ts +++ b/x-pack/plugins/cases/server/connectors/cases/index.ts @@ -95,7 +95,7 @@ export const getCasesConnectorAdapter = ({ return { connectorTypeId: CASES_CONNECTOR_ID, ruleActionParamsSchema: CasesConnectorRuleActionParamsSchema, - buildActionParams: ({ alerts, rule, params, spaceId, ruleUrl }) => { + buildActionParams: ({ alerts, rule, params, ruleUrl }) => { const caseAlerts = [...alerts.new.data, ...alerts.ongoing.data]; const owner = getOwnerFromRuleConsumerProducer({ diff --git a/x-pack/plugins/cases/server/connectors/index.ts b/x-pack/plugins/cases/server/connectors/index.ts index 0b0f201b46d42..56dcddfbee76a 100644 --- a/x-pack/plugins/cases/server/connectors/index.ts +++ b/x-pack/plugins/cases/server/connectors/index.ts @@ -9,7 +9,7 @@ import type { PluginSetupContract as ActionsPluginSetupContract } from '@kbn/act import type { KibanaRequest } from '@kbn/core-http-server'; import type { CoreSetup, SavedObjectsClientContract } from '@kbn/core/server'; import { SECURITY_EXTENSION_ID } from '@kbn/core/server'; -import type { PluginSetupContract as AlertingPluginSetup } from '@kbn/alerting-plugin/server'; +import type { AlertingServerSetup } from '@kbn/alerting-plugin/server'; import type { CasesClient } from '../client'; import { getCasesConnectorAdapter, getCasesConnectorType } from './cases'; @@ -25,7 +25,7 @@ export function registerConnectorTypes({ isServerlessSecurity, }: { actions: ActionsPluginSetupContract; - alerting: AlertingPluginSetup; + alerting: AlertingServerSetup; core: CoreSetup; getCasesClient: (request: KibanaRequest) => Promise; getSpaceId: (request?: KibanaRequest) => string; diff --git a/x-pack/plugins/cases/server/types.ts b/x-pack/plugins/cases/server/types.ts index a51817c9d7e58..8606808e1c183 100644 --- a/x-pack/plugins/cases/server/types.ts +++ b/x-pack/plugins/cases/server/types.ts @@ -29,7 +29,7 @@ import type { UsageCollectionSetup } from '@kbn/usage-collection-plugin/server'; import type { LicensingPluginSetup, LicensingPluginStart } from '@kbn/licensing-plugin/server'; import type { NotificationsPluginStart } from '@kbn/notifications-plugin/server'; import type { RuleRegistryPluginStartContract } from '@kbn/rule-registry-plugin/server'; -import type { PluginSetupContract as AlertingPluginSetup } from '@kbn/alerting-plugin/server'; +import type { AlertingServerSetup } from '@kbn/alerting-plugin/server'; import type { CloudSetup } from '@kbn/cloud-plugin/server'; import type { CasesClient } from './client'; import type { AttachmentFramework } from './attachment_framework/types'; @@ -37,7 +37,7 @@ import type { ExternalReferenceAttachmentTypeRegistry } from './attachment_frame import type { PersistableStateAttachmentTypeRegistry } from './attachment_framework/persistable_state_registry'; export interface CasesServerSetupDependencies { - alerting: AlertingPluginSetup; + alerting: AlertingServerSetup; actions: ActionsPluginSetup; lens: LensServerPluginSetup; features: FeaturesPluginSetup; diff --git a/x-pack/plugins/cases/tsconfig.json b/x-pack/plugins/cases/tsconfig.json index 48ca36a02b2be..2a77cb0e7b5a1 100644 --- a/x-pack/plugins/cases/tsconfig.json +++ b/x-pack/plugins/cases/tsconfig.json @@ -74,6 +74,7 @@ "@kbn/core-logging-server-mocks", "@kbn/core-logging-browser-mocks", "@kbn/presentation-publishing", + "@kbn/securitysolution-rules", "@kbn/alerts-ui-shared", "@kbn/cloud-plugin", "@kbn/core-http-server-mocks", diff --git a/x-pack/plugins/cloud_security_posture/server/routes/benchmark_rules/bulk_action/bulk_action.ts b/x-pack/plugins/cloud_security_posture/server/routes/benchmark_rules/bulk_action/bulk_action.ts index b72cb27088eda..52a7c8b555094 100644 --- a/x-pack/plugins/cloud_security_posture/server/routes/benchmark_rules/bulk_action/bulk_action.ts +++ b/x-pack/plugins/cloud_security_posture/server/routes/benchmark_rules/bulk_action/bulk_action.ts @@ -31,7 +31,7 @@ import { bulkActionBenchmarkRulesHandler } from './v1'; // ... (additional benchmark rules) ]; } - + Response: { updated_benchmark_rules: CspBenchmarkRulesStates; Benchmark rules object that were affected @@ -67,7 +67,7 @@ export const defineBulkActionCspBenchmarkRulesRoute = (router: CspRouter) => const benchmarkRulesToUpdate = requestBody.rules; - const detectionRulesClient = (await context.alerting).getRulesClient(); + const detectionRulesClient = await (await context.alerting).getRulesClient(); const handlerResponse = await bulkActionBenchmarkRulesHandler( cspContext.soClient, diff --git a/x-pack/plugins/data_quality/public/routes/dataset_quality_details/context.tsx b/x-pack/plugins/data_quality/public/routes/dataset_quality_details/context.tsx index 462cbbbd9288b..5f710c445471e 100644 --- a/x-pack/plugins/data_quality/public/routes/dataset_quality_details/context.tsx +++ b/x-pack/plugins/data_quality/public/routes/dataset_quality_details/context.tsx @@ -74,7 +74,10 @@ export function DatasetQualityDetailsContextProvider({ urlStateStorageContainer, datasetQualityDetailsState: state, }); - const breadcrumbValue = getBreadcrumbValue(state.dataStream, state.integration); + const breadcrumbValue = getBreadcrumbValue( + state.dataStream, + state.integration?.integration + ); setBreadcrumbs([{ text: breadcrumbValue }]); } ); diff --git a/x-pack/plugins/data_usage/common/rest_types/data_streams.ts b/x-pack/plugins/data_usage/common/rest_types/data_streams.ts index 87af7e29eccb6..17fc5fa5de053 100644 --- a/x-pack/plugins/data_usage/common/rest_types/data_streams.ts +++ b/x-pack/plugins/data_usage/common/rest_types/data_streams.ts @@ -7,6 +7,14 @@ import { schema, TypeOf } from '@kbn/config-schema'; +export const DataStreamsRequestSchema = { + query: schema.object({ + includeZeroStorage: schema.boolean({ defaultValue: false }), + }), +}; + +export type DataStreamsRequestQuery = TypeOf; + export const DataStreamsResponseSchema = { body: () => schema.arrayOf( diff --git a/x-pack/plugins/data_usage/server/routes/internal/data_streams.ts b/x-pack/plugins/data_usage/server/routes/internal/data_streams.ts index bfa236aa1cec0..6a1a4517bf6ef 100644 --- a/x-pack/plugins/data_usage/server/routes/internal/data_streams.ts +++ b/x-pack/plugins/data_usage/server/routes/internal/data_streams.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { DataStreamsResponseSchema } from '../../../common/rest_types'; +import { DataStreamsResponseSchema, DataStreamsRequestSchema } from '../../../common/rest_types'; import { DATA_USAGE_DATA_STREAMS_API_ROUTE } from '../../../common'; import { DataUsageContext, DataUsageRouter } from '../../types'; import { getDataStreamsHandler } from './data_streams_handler'; @@ -23,7 +23,7 @@ export const registerDataStreamsRoute = ( { version: '1', validate: { - request: {}, + request: DataStreamsRequestSchema, response: { 200: DataStreamsResponseSchema, }, diff --git a/x-pack/plugins/data_usage/server/routes/internal/data_streams_handler.ts b/x-pack/plugins/data_usage/server/routes/internal/data_streams_handler.ts index 99b4e982c5a40..726aa157050f8 100644 --- a/x-pack/plugins/data_usage/server/routes/internal/data_streams_handler.ts +++ b/x-pack/plugins/data_usage/server/routes/internal/data_streams_handler.ts @@ -9,12 +9,15 @@ import { RequestHandler } from '@kbn/core/server'; import { DataUsageContext, DataUsageRequestHandlerContext } from '../../types'; import { errorHandler } from '../error_handler'; import { getMeteringStats } from '../../utils/get_metering_stats'; +import { DataStreamsRequestQuery } from '../../../common/rest_types/data_streams'; export const getDataStreamsHandler = ( dataUsageContext: DataUsageContext -): RequestHandler => { +): RequestHandler => { const logger = dataUsageContext.logFactory.get('dataStreamsRoute'); - return async (context, _, response) => { + return async (context, request, response) => { + const { includeZeroStorage } = request.query; + logger.debug('Retrieving user data streams'); try { @@ -28,7 +31,7 @@ export const getDataStreamsHandler = ( ? meteringStats .sort((a, b) => b.size_in_bytes - a.size_in_bytes) .reduce>((acc, stat) => { - if (stat.size_in_bytes > 0) { + if (includeZeroStorage || stat.size_in_bytes > 0) { acc.push({ name: stat.name, storageSizeBytes: stat.size_in_bytes ?? 0, diff --git a/x-pack/plugins/data_usage/server/services/autoops_api.ts b/x-pack/plugins/data_usage/server/services/autoops_api.ts index ac9265d081d31..d98b0c507fe14 100644 --- a/x-pack/plugins/data_usage/server/services/autoops_api.ts +++ b/x-pack/plugins/data_usage/server/services/autoops_api.ts @@ -123,7 +123,7 @@ export class AutoOpsAPIService { `${AUTO_OPS_AGENT_CREATION_PREFIX} with an error ${error} ${requestConfigDebugStatus}`, errorMetadataWithRequestConfig ); - throw new Error(withRequestIdMessage(error.message)); + throw new AutoOpsError(withRequestIdMessage(error.message)); } const errorLogCodeCause = `${error.code} ${this.convertCauseErrorsToString(error)}`; @@ -152,14 +152,16 @@ export class AutoOpsAPIService { `${AUTO_OPS_AGENT_CREATION_PREFIX} while sending the request to the AutoOps API: ${errorLogCodeCause} ${requestConfigDebugStatus}`, errorMetadataWithRequestConfig ); - throw new Error(withRequestIdMessage(`no response received from the AutoOps API`)); + throw new AutoOpsError(withRequestIdMessage(`no response received from the AutoOps API`)); } else { // Something happened in setting up the request that triggered an Error this.logger.error( - `${AUTO_OPS_AGENT_CREATION_PREFIX} to be created ${errorLogCodeCause} ${requestConfigDebugStatus}`, + `${AUTO_OPS_AGENT_CREATION_PREFIX} to be created ${errorLogCodeCause} ${requestConfigDebugStatus} ${error.toJSON()}`, errorMetadataWithRequestConfig ); - throw new AutoOpsError(withRequestIdMessage(AGENT_CREATION_FAILED_ERROR)); + throw new AutoOpsError( + withRequestIdMessage(`${AGENT_CREATION_FAILED_ERROR}, ${error.message}`) + ); } } ); diff --git a/x-pack/plugins/discover_enhanced/ui_tests/README.md b/x-pack/plugins/discover_enhanced/ui_tests/README.md index 8320e9464d9ca..e6c5943e1533f 100644 --- a/x-pack/plugins/discover_enhanced/ui_tests/README.md +++ b/x-pack/plugins/discover_enhanced/ui_tests/README.md @@ -11,7 +11,10 @@ node scripts/scout_start_servers.js --serverless=es Then you can run the tests multiple times in another terminal with: ```bash -npx playwright test --config x-pack/plugins/discover_enhanced/ui_tests/playwright.config.ts +// ESS +npx playwright test --config x-pack/plugins/discover_enhanced/ui_tests/playwright.config.ts --grep @ess +// Serverless +npx playwright test --config x-pack/plugins/discover_enhanced/ui_tests/playwright.config.ts --grep @svlSearch // @svlOblt, @svlSecurity ``` Test results are available in `x-pack/plugins/discover_enhanced/ui_tests/output` diff --git a/x-pack/plugins/discover_enhanced/ui_tests/fixtures/assertion_messages.ts b/x-pack/plugins/discover_enhanced/ui_tests/fixtures/assertion_messages.ts new file mode 100644 index 0000000000000..6ccbe4df990cb --- /dev/null +++ b/x-pack/plugins/discover_enhanced/ui_tests/fixtures/assertion_messages.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 const QUERY_BAR_VALIDATION = { + SUGGESTIONS_COUNT: 'The query bar suggestions count should be', +}; diff --git a/x-pack/plugins/discover_enhanced/ui_tests/fixtures/constants.ts b/x-pack/plugins/discover_enhanced/ui_tests/fixtures/constants.ts new file mode 100644 index 0000000000000..3ac2c34586f4d --- /dev/null +++ b/x-pack/plugins/discover_enhanced/ui_tests/fixtures/constants.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. + */ + +export const LOGSTASH_DEFAULT_START_TIME = '2015-09-19T06:31:44.000Z'; +export const LOGSTASH_DEFAULT_END_TIME = '2015-09-23T18:31:44.000Z'; + +export const DATA_VIEW_ID = { + ECOMMERCE: '5193f870-d861-11e9-a311-0fa548c5f953', + LOGSTASH: 'logstash-*', +}; + +export const DATA_VIEW = { + ECOMMERCE: 'ecommerce', + LOGSTASH: 'logstash-*', +}; + +export const LOGSTASH_OUT_OF_RANGE_DATES = { + from: 'Mar 1, 2020 @ 00:00:00.000', + to: 'Nov 1, 2020 @ 00:00:00.000', +}; + +export const LOGSTASH_IN_RANGE_DATES = { + from: 'Sep 19, 2015 @ 06:31:44.000', + to: 'Sep 23, 2015 @ 18:31:44.000', +}; + +export const ES_ARCHIVES = { + LOGSTASH: 'x-pack/test/functional/es_archives/logstash_functional', + NO_TIME_FIELD: 'test/functional/fixtures/es_archiver/index_pattern_without_timefield', + ECOMMERCE: 'x-pack/test/functional/es_archives/reporting/ecommerce', +}; + +export const KBN_ARCHIVES = { + INVALID_SCRIPTED_FIELD: 'test/functional/fixtures/kbn_archiver/invalid_scripted_field', + NO_TIME_FIELD: 'test/functional/fixtures/kbn_archiver/index_pattern_without_timefield', + DASHBOARD_DRILLDOWNS: + 'x-pack/test/functional/fixtures/kbn_archiver/dashboard_drilldowns/drilldowns', + DISCOVER: 'test/functional/fixtures/kbn_archiver/discover', + ECOMMERCE: 'x-pack/test/functional/fixtures/kbn_archiver/reporting/ecommerce.json', +}; diff --git a/x-pack/plugins/discover_enhanced/ui_tests/fixtures/index.ts b/x-pack/plugins/discover_enhanced/ui_tests/fixtures/index.ts index 38d4905f82e6f..4cff802b3b89f 100644 --- a/x-pack/plugins/discover_enhanced/ui_tests/fixtures/index.ts +++ b/x-pack/plugins/discover_enhanced/ui_tests/fixtures/index.ts @@ -14,7 +14,7 @@ import { } from '@kbn/scout'; import { DemoPage } from './page_objects'; -interface ExtendedScoutTestFixtures extends ScoutTestFixtures { +export interface ExtendedScoutTestFixtures extends ScoutTestFixtures { pageObjects: PageObjects & { demo: DemoPage; }; @@ -30,3 +30,6 @@ export const test = base.extend( await use(extendedPageObjects); }, }); + +export * as testData from './constants'; +export * as assertionMessages from './assertion_messages'; diff --git a/x-pack/plugins/discover_enhanced/ui_tests/tests/error_handling.spec.ts b/x-pack/plugins/discover_enhanced/ui_tests/tests/error_handling.spec.ts new file mode 100644 index 0000000000000..914558fbdc97f --- /dev/null +++ b/x-pack/plugins/discover_enhanced/ui_tests/tests/error_handling.spec.ts @@ -0,0 +1,38 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { expect } from '@kbn/scout'; +import { test, testData } from '../fixtures'; + +test.describe('Discover app - errors', { tag: ['@ess'] }, () => { + test.beforeAll(async ({ esArchiver, kbnClient, uiSettings }) => { + await kbnClient.savedObjects.clean({ types: ['search', 'index-pattern'] }); + await esArchiver.loadIfNeeded(testData.ES_ARCHIVES.LOGSTASH); + await kbnClient.importExport.load(testData.KBN_ARCHIVES.INVALID_SCRIPTED_FIELD); + await uiSettings.setDefaultTime({ + from: testData.LOGSTASH_DEFAULT_START_TIME, + to: testData.LOGSTASH_DEFAULT_END_TIME, + }); + }); + + test.afterAll(async ({ kbnClient }) => { + await kbnClient.savedObjects.cleanStandardList(); + }); + + test.beforeEach(async ({ browserAuth, pageObjects }) => { + await browserAuth.loginAsViewer(); + await pageObjects.discover.goto(); + }); + + test('should render invalid scripted field error', async ({ page }) => { + await page.testSubj.locator('discoverErrorCalloutTitle').waitFor({ state: 'visible' }); + await expect( + page.testSubj.locator('painlessStackTrace'), + 'Painless error stacktrace should be displayed' + ).toBeVisible(); + }); +}); diff --git a/x-pack/plugins/discover_enhanced/ui_tests/tests/saved_search_embeddable.spec.ts b/x-pack/plugins/discover_enhanced/ui_tests/tests/saved_search_embeddable.spec.ts new file mode 100644 index 0000000000000..7103f2b25e633 --- /dev/null +++ b/x-pack/plugins/discover_enhanced/ui_tests/tests/saved_search_embeddable.spec.ts @@ -0,0 +1,102 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor 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 { ScoutWorkerFixtures, expect } from '@kbn/scout'; +import { test, testData } from '../fixtures'; + +const createSavedSearch = async ( + kbnClient: ScoutWorkerFixtures['kbnClient'], + searchId: string, + searchTitle: string, + dataViewId: string +) => + await kbnClient.savedObjects.create({ + type: 'search', + id: searchId, + overwrite: false, + attributes: { + title: searchTitle, + description: '', + columns: ['agent', 'bytes', 'clientip'], + sort: [['@timestamp', 'desc']], + kibanaSavedObjectMeta: { + searchSourceJSON: + '{"highlightAll":true,"version":true,"query":{"language":"lucene","query":""},"filter":[],"indexRefName":"kibanaSavedObjectMeta.searchSourceJSON.index"}', + }, + }, + references: [ + { + id: dataViewId, + name: 'kibanaSavedObjectMeta.searchSourceJSON.index', + type: 'index-pattern', + }, + ], + }); + +test.describe( + 'Discover app - saved search embeddable', + { tag: ['@ess', '@svlSecurity', '@svlOblt', '@svlSearch'] }, + () => { + const SAVED_SEARCH_TITLE = 'TempSearch'; + const SAVED_SEARCH_ID = '90943e30-9a47-11e8-b64d-95841ca0b247'; + test.beforeAll(async ({ esArchiver, kbnClient, uiSettings }) => { + await esArchiver.loadIfNeeded(testData.ES_ARCHIVES.LOGSTASH); + await kbnClient.importExport.load(testData.KBN_ARCHIVES.DASHBOARD_DRILLDOWNS); + await uiSettings.set({ + defaultIndex: testData.DATA_VIEW_ID.LOGSTASH, // TODO: investigate why it is required for `node scripts/playwright_test.js` run + 'timepicker:timeDefaults': `{ "from": "${testData.LOGSTASH_DEFAULT_START_TIME}", "to": "${testData.LOGSTASH_DEFAULT_END_TIME}"}`, + }); + }); + + test.afterAll(async ({ kbnClient, uiSettings }) => { + await uiSettings.unset('defaultIndex', 'timepicker:timeDefaults'); + await kbnClient.savedObjects.cleanStandardList(); + }); + + test.beforeEach(async ({ browserAuth, pageObjects }) => { + await browserAuth.loginAsPrivilegedUser(); + await pageObjects.dashboard.goto(); + }); + + test('should allow removing the dashboard panel after the underlying saved search has been deleted', async ({ + kbnClient, + page, + pageObjects, + }) => { + await pageObjects.dashboard.openNewDashboard(); + await createSavedSearch( + kbnClient, + SAVED_SEARCH_ID, + SAVED_SEARCH_TITLE, + testData.DATA_VIEW_ID.LOGSTASH + ); + await pageObjects.dashboard.addPanelFromLibrary(SAVED_SEARCH_TITLE); + await page.testSubj.locator('savedSearchTotalDocuments').waitFor({ + state: 'visible', + }); + + await pageObjects.dashboard.saveDashboard('Dashboard with deleted saved search'); + await kbnClient.savedObjects.delete({ + type: 'search', + id: SAVED_SEARCH_ID, + }); + + await page.reload(); + await page.waitForLoadingIndicatorHidden(); + await expect( + page.testSubj.locator('embeddableError'), + 'Embeddable error should be displayed' + ).toBeVisible(); + + await pageObjects.dashboard.removePanel('embeddableError'); + await expect( + page.testSubj.locator('embeddableError'), + 'Embeddable error should not be displayed' + ).toBeHidden(); + }); + } +); diff --git a/x-pack/plugins/discover_enhanced/ui_tests/tests/saved_searches.spec.ts b/x-pack/plugins/discover_enhanced/ui_tests/tests/saved_searches.spec.ts new file mode 100644 index 0000000000000..1398f5f24ab27 --- /dev/null +++ b/x-pack/plugins/discover_enhanced/ui_tests/tests/saved_searches.spec.ts @@ -0,0 +1,128 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor 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/scout'; +import { test, testData } from '../fixtures'; +import type { ExtendedScoutTestFixtures } from '../fixtures'; + +const assertNoFilterAndEmptyQuery = async ( + filterBadge: { field: string; value: string }, + pageObjects: ExtendedScoutTestFixtures['pageObjects'], + page: ExtendedScoutTestFixtures['page'] +) => { + expect( + // checking if filter exists, enabled or disabled + await pageObjects.filterBar.hasFilter(filterBadge), + `Filter ${JSON.stringify(filterBadge)} should not exist` + ).toBe(false); + await expect( + page.testSubj.locator('queryInput'), + 'Query Bar input field should be empty' + ).toHaveText(''); +}; + +const assertDataViewIsSelected = async (page: ExtendedScoutTestFixtures['page'], name: string) => + await expect( + page.testSubj.locator('*dataView-switch-link'), + 'Incorrect data view is selected' + ).toHaveText(name); + +test.describe( + 'Discover app - saved searches', + { tag: ['@ess', '@svlSecurity', '@svlOblt', '@svlSearch'] }, + () => { + const START_TIME = '2019-04-27T23:56:51.374Z'; + const END_TIME = '2019-08-23T16:18:51.821Z'; + const PANEL_NAME = 'Ecommerce Data'; + const SEARCH_QUERY = 'customer_gender:MALE'; + const SAVED_SEARCH_NAME = 'test-unselect-saved-search'; + const filterFieldAndValue = { + field: 'category', + value: `Men's Shoes`, + }; + + test.beforeAll(async ({ esArchiver, kbnClient, uiSettings }) => { + await esArchiver.loadIfNeeded(testData.ES_ARCHIVES.ECOMMERCE); + await kbnClient.importExport.load(testData.KBN_ARCHIVES.DISCOVER); + await kbnClient.importExport.load(testData.KBN_ARCHIVES.ECOMMERCE); + await uiSettings.set({ + defaultIndex: testData.DATA_VIEW_ID.ECOMMERCE, + 'timepicker:timeDefaults': `{ "from": "${START_TIME}", "to": "${END_TIME}"}`, + }); + }); + + test.afterAll(async ({ kbnClient, uiSettings }) => { + await uiSettings.unset('defaultIndex', 'timepicker:timeDefaults'); + await kbnClient.savedObjects.cleanStandardList(); + }); + + test.beforeEach(async ({ browserAuth }) => { + await browserAuth.loginAsPrivilegedUser(); + }); + + test('should customize time range on dashboards', async ({ pageObjects, page }) => { + await pageObjects.dashboard.goto(); + await pageObjects.dashboard.openNewDashboard(); + await pageObjects.dashboard.addPanelFromLibrary(PANEL_NAME); + await page.testSubj.locator('savedSearchTotalDocuments').waitFor({ + state: 'visible', + }); + + await pageObjects.dashboard.customizePanel({ + name: PANEL_NAME, + customTimeRageCommonlyUsed: { value: 'Last_90 days' }, + }); + await expect( + page.testSubj.locator('embeddedSavedSearchDocTable').locator('.euiDataGrid__noResults'), + 'No results message in Saved Search panel should be visible' + ).toBeVisible(); + }); + + test(`should unselect saved search when navigating to a 'new'`, async ({ + pageObjects, + page, + }) => { + await pageObjects.discover.goto(); + await assertDataViewIsSelected(page, testData.DATA_VIEW.ECOMMERCE); + await pageObjects.filterBar.addFilter({ + ...filterFieldAndValue, + operator: 'is', + }); + await page.testSubj.fill('queryInput', SEARCH_QUERY); + await page.testSubj.click('querySubmitButton'); + await pageObjects.discover.waitForHistogramRendered(); + + await pageObjects.discover.saveSearch(SAVED_SEARCH_NAME); + await pageObjects.discover.waitForHistogramRendered(); + + expect( + await pageObjects.filterBar.hasFilter({ + ...filterFieldAndValue, + enabled: true, // Filter is enabled by default + }) + ).toBe(true); + await expect(page.testSubj.locator('queryInput')).toHaveText(SEARCH_QUERY); + + // create new search + await pageObjects.discover.clickNewSearch(); + await assertDataViewIsSelected(page, testData.DATA_VIEW.ECOMMERCE); + await assertNoFilterAndEmptyQuery(filterFieldAndValue, pageObjects, page); + + // change data view + await pageObjects.discover.selectDataView(testData.DATA_VIEW.LOGSTASH); + await assertNoFilterAndEmptyQuery(filterFieldAndValue, pageObjects, page); + + // change data view again + await pageObjects.discover.selectDataView(testData.DATA_VIEW.ECOMMERCE); + await assertNoFilterAndEmptyQuery(filterFieldAndValue, pageObjects, page); + + // create new search again + await pageObjects.discover.clickNewSearch(); + await assertDataViewIsSelected(page, testData.DATA_VIEW.ECOMMERCE); + }); + } +); diff --git a/x-pack/plugins/discover_enhanced/ui_tests/tests/value_suggestions.spec.ts b/x-pack/plugins/discover_enhanced/ui_tests/tests/value_suggestions.spec.ts index ff1389e85924e..04836afb99b5b 100644 --- a/x-pack/plugins/discover_enhanced/ui_tests/tests/value_suggestions.spec.ts +++ b/x-pack/plugins/discover_enhanced/ui_tests/tests/value_suggestions.spec.ts @@ -6,51 +6,54 @@ */ import { expect } from '@kbn/scout'; -import { test } from '../fixtures'; +import { test, testData, assertionMessages } from '../fixtures'; -test.describe('Discover app - value suggestions', () => { - test.beforeAll(async ({ esArchiver, kbnClient }) => { - await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/logstash_functional'); - await kbnClient.importExport.load( - 'x-pack/test/functional/fixtures/kbn_archiver/dashboard_drilldowns/drilldowns' - ); - await kbnClient.uiSettings.update({ - defaultIndex: 'logstash-*', // TODO: investigate why it is required for `node scripts/playwright_test.js` run - 'doc_table:legacy': false, +test.describe( + 'Discover app - value suggestions: useTimeRange enabled', + { tag: ['@ess', '@svlSecurity', '@svlOblt', '@svlSearch'] }, + () => { + test.beforeAll(async ({ esArchiver, kbnClient, uiSettings }) => { + await esArchiver.loadIfNeeded(testData.ES_ARCHIVES.LOGSTASH); + await kbnClient.importExport.load(testData.KBN_ARCHIVES.DASHBOARD_DRILLDOWNS); + await uiSettings.set({ + defaultIndex: testData.DATA_VIEW_ID.LOGSTASH, // TODO: investigate why it is required for `node scripts/playwright_test.js` run + 'timepicker:timeDefaults': `{ "from": "${testData.LOGSTASH_DEFAULT_START_TIME}", "to": "${testData.LOGSTASH_DEFAULT_END_TIME}"}`, + }); }); - }); - test.afterAll(async ({ kbnClient }) => { - await kbnClient.uiSettings.unset('doc_table:legacy'); - await kbnClient.uiSettings.unset('defaultIndex'); - await kbnClient.savedObjects.cleanStandardList(); - }); + test.afterAll(async ({ kbnClient, uiSettings }) => { + await uiSettings.unset('defaultIndex', 'timepicker:timeDefaults'); + await kbnClient.savedObjects.cleanStandardList(); + }); - test.beforeEach(async ({ browserAuth, pageObjects }) => { - await browserAuth.loginAsPrivilegedUser(); - await pageObjects.discover.goto(); - }); + test.beforeEach(async ({ browserAuth, pageObjects }) => { + await browserAuth.loginAsViewer(); + await pageObjects.discover.goto(); + }); - test('dont show up if outside of range', async ({ page, pageObjects }) => { - await pageObjects.datePicker.setAbsoluteRange({ - from: 'Mar 1, 2020 @ 00:00:00.000', - to: 'Nov 1, 2020 @ 00:00:00.000', + test('dont show up if outside of range', async ({ page, pageObjects }) => { + await pageObjects.datePicker.setAbsoluteRange(testData.LOGSTASH_OUT_OF_RANGE_DATES); + await page.testSubj.fill('queryInput', 'extension.raw : '); + await expect(page.testSubj.locator('autoCompleteSuggestionText')).toHaveCount(0); }); - await page.testSubj.fill('queryInput', 'extension.raw : '); - await expect(page.testSubj.locator('autoCompleteSuggestionText')).toHaveCount(0); - }); + test('show up if in range', async ({ page, pageObjects }) => { + await pageObjects.datePicker.setAbsoluteRange(testData.LOGSTASH_IN_RANGE_DATES); + await page.testSubj.fill('queryInput', 'extension.raw : '); + await expect( + page.testSubj.locator('autoCompleteSuggestionText'), + assertionMessages.QUERY_BAR_VALIDATION.SUGGESTIONS_COUNT + ).toHaveCount(5); + const actualSuggestions = await page.testSubj + .locator('autoCompleteSuggestionText') + .allTextContents(); + expect(actualSuggestions.join(',')).toContain('jpg'); + }); - test('show up if in range', async ({ page, pageObjects }) => { - await pageObjects.datePicker.setAbsoluteRange({ - from: 'Sep 19, 2015 @ 06:31:44.000', - to: 'Sep 23, 2015 @ 18:31:44.000', + test('also displays descriptions for operators', async ({ page, pageObjects }) => { + await pageObjects.datePicker.setAbsoluteRange(testData.LOGSTASH_IN_RANGE_DATES); + await page.testSubj.fill('queryInput', 'extension.raw'); + await expect(page.testSubj.locator('^autocompleteSuggestion-operator')).toHaveCount(2); }); - await page.testSubj.fill('queryInput', 'extension.raw : '); - await expect(page.testSubj.locator('autoCompleteSuggestionText')).toHaveCount(5); - const actualSuggestions = await page.testSubj - .locator('autoCompleteSuggestionText') - .allTextContents(); - expect(actualSuggestions.join(',')).toContain('jpg'); - }); -}); + } +); diff --git a/x-pack/plugins/discover_enhanced/ui_tests/tests/value_suggestions_non_time_based.spec.ts b/x-pack/plugins/discover_enhanced/ui_tests/tests/value_suggestions_non_time_based.spec.ts index 4ba9450869313..319d8af3e93c9 100644 --- a/x-pack/plugins/discover_enhanced/ui_tests/tests/value_suggestions_non_time_based.spec.ts +++ b/x-pack/plugins/discover_enhanced/ui_tests/tests/value_suggestions_non_time_based.spec.ts @@ -6,39 +6,42 @@ */ import { expect } from '@kbn/scout'; -import { test } from '../fixtures'; +import { test, testData, assertionMessages } from '../fixtures'; -test.describe('Discover app - value suggestions non-time based', () => { - test.beforeAll(async ({ esArchiver, kbnClient }) => { - await esArchiver.loadIfNeeded( - 'test/functional/fixtures/es_archiver/index_pattern_without_timefield' - ); - await kbnClient.importExport.load( - 'test/functional/fixtures/kbn_archiver/index_pattern_without_timefield' - ); - await kbnClient.uiSettings.update({ - defaultIndex: 'without-timefield', - 'doc_table:legacy': false, +test.describe( + 'Discover app - value suggestions non-time based', + { tag: ['@ess', '@svlSecurity', '@svlOblt', '@svlSearch'] }, + () => { + test.beforeAll(async ({ esArchiver, kbnClient, uiSettings }) => { + await esArchiver.loadIfNeeded(testData.ES_ARCHIVES.NO_TIME_FIELD); + await kbnClient.importExport.load(testData.KBN_ARCHIVES.NO_TIME_FIELD); + await uiSettings.set({ + defaultIndex: 'without-timefield', + }); }); - }); - test.afterAll(async ({ kbnClient }) => { - await kbnClient.uiSettings.unset('doc_table:legacy'); - await kbnClient.uiSettings.unset('defaultIndex'); - await kbnClient.savedObjects.cleanStandardList(); - }); + test.afterAll(async ({ kbnClient, uiSettings }) => { + await uiSettings.unset('defaultIndex'); + await kbnClient.savedObjects.cleanStandardList(); + }); - test.beforeEach(async ({ browserAuth, pageObjects }) => { - await browserAuth.loginAsPrivilegedUser(); - await pageObjects.discover.goto(); - }); + test.beforeEach(async ({ browserAuth, pageObjects }) => { + await browserAuth.loginAsViewer(); + await pageObjects.discover.goto(); + }); - test('shows all auto-suggest options for a filter in discover context app', async ({ page }) => { - await page.testSubj.fill('queryInput', 'type.keyword : '); - await expect(page.testSubj.locator('autoCompleteSuggestionText')).toHaveCount(1); - const actualSuggestions = await page.testSubj - .locator('autoCompleteSuggestionText') - .allTextContents(); - expect(actualSuggestions.join(',')).toContain('"apache"'); - }); -}); + test('shows all auto-suggest options for a filter in discover context app', async ({ + page, + }) => { + await page.testSubj.fill('queryInput', 'type.keyword : '); + await expect( + page.testSubj.locator('autoCompleteSuggestionText'), + assertionMessages.QUERY_BAR_VALIDATION.SUGGESTIONS_COUNT + ).toHaveCount(1); + const actualSuggestions = await page.testSubj + .locator('autoCompleteSuggestionText') + .allTextContents(); + expect(actualSuggestions.join(',')).toContain('"apache"'); + }); + } +); diff --git a/x-pack/plugins/discover_enhanced/ui_tests/tests/value_suggestions_use_time_range_disabled.spec.ts b/x-pack/plugins/discover_enhanced/ui_tests/tests/value_suggestions_use_time_range_disabled.spec.ts new file mode 100644 index 0000000000000..857709b091940 --- /dev/null +++ b/x-pack/plugins/discover_enhanced/ui_tests/tests/value_suggestions_use_time_range_disabled.spec.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/scout'; +import { test, testData, assertionMessages } from '../fixtures'; + +test.describe( + 'Discover app - value suggestions: useTimeRange disabled', + { tag: ['@ess', '@svlSecurity', '@svlOblt', '@svlSearch'] }, + () => { + test.beforeAll(async ({ esArchiver, kbnClient, uiSettings }) => { + await esArchiver.loadIfNeeded(testData.ES_ARCHIVES.LOGSTASH); + await kbnClient.importExport.load(testData.KBN_ARCHIVES.DASHBOARD_DRILLDOWNS); + await uiSettings.set({ + defaultIndex: testData.DATA_VIEW_ID.LOGSTASH, // TODO: investigate why it is required for `node scripts/playwright_test.js` run + 'timepicker:timeDefaults': `{ "from": "${testData.LOGSTASH_DEFAULT_START_TIME}", "to": "${testData.LOGSTASH_DEFAULT_END_TIME}"}`, + 'autocomplete:useTimeRange': false, + }); + }); + + test.afterAll(async ({ uiSettings, kbnClient }) => { + await uiSettings.unset('defaultIndex', 'timepicker:timeDefaults'); + await uiSettings.set({ 'autocomplete:useTimeRange': true }); + await kbnClient.savedObjects.cleanStandardList(); + }); + + test.beforeEach(async ({ browserAuth, pageObjects }) => { + await browserAuth.loginAsViewer(); + await pageObjects.discover.goto(); + }); + + test('show up if outside of range', async ({ page, pageObjects }) => { + await pageObjects.datePicker.setAbsoluteRange(testData.LOGSTASH_OUT_OF_RANGE_DATES); + await page.testSubj.fill('queryInput', 'extension.raw : '); + await expect( + page.testSubj.locator('autoCompleteSuggestionText'), + assertionMessages.QUERY_BAR_VALIDATION.SUGGESTIONS_COUNT + ).toHaveCount(5); + const actualSuggestions = await page.testSubj + .locator('autoCompleteSuggestionText') + .allTextContents(); + expect(actualSuggestions.join(',')).toContain('jpg'); + }); + + test('show up if in range', async ({ page, pageObjects }) => { + await pageObjects.datePicker.setAbsoluteRange(testData.LOGSTASH_IN_RANGE_DATES); + await page.testSubj.fill('queryInput', 'extension.raw : '); + await expect( + page.testSubj.locator('autoCompleteSuggestionText'), + assertionMessages.QUERY_BAR_VALIDATION.SUGGESTIONS_COUNT + ).toHaveCount(5); + const actualSuggestions = await page.testSubj + .locator('autoCompleteSuggestionText') + .allTextContents(); + expect(actualSuggestions.join(',')).toContain('jpg'); + }); + } +); diff --git a/x-pack/plugins/elastic_assistant/server/ai_assistant_service/helpers.ts b/x-pack/plugins/elastic_assistant/server/ai_assistant_service/helpers.ts index 57b7745a89c78..2a4ad628eb757 100644 --- a/x-pack/plugins/elastic_assistant/server/ai_assistant_service/helpers.ts +++ b/x-pack/plugins/elastic_assistant/server/ai_assistant_service/helpers.ts @@ -9,6 +9,9 @@ import type { ElasticsearchClient } from '@kbn/core-elasticsearch-server'; import type { KibanaRequest } from '@kbn/core-http-server'; import type { SavedObjectsClientContract } from '@kbn/core-saved-objects-api-server'; import type { MlPluginSetup } from '@kbn/ml-plugin/server'; +import { DeleteByQueryRequest } from '@elastic/elasticsearch/lib/api/types'; +import { i18n } from '@kbn/i18n'; +import { getResourceName } from '.'; import { knowledgeBaseIngestPipeline } from '../ai_assistant_data_clients/knowledge_base/ingest_pipeline'; import { GetElser } from '../types'; @@ -96,3 +99,45 @@ export const deletePipeline = async ({ esClient, id }: DeletePipelineParams): Pr return response.acknowledged; }; + +export const removeLegacyQuickPrompt = async (esClient: ElasticsearchClient) => { + try { + const deleteQuery: DeleteByQueryRequest = { + index: `${getResourceName('prompts')}-*`, + query: { + bool: { + must: [ + { + term: { + name: ESQL_QUERY_GENERATION_TITLE, + }, + }, + { + term: { + prompt_type: 'quick', + }, + }, + { + term: { + is_default: true, + }, + }, + ], + }, + }, + }; + return esClient.deleteByQuery(deleteQuery); + } catch (e) { + // swallow any errors + return { + total: 0, + }; + } +}; + +const ESQL_QUERY_GENERATION_TITLE = i18n.translate( + 'xpack.elasticAssistantPlugin.assistant.quickPrompts.esqlQueryGenerationTitle', + { + defaultMessage: 'ES|QL Query Generation', + } +); diff --git a/x-pack/plugins/elastic_assistant/server/ai_assistant_service/index.ts b/x-pack/plugins/elastic_assistant/server/ai_assistant_service/index.ts index 81ddd69fb67d3..233b5781ddf68 100644 --- a/x-pack/plugins/elastic_assistant/server/ai_assistant_service/index.ts +++ b/x-pack/plugins/elastic_assistant/server/ai_assistant_service/index.ts @@ -40,7 +40,7 @@ import { hasAIAssistantLicense } from '../routes/helpers'; const TOTAL_FIELDS_LIMIT = 2500; -function getResourceName(resource: string) { +export function getResourceName(resource: string) { return `.kibana-elastic-ai-assistant-${resource}`; } diff --git a/x-pack/plugins/elastic_assistant/server/plugin.ts b/x-pack/plugins/elastic_assistant/server/plugin.ts index 4386b95c3fa7a..110dbbc05f2a6 100755 --- a/x-pack/plugins/elastic_assistant/server/plugin.ts +++ b/x-pack/plugins/elastic_assistant/server/plugin.ts @@ -25,7 +25,7 @@ import { RequestContextFactory } from './routes/request_context_factory'; import { PLUGIN_ID } from '../common/constants'; import { registerRoutes } from './routes/register_routes'; import { appContextService } from './services/app_context'; -import { createGetElserId } from './ai_assistant_service/helpers'; +import { createGetElserId, removeLegacyQuickPrompt } from './ai_assistant_service/helpers'; export class ElasticAssistantPlugin implements @@ -109,6 +109,12 @@ export class ElasticAssistantPlugin this.getElserId = createGetElserId(this.mlTrainedModelsProvider); } }); + removeLegacyQuickPrompt(core.elasticsearch.client.asInternalUser) + .then((res) => { + if (res?.total) + this.logger.info(`Removed ${res.total} legacy quick prompts from AI Assistant`); + }) + .catch(() => {}); return { actions: plugins.actions, diff --git a/x-pack/plugins/enterprise_search/public/applications/ai_search/index.tsx b/x-pack/plugins/enterprise_search/public/applications/ai_search/index.tsx index 2920a4900f0bd..bcb4441750d08 100644 --- a/x-pack/plugins/enterprise_search/public/applications/ai_search/index.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/ai_search/index.tsx @@ -9,35 +9,17 @@ import React from 'react'; import { Routes, Route } from '@kbn/shared-ux-router'; -import { isVersionMismatch } from '../../../common/is_version_mismatch'; import { InitialAppData } from '../../../common/types'; -import { VersionMismatchPage } from '../shared/version_mismatch'; import { AISearchGuide } from './components/ai_search_guide/ai_search_guide'; import { ROOT_PATH } from './routes'; -export const EnterpriseSearchAISearch: React.FC = (props) => { - const { enterpriseSearchVersion, kibanaVersion } = props; - const incompatibleVersions = isVersionMismatch(enterpriseSearchVersion, kibanaVersion); - - const showView = () => { - if (incompatibleVersions) { - return ( - - ); - } - - return ; - }; - +export const EnterpriseSearchAISearch: React.FC = () => { return ( - {showView()} + ); diff --git a/x-pack/plugins/enterprise_search/public/applications/analytics/index.test.tsx b/x-pack/plugins/enterprise_search/public/applications/analytics/index.test.tsx index d3261eb265c06..a9914ca244f5b 100644 --- a/x-pack/plugins/enterprise_search/public/applications/analytics/index.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/analytics/index.test.tsx @@ -14,8 +14,6 @@ import React from 'react'; import { shallow } from 'enzyme'; -import { VersionMismatchPage } from '../shared/version_mismatch'; - import { AnalyticsOverview } from './components/analytics_overview/analytics_overview'; import { Analytics } from '.'; @@ -30,10 +28,4 @@ describe('EnterpriseSearchAnalytics', () => { expect(wrapper.find(AnalyticsOverview)).toHaveLength(1); }); - - it('renders VersionMismatchPage when there are mismatching versions', () => { - const wrapper = shallow(); - - expect(wrapper.find(VersionMismatchPage)).toHaveLength(1); - }); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/analytics/index.tsx b/x-pack/plugins/enterprise_search/public/applications/analytics/index.tsx index 19d7b67be6bfc..03de5eff97837 100644 --- a/x-pack/plugins/enterprise_search/public/applications/analytics/index.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/analytics/index.tsx @@ -9,30 +9,18 @@ import React from 'react'; import { Routes, Route } from '@kbn/shared-ux-router'; -import { isVersionMismatch } from '../../../common/is_version_mismatch'; import { InitialAppData } from '../../../common/types'; -import { VersionMismatchPage } from '../shared/version_mismatch'; import { AnalyticsCollectionView } from './components/analytics_collection_view/analytics_collection_view'; import { AnalyticsOverview } from './components/analytics_overview/analytics_overview'; import { ROOT_PATH, COLLECTION_VIEW_PATH } from './routes'; -export const Analytics: React.FC = (props) => { - const { enterpriseSearchVersion, kibanaVersion } = props; - const incompatibleVersions = isVersionMismatch(enterpriseSearchVersion, kibanaVersion); - +export const Analytics: React.FC = () => { return ( - {incompatibleVersions ? ( - - ) : ( - - )} + diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/customization_modal.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/customization_modal.tsx index 299a840cf8919..779158ae1e114 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/customization_modal.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/customization_modal.tsx @@ -20,6 +20,7 @@ import { EuiModalFooter, EuiModalHeader, EuiModalHeaderTitle, + useGeneratedHtmlId, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; @@ -44,6 +45,7 @@ export const CustomizationModal: React.FC = ({ sortFields, }) => { const { engine } = useValues(EngineLogic); + const modalTitleId = useGeneratedHtmlId(); const [selectedFilterFields, setSelectedFilterFields] = useState( filterFields.map(fieldNameToComboBoxOption) @@ -69,9 +71,9 @@ export const CustomizationModal: React.FC = ({ ); return ( - + - + {i18n.translate( 'xpack.enterpriseSearch.appSearch.documents.search.customizationModal.title', { @@ -132,8 +134,11 @@ export const CustomizationModal: React.FC = ({ - {CANCEL_BUTTON_LABEL} + + {CANCEL_BUTTON_LABEL} + { onSave({ diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/error_connecting/error_connecting.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/error_connecting/error_connecting.test.tsx deleted file mode 100644 index b307835534dd4..0000000000000 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/error_connecting/error_connecting.test.tsx +++ /dev/null @@ -1,23 +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 { shallow } from 'enzyme'; - -import { ErrorStatePrompt } from '../../../shared/error_state'; - -import { ErrorConnecting } from '.'; - -describe('ErrorConnecting', () => { - it('renders', () => { - const wrapper = shallow(); - - const errorStatePrompt = wrapper.find(ErrorStatePrompt); - expect(errorStatePrompt).toHaveLength(1); - }); -}); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/error_connecting/error_connecting.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/error_connecting/error_connecting.tsx deleted file mode 100644 index 2d1235e0b5c46..0000000000000 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/error_connecting/error_connecting.tsx +++ /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; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; - -import { KibanaPageTemplate } from '@kbn/shared-ux-page-kibana-template'; - -import { ErrorStatePrompt } from '../../../shared/error_state'; -import { SetAppSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome'; -import { SendAppSearchTelemetry as SendTelemetry } from '../../../shared/telemetry'; - -export const ErrorConnecting: React.FC = () => { - return ( - <> - - - - - - - - ); -}; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/index.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/index.test.tsx index bd8d6c30a0188..2c73e7606cd86 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/index.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/index.test.tsx @@ -16,7 +16,6 @@ import { Redirect } from 'react-router-dom'; import { shallow, ShallowWrapper } from 'enzyme'; -import { VersionMismatchPage } from '../shared/version_mismatch'; import { rerender } from '../test_helpers'; jest.mock('./app_logic', () => ({ AppLogic: jest.fn() })); @@ -26,7 +25,6 @@ import { Credentials } from './components/credentials'; import { EngineRouter } from './components/engine'; import { EngineCreation } from './components/engine_creation'; import { EnginesOverview } from './components/engines'; -import { ErrorConnecting } from './components/error_connecting'; import { Library } from './components/library'; import { MetaEngineCreation } from './components/meta_engine_creation'; import { RoleMappings } from './components/role_mappings'; @@ -42,12 +40,6 @@ describe('AppSearch', () => { expect(wrapper.find(SetupGuide)).toHaveLength(1); }); - it('renders VersionMismatchPage when there are mismatching versions', () => { - const wrapper = shallow(); - - expect(wrapper.find(VersionMismatchPage)).toHaveLength(1); - }); - it('renders AppSearchUnconfigured when config.host is not set', () => { setMockValues({ config: { host: '' } }); const wrapper = shallow(); @@ -55,14 +47,6 @@ describe('AppSearch', () => { expect(wrapper.find(AppSearchUnconfigured)).toHaveLength(1); }); - it('renders ErrorConnecting when Enterprise Search is unavailable', () => { - setMockValues({ errorConnectingMessage: '502 Bad Gateway' }); - const wrapper = shallow(); - - const errorConnection = wrapper.find(ErrorConnecting); - expect(errorConnection).toHaveLength(1); - }); - it('renders AppSearchConfigured when config.host is set & available', () => { setMockValues({ errorConnectingMessage: '', config: { host: 'some.url' } }); const wrapper = shallow(); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/index.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/index.tsx index 7f7237555867b..1a75cd58b1a24 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/index.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/index.tsx @@ -12,19 +12,15 @@ import { useValues } from 'kea'; import { Routes, Route } from '@kbn/shared-ux-router'; -import { isVersionMismatch } from '../../../common/is_version_mismatch'; import { InitialAppData } from '../../../common/types'; -import { HttpLogic } from '../shared/http'; import { KibanaLogic } from '../shared/kibana'; import { EndpointsHeaderAction } from '../shared/layout/endpoints_header_action'; -import { VersionMismatchPage } from '../shared/version_mismatch'; import { AppLogic } from './app_logic'; import { Credentials } from './components/credentials'; import { EngineRouter } from './components/engine'; import { EngineCreation } from './components/engine_creation'; import { EnginesOverview } from './components/engines'; -import { ErrorConnecting } from './components/error_connecting'; import { KibanaHeaderActions } from './components/layout'; import { Library } from './components/library'; import { MetaEngineCreation } from './components/meta_engine_creation'; @@ -47,24 +43,10 @@ import { export const AppSearch: React.FC = (props) => { const { config } = useValues(KibanaLogic); - const { errorConnectingMessage } = useValues(HttpLogic); - const { enterpriseSearchVersion, kibanaVersion } = props; - const incompatibleVersions = isVersionMismatch(enterpriseSearchVersion, kibanaVersion); - const showView = () => { if (!config.host) { return ; - } else if (incompatibleVersions) { - return ( - - ); - } else if (errorConnectingMessage) { - return ; } - return )} />; }; diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/connect/search_application_connect.tsx b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/connect/search_application_connect.tsx index f3047ac23b645..99f44cbb01f0c 100644 --- a/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/connect/search_application_connect.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/connect/search_application_connect.tsx @@ -21,7 +21,6 @@ import { } from '../../../routes'; import { EnterpriseSearchApplicationsPageTemplate } from '../../layout/page_template'; -import { SearchApplicationError } from '../search_application_error'; import { SearchApplicationViewLogic } from '../search_application_view_logic'; import { SearchApplicationAPI } from './search_application_api'; @@ -47,7 +46,6 @@ const DOCUMENTATION_TAB_TITLE = i18n.translate( defaultMessage: 'Documentation', } ); -const ConnectTabs: string[] = Object.values(SearchApplicationConnectTabs); const getTabBreadCrumb = (tabId: string) => { switch (tabId) { case SearchApplicationConnectTabs.SEARCHAPI: @@ -76,26 +74,6 @@ export const SearchApplicationConnect: React.FC = () => { ); }; - if (!ConnectTabs.includes(connectTabId)) { - return ( - - - - ); - } - return ( { } }; -const ContentTabs: string[] = Object.values(SearchApplicationContentTabs); - export const SearchApplicationContent = () => { const { searchApplicationName, isLoadingSearchApplication, hasSchemaConflicts } = useValues( SearchApplicationViewLogic @@ -74,26 +71,6 @@ export const SearchApplicationContent = () => { contentTabId?: string; }>(); - if (!ContentTabs.includes(contentTabId)) { - return ( - - - - ); - } - const onTabClick = (tab: SearchApplicationContentTabs) => () => { KibanaLogic.values.navigateToUrl( generateEncodedPath(SEARCH_APPLICATION_CONTENT_PATH, { diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_application_error.test.tsx b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_application_error.test.tsx deleted file mode 100644 index d24675822a730..0000000000000 --- a/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_application_error.test.tsx +++ /dev/null @@ -1,68 +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 { setMockValues } from '../../../__mocks__/kea_logic'; - -import React from 'react'; - -import { HttpError } from '../../../../../common/types/api'; - -import { ErrorStatePrompt } from '../../../shared/error_state'; -import { NotFoundPrompt } from '../../../shared/not_found'; -import { SendEnterpriseSearchTelemetry } from '../../../shared/telemetry'; - -import { mountWithIntl } from '../../../test_helpers'; - -import { SearchApplicationError } from './search_application_error'; - -describe('SearchApplicationError', () => { - beforeEach(() => { - jest.clearAllMocks(); - setMockValues({}); - }); - - it('renders 404 prompt for 404 error', () => { - const error = { - body: { - error: 'NOT_FOUND', - message: 'Not Found', - statusCode: 404, - }, - } as HttpError; - const wrapper = mountWithIntl(); - - expect(wrapper.find(NotFoundPrompt)).toHaveLength(1); - expect(wrapper.find(SendEnterpriseSearchTelemetry)).toHaveLength(1); - expect(wrapper.find(ErrorStatePrompt)).toHaveLength(0); - - const notFound = wrapper.find(NotFoundPrompt); - expect(notFound.prop('backToLink')).toEqual('/search_applications'); - expect(notFound.prop('backToContent')).toEqual('Back to Search Applications'); - - const telemetry = wrapper.find(SendEnterpriseSearchTelemetry); - expect(telemetry.prop('action')).toEqual('error'); - expect(telemetry.prop('metric')).toEqual('not_found'); - }); - - it('renders error prompt for api errors', () => { - const error = { - body: { - error: 'ERROR', - message: 'Internal Server Error', - statusCode: 500, - }, - } as HttpError; - const wrapper = mountWithIntl(); - - expect(wrapper.find(ErrorStatePrompt)).toHaveLength(1); - expect(wrapper.find(SendEnterpriseSearchTelemetry)).toHaveLength(1); - expect(wrapper.find(NotFoundPrompt)).toHaveLength(0); - - const telemetry = wrapper.find(SendEnterpriseSearchTelemetry); - expect(telemetry.prop('action')).toEqual('error'); - expect(telemetry.prop('metric')).toEqual('cannot_connect'); - }); -}); diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_application_error.tsx b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_application_error.tsx deleted file mode 100644 index 49a783dbbcec3..0000000000000 --- a/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_application_error.tsx +++ /dev/null @@ -1,48 +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 { APPLICATIONS_PLUGIN } from '../../../../../common/constants'; -import { HttpError } from '../../../../../common/types/api'; - -import { ErrorStatePrompt } from '../../../shared/error_state'; -import { NotFoundPrompt } from '../../../shared/not_found'; -import { SendEnterpriseSearchTelemetry } from '../../../shared/telemetry'; - -import { SEARCH_APPLICATIONS_PATH } from '../../routes'; - -export const SearchApplicationError: React.FC<{ error?: HttpError; notFound?: boolean }> = ({ - error, - notFound, -}) => { - if (notFound || error?.body?.statusCode === 404) { - return ( - <> - - - - ); - } - return ( - <> - - - - ); -}; diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_application_view.tsx b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_application_view.tsx index fef6f95c3b435..001d36a0faf43 100644 --- a/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_application_view.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_application_view.tsx @@ -6,13 +6,12 @@ */ import React, { useEffect } from 'react'; -import { useParams, Redirect } from 'react-router-dom'; +import { Redirect } from 'react-router-dom'; import { useValues, useActions } from 'kea'; import { Routes, Route } from '@kbn/shared-ux-router'; -import { Status } from '../../../../../common/types/api'; import { SEARCH_APPLICATION_PATH, SEARCH_APPLICATION_CONTENT_PATH, @@ -22,52 +21,23 @@ import { SearchApplicationContentTabs, } from '../../routes'; -import { EnterpriseSearchApplicationsPageTemplate } from '../layout/page_template'; import { DeleteSearchApplicationModal } from '../search_applications/delete_search_application_modal'; import { SearchApplicationConnect } from './connect/search_application_connect'; import { SearchApplicationDocsExplorer } from './docs_explorer/docs_explorer'; import { SearchApplicationContent } from './search_application_content'; -import { SearchApplicationError } from './search_application_error'; import { SearchApplicationViewLogic } from './search_application_view_logic'; export const SearchApplicationView: React.FC = () => { const { fetchSearchApplication, closeDeleteSearchApplicationModal } = useActions( SearchApplicationViewLogic ); - const { - searchApplicationName, - fetchSearchApplicationApiError, - fetchSearchApplicationApiStatus, - hasSchemaConflicts, - isDeleteModalVisible, - } = useValues(SearchApplicationViewLogic); - const { tabId = SearchApplicationViewTabs.DOCS_EXPLORER } = useParams<{ - tabId?: string; - }>(); + const { searchApplicationName, isDeleteModalVisible } = useValues(SearchApplicationViewLogic); useEffect(() => { fetchSearchApplication({ name: searchApplicationName }); }, [searchApplicationName]); - if (fetchSearchApplicationApiStatus === Status.ERROR) { - return ( - } - hasSchemaConflicts={hasSchemaConflicts} - /> - ); - } - return ( <> {isDeleteModalVisible ? ( @@ -92,22 +62,6 @@ export const SearchApplicationView: React.FC = () => { from={`${SEARCH_APPLICATION_PATH}/${SearchApplicationViewTabs.CONNECT}`} to={`${SEARCH_APPLICATION_PATH}/${SearchApplicationViewTabs.CONNECT}/${SearchApplicationConnectTabs.SEARCHAPI}`} /> - - - - - ); diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/search_applications/search_application_indices_flyout.tsx b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_applications/search_application_indices_flyout.tsx index 532ba053af1d0..78f20bc122ca8 100644 --- a/x-pack/plugins/enterprise_search/public/applications/applications/components/search_applications/search_application_indices_flyout.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_applications/search_application_indices_flyout.tsx @@ -26,7 +26,6 @@ import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; import { ENTERPRISE_SEARCH_CONTENT_PLUGIN } from '../../../../../common/constants'; -import { Status } from '../../../../../common/types/api'; import { EnterpriseSearchApplicationIndex } from '../../../../../common/types/search_applications'; @@ -35,8 +34,6 @@ import { healthColorsMap } from '../../../shared/constants/health_colors'; import { generateEncodedPath } from '../../../shared/encode_path_params'; import { EuiLinkTo } from '../../../shared/react_router_helpers'; -import { SearchApplicationError } from '../search_application/search_application_error'; - import { SearchApplicationIndicesFlyoutLogic } from './search_application_indices_flyout_logic'; export const SearchApplicationIndicesFlyout: React.FC = () => { @@ -45,15 +42,11 @@ export const SearchApplicationIndicesFlyout: React.FC = () => { searchApplicationName, isSearchApplicationLoading, isFlyoutVisible, - fetchSearchApplicationApiStatus, - fetchSearchApplicationApiError, } = useValues(SearchApplicationIndicesFlyoutLogic); const { closeFlyout } = useActions(SearchApplicationIndicesFlyoutLogic); if (!searchApplicationData) return null; const { indices } = searchApplicationData; - const searchApplicationFetchError = - fetchSearchApplicationApiStatus === Status.ERROR ? true : false; const columns: Array> = [ { @@ -139,11 +132,7 @@ export const SearchApplicationIndicesFlyout: React.FC = () => { - {searchApplicationFetchError ? ( - - ) : ( - - )} + ); diff --git a/x-pack/plugins/enterprise_search/public/applications/elasticsearch/index.tsx b/x-pack/plugins/enterprise_search/public/applications/elasticsearch/index.tsx index e5da2b5610d3d..881f042d1d626 100644 --- a/x-pack/plugins/enterprise_search/public/applications/elasticsearch/index.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/elasticsearch/index.tsx @@ -9,35 +9,17 @@ import React from 'react'; import { Routes, Route } from '@kbn/shared-ux-router'; -import { isVersionMismatch } from '../../../common/is_version_mismatch'; import { InitialAppData } from '../../../common/types'; -import { VersionMismatchPage } from '../shared/version_mismatch'; import { ElasticsearchGuide } from './components/elasticsearch_guide/elasticsearch_guide'; import { ROOT_PATH } from './routes'; -export const Elasticsearch: React.FC = (props) => { - const { enterpriseSearchVersion, kibanaVersion } = props; - const incompatibleVersions = isVersionMismatch(enterpriseSearchVersion, kibanaVersion); - - const showView = () => { - if (incompatibleVersions) { - return ( - - ); - } - - return ; - }; - +export const Elasticsearch: React.FC = () => { return ( - {showView()} + ); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/connector/generate_connector_names_api_logic.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/connector/generate_connector_names_api_logic.ts index 8d2ee0ee87aa3..d2bd5cfe71493 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/connector/generate_connector_names_api_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/connector/generate_connector_names_api_logic.ts @@ -10,6 +10,7 @@ import { HttpLogic } from '../../../shared/http'; export interface GenerateConnectorNamesApiArgs { connectorName?: string; connectorType?: string; + isManagedConnector?: boolean; } export interface GenerateConnectorNamesApiResponse { @@ -19,14 +20,16 @@ export interface GenerateConnectorNamesApiResponse { } export const generateConnectorNames = async ( - { connectorType, connectorName }: GenerateConnectorNamesApiArgs = { connectorType: 'custom' } + { connectorType, connectorName, isManagedConnector }: GenerateConnectorNamesApiArgs = { + connectorType: 'custom', + } ) => { if (connectorType === '') { connectorType = 'custom'; } const route = `/internal/enterprise_search/connectors/generate_connector_name`; return await HttpLogic.values.http.post(route, { - body: JSON.stringify({ connectorName, connectorType }), + body: JSON.stringify({ connectorName, connectorType, isManagedConnector }), }); }; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connector_detail/attach_index_box.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connector_detail/attach_index_box.tsx index 5a2e279026bda..dbc854251e33a 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connector_detail/attach_index_box.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connector_detail/attach_index_box.tsx @@ -27,7 +27,7 @@ import { import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; -import { Connector } from '@kbn/search-connectors'; +import { Connector, MANAGED_CONNECTOR_INDEX_PREFIX } from '@kbn/search-connectors'; import { Status } from '../../../../../common/types/api'; @@ -65,66 +65,114 @@ export const AttachIndexBox: React.FC = ({ connector }) => createApiError, attachApiError, } = useValues(AttachIndexLogic); + + const { makeRequest } = useActions(FetchAvailableIndicesAPILogic); + const { data, status } = useValues(FetchAvailableIndicesAPILogic); + const isLoading = [Status.IDLE, Status.LOADING].includes(status); + + // Helper function to remove the managed connector index prefix from the index name + const removePrefixConnectorIndex = (connectorIndexName: string) => { + if (!connector.is_native) { + return connectorIndexName; + } + if (connectorIndexName.startsWith(MANAGED_CONNECTOR_INDEX_PREFIX)) { + return connectorIndexName.substring(MANAGED_CONNECTOR_INDEX_PREFIX.length); + } + return connectorIndexName; + }; + + // Helper function to add the managed connector index prefix to the index name + const prefixConnectorIndex = (connectorIndexName: string) => { + if (!connector.is_native) { + return connectorIndexName; + } + if (connectorIndexName.startsWith(MANAGED_CONNECTOR_INDEX_PREFIX)) { + return connectorIndexName; + } + return `${MANAGED_CONNECTOR_INDEX_PREFIX}${connectorIndexName}`; + }; + + const [query, setQuery] = useState<{ + isFullMatch: boolean; + searchValue: string; + }>(); + const [sanitizedName, setSanitizedName] = useState( + prefixConnectorIndex(formatApiName(connector.name)) + ); + const [selectedIndex, setSelectedIndex] = useState< { label: string; shouldCreate?: boolean } | undefined >( + // For managed connectors, the index name should be displayed without prefix + // As `content-` is fixed UI element connector.index_name ? { - label: connector.index_name, + label: removePrefixConnectorIndex(connector.index_name), } : undefined ); - const [selectedLanguage] = useState(); - const [query, setQuery] = useState<{ - isFullMatch: boolean; - searchValue: string; - }>(); - const [sanitizedName, setSanitizedName] = useState(formatApiName(connector.name)); - - const { makeRequest } = useActions(FetchAvailableIndicesAPILogic); - const { data, status } = useValues(FetchAvailableIndicesAPILogic); - const isLoading = [Status.IDLE, Status.LOADING].includes(status); const onSave = () => { - if (selectedIndex?.shouldCreate) { - createIndex({ indexName: selectedIndex.label, language: selectedLanguage ?? null }); - } else if (selectedIndex && !(selectedIndex.label === connector.index_name)) { - attachIndex({ connectorId: connector.id, indexName: selectedIndex.label }); + if (!selectedIndex) return; + // Always attach and/or create prefixed index for managed connectors + const prefixedIndex = prefixConnectorIndex(selectedIndex.label); + if (selectedIndex.shouldCreate) { + createIndex({ + indexName: prefixedIndex, + language: null, + }); + } else if (connector.index_name !== prefixedIndex) { + attachIndex({ + connectorId: connector.id, + indexName: prefixedIndex, + }); } }; + // For managed connectors ensure that only prefixed indices are displayed in the dropdown + // This takes care of the initial component state where all indices could be displayed briefly const options: Array> = isLoading ? [] - : data?.indexNames.map((name) => { - return { + : data?.indexNames + .filter((name) => !connector.is_native || name.startsWith(MANAGED_CONNECTOR_INDEX_PREFIX)) + .map((name) => ({ label: name, - }; - }) ?? []; + value: removePrefixConnectorIndex(name), + })) ?? []; const hasMatchingOptions = data?.indexNames.some((name) => - name.toLocaleLowerCase().includes(query?.searchValue.toLocaleLowerCase() ?? '') + name + .toLocaleLowerCase() + .includes(prefixConnectorIndex(query?.searchValue?.toLocaleLowerCase() || '')) ) ?? false; + const isFullMatch = data?.indexNames.some( - (name) => name.toLocaleLowerCase() === query?.searchValue.toLocaleLowerCase() + (name) => + name.toLocaleLowerCase() === + prefixConnectorIndex(query?.searchValue?.toLocaleLowerCase() || '') ) ?? false; - const shouldPrependUserInputAsOption = !!query?.searchValue && hasMatchingOptions && !isFullMatch; + const shouldPrependUserInputAsOption = + !!query && + !!query.searchValue && + query.searchValue !== MANAGED_CONNECTOR_INDEX_PREFIX && + hasMatchingOptions && + !isFullMatch; const groupedOptions: Array> = shouldPrependUserInputAsOption ? [ - ...[ - { - label: CREATE_NEW_INDEX_GROUP_LABEL, - options: [ - { - label: query.searchValue, - }, - ], - }, - ], - ...[{ label: SELECT_EXISTING_INDEX_GROUP_LABEL, options }], + { + label: CREATE_NEW_INDEX_GROUP_LABEL, + options: [ + { + label: prefixConnectorIndex(query!.searchValue), + value: query!.searchValue, + }, + ], + }, + { label: SELECT_EXISTING_INDEX_GROUP_LABEL, options }, ] : [{ label: SELECT_EXISTING_INDEX_GROUP_LABEL, options }]; @@ -144,7 +192,8 @@ export const AttachIndexBox: React.FC = ({ connector }) => }, [query]); useEffect(() => { - setSanitizedName(formatApiName(connector.name)); + // Suggested name for managed connector should include the content- prefix + setSanitizedName(prefixConnectorIndex(formatApiName(connector.name))); }, [connector.name]); const { hash } = useLocation(); @@ -170,9 +219,10 @@ export const AttachIndexBox: React.FC = ({ connector }) => } ) : attachApiError?.body?.message || createApiError?.body?.message || undefined; + if (indexName) { - // We don't want to let people edit indices when on the index route - return <>; + // Do not render when on the index route + return null; } return ( @@ -189,8 +239,8 @@ export const AttachIndexBox: React.FC = ({ connector }) => @@ -201,10 +251,20 @@ export const AttachIndexBox: React.FC = ({ connector }) => 'xpack.enterpriseSearch.attachIndexBox.euiFormRow.associatedIndexLabel', { defaultMessage: 'Associated index' } )} - helpText={i18n.translate( - 'xpack.enterpriseSearch.attachIndexBox.euiFormRow.associatedIndexHelpTextLabel', - { defaultMessage: 'You can use an existing index or create a new one.' } - )} + helpText={ + connector.is_native + ? i18n.translate( + 'xpack.enterpriseSearch.attachIndexBox.euiFormRow.associatedManagedConnectorIndexHelpTextLabel', + { + defaultMessage: + 'Managed connector indices must be prefixed. Use an existing index or create a new one.', + } + ) + : i18n.translate( + 'xpack.enterpriseSearch.attachIndexBox.euiFormRow.associatedIndexHelpTextLabel', + { defaultMessage: 'You can use an existing index or create a new one.' } + ) + } error={error} isInvalid={!!error} > @@ -217,11 +277,13 @@ export const AttachIndexBox: React.FC = ({ connector }) => 'xpack.enterpriseSearch.attachIndexBox.euiFormRow.indexSelector.customOption', { defaultMessage: 'Create index {searchValue}', - values: { searchValue: '{searchValue}' }, + values: { searchValue: prefixConnectorIndex('{searchValue}') }, } )} isLoading={isLoading} options={groupedOptions} + singleSelection={{ asPlainText: connector.is_native }} + prepend={connector.is_native ? MANAGED_CONNECTOR_INDEX_PREFIX : undefined} onKeyDown={(event) => { // Index name should not contain spaces if (event.key === ' ') { @@ -229,28 +291,34 @@ export const AttachIndexBox: React.FC = ({ connector }) => } }} onSearchChange={(searchValue) => { + // Match by option value to ensure accurate comparison with non-prefixed + // user input for managed connectors setQuery({ - isFullMatch: options.some((option) => option.label === searchValue), - searchValue, + isFullMatch: options.some( + (option) => option.value === prefixConnectorIndex(searchValue) + ), + searchValue: prefixConnectorIndex(searchValue), }); }} onChange={(selection) => { - const currentSelection = selection[0] ?? undefined; + const currentSelection = selection[0]; const selectedIndexOption = currentSelection ? { - label: currentSelection.label, + label: removePrefixConnectorIndex(currentSelection.label), shouldCreate: shouldPrependUserInputAsOption && - !!(currentSelection?.label === query?.searchValue), + currentSelection.value === query?.searchValue, } : undefined; setSelectedIndex(selectedIndexOption); }} selectedOptions={selectedIndex ? [selectedIndex] : undefined} onCreateOption={(value) => { - setSelectedIndex({ label: value.trim(), shouldCreate: true }); + setSelectedIndex({ + label: removePrefixConnectorIndex(value.trim()), + shouldCreate: true, + }); }} - singleSelection />
        @@ -261,8 +329,12 @@ export const AttachIndexBox: React.FC = ({ connector }) => onSave()} - disabled={!selectedIndex || selectedIndex.label === connector.index_name} + onClick={onSave} + disabled={ + !selectedIndex || + prefixConnectorIndex(selectedIndex.label) === connector.index_name || + !!error + } isLoading={isSaveLoading} > {i18n.translate('xpack.enterpriseSearch.attachIndexBox.saveConfigurationButtonLabel', { @@ -314,15 +386,13 @@ export const AttachIndexBox: React.FC = ({ connector }) => } )} - {indexExists[sanitizedName] ? ( + {indexExists[sanitizedName] && ( {i18n.translate('xpack.enterpriseSearch.attachIndexBox.indexNameExistsError', { defaultMessage: 'Index with name {indexName} already exists', values: { indexName: sanitizedName }, })} - ) : ( - <> )} diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connector_detail/native_connector_configuration.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connector_detail/native_connector_configuration.tsx index 29a54c913301a..86a3bf83f1b78 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connector_detail/native_connector_configuration.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connector_detail/native_connector_configuration.tsx @@ -11,7 +11,6 @@ import { useValues } from 'kea'; import { EuiBadge, - EuiCallOut, EuiFlexGroup, EuiFlexItem, EuiIcon, @@ -23,12 +22,8 @@ import { import { i18n } from '@kbn/i18n'; import { BetaConnectorCallout } from '../../../shared/beta/beta_connector_callout'; -import { HttpLogic } from '../../../shared/http'; import { KibanaLogic } from '../../../shared/kibana'; -import { GenerateConnectorApiKeyApiLogic } from '../../api/connector/generate_connector_api_key_api_logic'; - -import { ApiKeyConfig } from '../search_index/connector/api_key_configuration'; import { ConvertConnector } from '../search_index/connector/native_connector_configuration/convert_connector'; import { NativeConnectorConfigurationConfig } from '../search_index/connector/native_connector_configuration/native_connector_configuration_config'; import { ResearchConfiguration } from '../search_index/connector/native_connector_configuration/research_configuration'; @@ -39,9 +34,7 @@ import { ConnectorViewLogic } from './connector_view_logic'; export const NativeConnectorConfiguration: React.FC = () => { const { connector } = useValues(ConnectorViewLogic); - const { config, connectorTypes: connectors } = useValues(KibanaLogic); - const { errorConnectingMessage } = useValues(HttpLogic); - const { data: apiKeyData } = useValues(GenerateConnectorApiKeyApiLogic); + const { connectorTypes: connectors } = useValues(KibanaLogic); const NATIVE_CONNECTORS = useMemo( () => connectors.filter(({ isNative }) => isNative), @@ -68,7 +61,6 @@ export const NativeConnectorConfiguration: React.FC = () => { }; const iconPath = nativeConnector.iconPath; - const hasApiKey = !!(connector.api_key_id ?? apiKeyData); // TODO service_type === "" is considered unknown/custom connector multipleplaces replace all of them with a better solution const isBeta = @@ -114,39 +106,8 @@ export const NativeConnectorConfiguration: React.FC = () => { - {config.host && config.canDeployEntSearch && errorConnectingMessage && ( - <> - -

        - {i18n.translate( - 'xpack.enterpriseSearch.content.indices.configurationConnector.nativeConnector.entSearchWarning.text', - { - defaultMessage: - 'Elastic managed connectors require a running Enterprise Search instance.', - } - )} -

        -
        - - - - )} - { - <> - - - - } + + {connector.index_name && ( <> @@ -170,23 +131,6 @@ export const NativeConnectorConfiguration: React.FC = () => { - - -

        - {i18n.translate( - 'xpack.enterpriseSearch.content.connector_detail.nativeConfigurationConnector.apiKey.title', - { defaultMessage: 'API Key' } - )} -

        -
        - - -
        - diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connector_detail/overview.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connector_detail/overview.tsx index 906c64ccae8e2..3fdd3d379eacb 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connector_detail/overview.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connector_detail/overview.tsx @@ -95,7 +95,7 @@ export const ConnectorDetailOverview: React.FC = () => { <> { = ({ isCrawler }) => { {productFeatures.hasDefaultIngestPipeline && showDefaultSettingsFlyout && ( setShowDefaultSettingsFlyout(false)} /> )} - {Boolean(errorConnectingMessage) && ( - <> - - - - )} diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connectors/create_connector/components/connector_description_popover.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connectors/create_connector/components/connector_description_popover.tsx index 9e0aed3fa75f0..f91a8eff670fe 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connectors/create_connector/components/connector_description_popover.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connectors/create_connector/components/connector_description_popover.tsx @@ -6,7 +6,10 @@ */ import React, { useState } from 'react'; +import { css } from '@emotion/react'; + import { + EuiButton, EuiButtonIcon, EuiCallOut, EuiFlexGroup, @@ -83,13 +86,15 @@ const connectorClientPopoverPanels = [ ]; export interface ConnectorDescriptionPopoverProps { - isDisabled: boolean; isNative: boolean; + isRunningLocally?: boolean; + showIsOnlySelfManaged: boolean; } export const ConnectorDescriptionPopover: React.FC = ({ isNative, - isDisabled, + isRunningLocally, + showIsOnlySelfManaged, }) => { const [isPopoverOpen, setIsPopoverOpen] = useState(false); const panels = isNative ? nativePopoverPanels : connectorClientPopoverPanels; @@ -111,55 +116,115 @@ export const ConnectorDescriptionPopover: React.FC - - {isDisabled && ( - - - + {(showIsOnlySelfManaged || isRunningLocally) && ( + <> + + + - + size="s" + iconType="warning" + color="warning" + /> + + + + + )} + + {!isRunningLocally && ( + + {panels.map((panel) => { + return ( + + + + + {panel.icons.map((icon, index) => ( + + {icon} + + ))} + + + + +

        {panel.description}

        +
        +
        +
        +
        + ); + })}
        )} - - - {panels.map((panel) => { - return ( - - + + + + +

        + {i18n.translate( + 'xpack.enterpriseSearch.createConnector.connectorDescriptionBadge.learnMore', + { defaultMessage: 'Explore Elastic Cloud with your 14-day free trial' } + )} +

        +
        +
        + + + {i18n.translate( + 'xpack.enterpriseSearch.createConnector.connectorDescriptionBadge.learnMore', + { + defaultMessage: + 'Take advantage of Elastic managed connectors and generative AI capabilities to address search challenges across your organization in real time, at scale.', + } + )} + + + + - - - {panel.icons.map((icon, index) => ( - - {icon} - - ))} - - - - -

        {panel.description}

        -
        -
        -
        + {i18n.translate('xpack.enterpriseSearch.createConnector.startTrialButtonLabel', { + defaultMessage: 'Start free trial', + })} +
        - ); - })} -
        + + + )}
        ); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connectors/create_connector/create_connector.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connectors/create_connector/create_connector.tsx index 6e83bf98c2371..095990c823f0a 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connectors/create_connector/create_connector.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connectors/create_connector/create_connector.tsx @@ -65,9 +65,14 @@ export const CreateConnector: React.FC = () => { const { setCurrentStep } = useActions(NewConnectorLogic); const stepStates = generateStepState(currentStep); + const { config } = useValues(KibanaLogic); + const isRunningLocally = (config.host ?? '').includes('localhost'); + useEffect(() => { - // TODO: separate this to ability and preference - if (selectedConnector && !selectedConnector.isNative && selfManagePreference === 'native') { + if ( + (selectedConnector && !selectedConnector.isNative && selfManagePreference === 'native') || + isRunningLocally + ) { setSelfManagePreference('selfManaged'); } }, [selectedConnector]); @@ -141,6 +146,7 @@ export const CreateConnector: React.FC = () => { setSelfManagePreference(preference); }} error={errorToText(error)} + isRunningLocally={isRunningLocally} /> ), }; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connectors/create_connector/start_step.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connectors/create_connector/start_step.tsx index 46840d577e4d6..fb740189148d7 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connectors/create_connector/start_step.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connectors/create_connector/start_step.tsx @@ -41,6 +41,7 @@ import { SelfManagePreference } from './create_connector'; interface StartStepProps { error?: string | React.ReactNode; + isRunningLocally: boolean; onSelfManagePreferenceChange(preference: SelfManagePreference): void; selfManagePreference: SelfManagePreference; setCurrentStep: Function; @@ -49,6 +50,7 @@ interface StartStepProps { export const StartStep: React.FC = ({ title, + isRunningLocally, selfManagePreference, setCurrentStep, onSelfManagePreferenceChange, @@ -144,6 +146,7 @@ export const StartStep: React.FC = ({ generateConnectorName({ connectorName: rawName, connectorType: selectedConnector.serviceType, + isManagedConnector: selectedConnector.isNative, }); } }} @@ -208,14 +211,15 @@ export const StartStep: React.FC = ({ { defaultMessage: 'Elastic managed' } )} checked={selfManagePreference === 'native'} - disabled={selectedConnector?.isNative === false} + disabled={selectedConnector?.isNative === false || isRunningLocally} onChange={() => onSelfManagePreferenceChange('native')} name="setUp" /> @@ -233,7 +237,7 @@ export const StartStep: React.FC = ({ /> - + diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/error_connecting/error_connecting.test.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/error_connecting/error_connecting.test.tsx deleted file mode 100644 index b307835534dd4..0000000000000 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/error_connecting/error_connecting.test.tsx +++ /dev/null @@ -1,23 +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 { shallow } from 'enzyme'; - -import { ErrorStatePrompt } from '../../../shared/error_state'; - -import { ErrorConnecting } from '.'; - -describe('ErrorConnecting', () => { - it('renders', () => { - const wrapper = shallow(); - - const errorStatePrompt = wrapper.find(ErrorStatePrompt); - expect(errorStatePrompt).toHaveLength(1); - }); -}); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/error_connecting/error_connecting.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/error_connecting/error_connecting.tsx deleted file mode 100644 index 69f479026014e..0000000000000 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/error_connecting/error_connecting.tsx +++ /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; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; - -import { KibanaPageTemplate } from '@kbn/shared-ux-page-kibana-template'; - -import { ErrorStatePrompt } from '../../../shared/error_state'; -import { SetSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome'; -import { SendEnterpriseSearchTelemetry as SendTelemetry } from '../../../shared/telemetry'; - -export const ErrorConnecting: React.FC = () => { - return ( - <> - - - - - - - - ); -}; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/new_index/method_connector/new_connector_logic.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/new_index/method_connector/new_connector_logic.ts index 0c8a81d90149a..f2f327f40650e 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/new_index/method_connector/new_connector_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/new_index/method_connector/new_connector_logic.ts @@ -192,6 +192,7 @@ export const NewConnectorLogic = kea { )} - {Boolean(errorConnectingMessage) && ( - - - - )} { }} > - {errorConnectingMessage && productFeatures.hasWebCrawler && } - <> - - - {availableIngestionMethodOptions.map((type) => ( - - { - if (type === INGESTION_METHOD_IDS.CONNECTOR) { - KibanaLogic.values.navigateToUrl(NEW_INDEX_SELECT_CONNECTOR_PATH); - } else if (type === INGESTION_METHOD_IDS.CRAWLER) { - KibanaLogic.values.navigateToUrl(NEW_CRAWLER_PATH); - } else { - KibanaLogic.values.navigateToUrl(NEW_API_PATH); - } - }} - /> - - ))} - - - + + + {availableIngestionMethodOptions.map((type) => ( + + { + if (type === INGESTION_METHOD_IDS.CONNECTOR) { + KibanaLogic.values.navigateToUrl(NEW_INDEX_SELECT_CONNECTOR_PATH); + } else if (type === INGESTION_METHOD_IDS.CRAWLER) { + KibanaLogic.values.navigateToUrl(NEW_CRAWLER_PATH); + } else { + KibanaLogic.values.navigateToUrl(NEW_API_PATH); + } + }} + /> + + ))} + + ); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/components/cannot_connect.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/components/cannot_connect.tsx deleted file mode 100644 index 3fa7b40117a68..0000000000000 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/components/cannot_connect.tsx +++ /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; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; - -import { EuiCallOut, EuiSpacer, EuiText } from '@elastic/eui'; - -import { i18n } from '@kbn/i18n'; - -import { FormattedMessage } from '@kbn/i18n-react'; - -import { EuiLinkTo } from '../../../../shared/react_router_helpers'; - -import { ERROR_STATE_PATH } from '../../../routes'; - -export const CannotConnect: React.FC = () => { - return ( - - - - - {i18n.translate('xpack.enterpriseSearch.content.cannotConnect.body', { - defaultMessage: 'More information.', - })} - - ), - }} - /> - - - ); -}; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/search_index.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/search_index.tsx index 6cdd06f1586a2..e8876a7c56818 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/search_index.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/search_index.tsx @@ -18,8 +18,6 @@ import { i18n } from '@kbn/i18n'; import { ClientConfigType } from '../../../../../common/types'; import { generateEncodedPath } from '../../../shared/encode_path_params'; -import { ErrorStatePrompt } from '../../../shared/error_state'; -import { HttpLogic } from '../../../shared/http'; import { KibanaLogic } from '../../../shared/kibana'; import { SEARCH_INDEX_PATH, SEARCH_INDEX_TAB_PATH } from '../../routes'; @@ -71,7 +69,6 @@ export const SearchIndex: React.FC = () => { }>(); const { indexName } = useValues(IndexNameLogic); - const { errorConnectingMessage } = useValues(HttpLogic); /** * Guided Onboarding needs us to mark the add data step as complete as soon as the user has data in an index. @@ -286,32 +283,19 @@ export const SearchIndex: React.FC = () => { }} > - + ); }; interface ContentProps { config?: ClientConfigType; - errorConnectingMessage: string; index?: ElasticsearchViewIndex; tabId?: string; tabs: EuiTabbedContentTab[]; } -const Content: React.FC = ({ - config, - errorConnectingMessage, - index, - tabs, - tabId, -}) => { +const Content: React.FC = ({ index, tabs, tabId }) => { const selectedTab = useMemo(() => tabs.find((tab) => tab.id === tabId), [tabId]); const onTabClick = (tab: EuiTabbedContentTab) => { @@ -329,9 +313,6 @@ const Content: React.FC = ({ if (isCrawlerIndex(index) && !index.connector) { return ; } - if (isCrawlerIndex(index) && (Boolean(errorConnectingMessage) || !config?.host)) { - return ; - } return ( <> diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_indices/search_indices.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_indices/search_indices.tsx index dece1b4beb2f7..d44e95b6271e4 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_indices/search_indices.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_indices/search_indices.tsx @@ -11,10 +11,8 @@ import { useValues, useActions } from 'kea'; import { EuiButton, - EuiCallOut, EuiFlexGroup, EuiFlexItem, - EuiSpacer, EuiTitle, EuiSwitch, EuiSearchBar, @@ -26,14 +24,13 @@ import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; import { AddContentEmptyPrompt } from '../../../shared/add_content_empty_prompt'; -import { HttpLogic } from '../../../shared/http/http_logic'; import { KibanaLogic } from '../../../shared/kibana'; -import { EuiButtonTo, EuiLinkTo } from '../../../shared/react_router_helpers'; +import { EuiLinkTo } from '../../../shared/react_router_helpers'; import { handlePageChange } from '../../../shared/table_pagination'; import { NEW_API_PATH } from '../../routes'; import { EnterpriseSearchContentPageTemplate } from '../layout/page_template'; -import { CannotConnect } from '../search_index/components/cannot_connect'; +// import { CannotConnect } from '../search_index/components/cannot_connect'; import { DefaultSettingsFlyout } from '../settings/default_settings_flyout'; import { DeleteIndexModal } from './delete_index_modal'; @@ -53,8 +50,7 @@ export const SearchIndices: React.FC = () => { const [showHiddenIndices, setShowHiddenIndices] = useState(false); const [onlyShowSearchOptimizedIndices, setOnlyShowSearchOptimizedIndices] = useState(false); const [searchQuery, setSearchValue] = useState(''); - const { config, productFeatures } = useValues(KibanaLogic); - const { errorConnectingMessage } = useValues(HttpLogic); + const { productFeatures } = useValues(KibanaLogic); const [showDefaultSettingsFlyout, setShowDefaultSettingsFlyout] = useState(false); useEffect(() => { @@ -142,37 +138,6 @@ export const SearchIndices: React.FC = () => { {productFeatures.hasDefaultIngestPipeline && showDefaultSettingsFlyout && ( setShowDefaultSettingsFlyout(false)} /> )} - {config.host && config.canDeployEntSearch && errorConnectingMessage && ( - <> - - - - )} - {!config.host && config.canDeployEntSearch && ( - <> - -

        - -

        - - - -
        - - - )} {!hasNoIndices ? ( diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/index.test.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/index.test.tsx index 9fcfe7c7fcfab..a32062256eec5 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/index.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/index.test.tsx @@ -15,7 +15,6 @@ import React from 'react'; import { shallow } from 'enzyme'; import { SetupGuide } from '../enterprise_search_overview/components/setup_guide'; -import { VersionMismatchPage } from '../shared/version_mismatch'; import { SearchIndicesRouter } from './components/search_indices'; @@ -28,15 +27,6 @@ describe('EnterpriseSearchContent', () => { expect(wrapper.find(SetupGuide)).toHaveLength(1); }); - it('renders VersionMismatchPage when there are mismatching versions', () => { - setMockValues({ config: { canDeployEntSearch: true, host: 'host' } }); - const wrapper = shallow( - - ); - - expect(wrapper.find(VersionMismatchPage)).toHaveLength(1); - }); - it('renders EnterpriseSearchContentConfigured when config.host is set & available', () => { setMockValues({ config: { canDeployEntSearch: true, host: 'some.url' }, diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/index.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/index.tsx index 2ec701aa9847b..d464923dea2ca 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/index.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/index.tsx @@ -8,17 +8,10 @@ import React from 'react'; import { Redirect } from 'react-router-dom'; -import { useValues } from 'kea'; - import { Route, Routes } from '@kbn/shared-ux-router'; -import { isVersionMismatch } from '../../../common/is_version_mismatch'; import { InitialAppData } from '../../../common/types'; import { SetupGuide } from '../enterprise_search_overview/components/setup_guide'; -import { ErrorStatePrompt } from '../shared/error_state'; -import { HttpLogic } from '../shared/http'; -import { KibanaLogic } from '../shared/kibana'; -import { VersionMismatchPage } from '../shared/version_mismatch'; import { ConnectorsRouter } from './components/connectors/connectors_router'; import { CrawlersRouter } from './components/connectors/crawlers_router'; @@ -27,44 +20,20 @@ import { SearchIndicesRouter } from './components/search_indices'; import { CONNECTORS_PATH, CRAWLERS_PATH, - ERROR_STATE_PATH, ROOT_PATH, SEARCH_INDICES_PATH, SETUP_GUIDE_PATH, } from './routes'; export const EnterpriseSearchContent: React.FC = (props) => { - const { config } = useValues(KibanaLogic); - const { errorConnectingMessage } = useValues(HttpLogic); - const { enterpriseSearchVersion, kibanaVersion } = props; - const incompatibleVersions = isVersionMismatch(enterpriseSearchVersion, kibanaVersion); - - const showView = () => { - if (config.host && config.canDeployEntSearch && incompatibleVersions) { - return ( - - ); - } - - return )} />; - }; - return ( - - {config.host && config.canDeployEntSearch && errorConnectingMessage ? ( - - ) : ( - - )} + + )} /> - {showView()} ); }; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/error_connecting/error_connecting.test.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/error_connecting/error_connecting.test.tsx deleted file mode 100644 index b307835534dd4..0000000000000 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/error_connecting/error_connecting.test.tsx +++ /dev/null @@ -1,23 +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 { shallow } from 'enzyme'; - -import { ErrorStatePrompt } from '../../../shared/error_state'; - -import { ErrorConnecting } from '.'; - -describe('ErrorConnecting', () => { - it('renders', () => { - const wrapper = shallow(); - - const errorStatePrompt = wrapper.find(ErrorStatePrompt); - expect(errorStatePrompt).toHaveLength(1); - }); -}); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/error_connecting/error_connecting.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/error_connecting/error_connecting.tsx deleted file mode 100644 index 6fc4ae2842200..0000000000000 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/error_connecting/error_connecting.tsx +++ /dev/null @@ -1,21 +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 { KibanaPageTemplate } from '@kbn/shared-ux-page-kibana-template'; - -import { ErrorStatePrompt } from '../../../shared/error_state'; -import { SendEnterpriseSearchTelemetry as SendTelemetry } from '../../../shared/telemetry'; - -export const ErrorConnecting: React.FC = () => ( - - - - - -); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/product_selector/product_selector.test.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/product_selector/product_selector.test.tsx index dd67bf33d987b..3718a495cd17b 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/product_selector/product_selector.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/product_selector/product_selector.test.tsx @@ -11,8 +11,6 @@ import React from 'react'; import { shallow } from 'enzyme'; -import { ErrorStateCallout } from '../../../shared/error_state'; - import { TrialCallout } from '../trial_callout'; import { ElasticsearchProductCard } from './elasticsearch_product_card'; @@ -34,23 +32,6 @@ describe('ProductSelector', () => { expect(wrapper.find(TrialCallout)).toHaveLength(1); }); - it('does not render connection error callout without an error', () => { - setMockValues({ config: { canDeployEntSearch: true, host: 'localhost' } }); - const wrapper = shallow(); - - expect(wrapper.find(ErrorStateCallout)).toHaveLength(0); - }); - - it('does render connection error callout with an error', () => { - setMockValues({ - config: { canDeployEntSearch: true, host: 'localhost' }, - errorConnectingMessage: '502 Bad Gateway', - }); - const wrapper = shallow(); - - expect(wrapper.find(ErrorStateCallout)).toHaveLength(1); - }); - describe('access checks when host is set', () => { beforeEach(() => { setMockValues({ config: { canDeployEntSearch: true, host: 'localhost' } }); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/product_selector/product_selector.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/product_selector/product_selector.tsx index 1f25f5f69c2e0..7c22f5bfd433a 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/product_selector/product_selector.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/product_selector/product_selector.tsx @@ -20,8 +20,6 @@ import { import { i18n } from '@kbn/i18n'; import { ApiKeyPanel } from '../../../shared/api_key/api_key_panel'; -import { ErrorStateCallout } from '../../../shared/error_state'; -import { HttpLogic } from '../../../shared/http'; import { KibanaLogic } from '../../../shared/kibana'; import { SetSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome'; import { SearchLabsBanner } from '../../../shared/search_labs_banner/search_labs_banner'; @@ -39,11 +37,8 @@ import './product_selector.scss'; import { WelcomeBanner } from './welcome_banner'; export const ProductSelector: React.FC = () => { - const { config } = useValues(KibanaLogic); - const { errorConnectingMessage } = useValues(HttpLogic); const { user } = useValues(KibanaLogic); - const showErrorConnecting = !!(config.host && errorConnectingMessage); // The create index flow does not work without ent-search, when content is updated // to no longer rely on ent-search we can always show the Add Content component @@ -80,12 +75,6 @@ export const ProductSelector: React.FC = () => { - {showErrorConnecting && ( - <> - - - - )} diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/index.test.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/index.test.tsx index 6742de0816f81..7754aa0cf11f7 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/index.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/index.test.tsx @@ -11,8 +11,6 @@ import React from 'react'; import { shallow } from 'enzyme'; -import { VersionMismatchPage } from '../shared/version_mismatch'; - import { ProductSelector } from './components/product_selector'; import { SetupGuide } from './components/setup_guide'; @@ -29,17 +27,4 @@ describe('EnterpriseSearchOverview', () => { expect(wrapper.find(SetupGuide)).toHaveLength(1); expect(wrapper.find(ProductSelector)).toHaveLength(1); }); - - it('renders the version error message if versions mismatch and the host is configured', () => { - setMockValues({ - errorConnectingMessage: '', - config: { host: 'localhost' }, - }); - const wrapper = shallow( - - ); - - expect(wrapper.find(VersionMismatchPage)).toHaveLength(1); - expect(wrapper.find(ProductSelector)).toHaveLength(0); - }); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/index.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/index.tsx index 64ab8e44a69ae..70d4b40bb7f90 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/index.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/index.tsx @@ -7,49 +7,22 @@ import React from 'react'; -import { useValues } from 'kea'; - import { Routes, Route } from '@kbn/shared-ux-router'; -import { isVersionMismatch } from '../../../common/is_version_mismatch'; import { InitialAppData } from '../../../common/types'; -import { KibanaLogic } from '../shared/kibana'; -import { VersionMismatchPage } from '../shared/version_mismatch'; import { ProductSelector } from './components/product_selector'; import { SetupGuide } from './components/setup_guide'; import { ROOT_PATH, SETUP_GUIDE_PATH } from './routes'; -export const EnterpriseSearchOverview: React.FC = ({ - enterpriseSearchVersion, - kibanaVersion, -}) => { - const { config } = useValues(KibanaLogic); - - const incompatibleVersions = !!( - config.host && isVersionMismatch(enterpriseSearchVersion, kibanaVersion) - ); - - const showView = () => { - if (incompatibleVersions) { - return ( - - ); - } - - return ; - }; - +export const EnterpriseSearchOverview: React.FC = ({}) => { return ( - {showView()} + ); diff --git a/x-pack/plugins/enterprise_search/public/applications/search_experiences/index.tsx b/x-pack/plugins/enterprise_search/public/applications/search_experiences/index.tsx index 118cb5cb7caf2..e41918d8ce29d 100644 --- a/x-pack/plugins/enterprise_search/public/applications/search_experiences/index.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/search_experiences/index.tsx @@ -9,35 +9,17 @@ import React from 'react'; import { Routes, Route } from '@kbn/shared-ux-router'; -import { isVersionMismatch } from '../../../common/is_version_mismatch'; import { InitialAppData } from '../../../common/types'; -import { VersionMismatchPage } from '../shared/version_mismatch'; import { SearchExperiencesGuide } from './components/search_experiences_guide'; import { ROOT_PATH } from './routes'; -export const SearchExperiences: React.FC = (props) => { - const { enterpriseSearchVersion, kibanaVersion } = props; - const incompatibleVersions = isVersionMismatch(enterpriseSearchVersion, kibanaVersion); - - const showView = () => { - if (incompatibleVersions) { - return ( - - ); - } - - return ; - }; - +export const SearchExperiences: React.FC = () => { return ( - {showView()} + ); diff --git a/x-pack/plugins/enterprise_search/public/applications/semantic_search/index.tsx b/x-pack/plugins/enterprise_search/public/applications/semantic_search/index.tsx index f33142bae940c..e6e5e3e66bbf4 100644 --- a/x-pack/plugins/enterprise_search/public/applications/semantic_search/index.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/semantic_search/index.tsx @@ -12,29 +12,17 @@ import { Switch } from 'react-router-dom'; import { Route } from '@kbn/shared-ux-router'; -import { isVersionMismatch } from '../../../common/is_version_mismatch'; import { InitialAppData } from '../../../common/types'; -import { VersionMismatchPage } from '../shared/version_mismatch'; import { SemanticSearchGuide } from './components/semantic_search_guide/semantic_search_guide'; import { ROOT_PATH } from './routes'; -export const EnterpriseSearchSemanticSearch: React.FC = (props) => { - const { enterpriseSearchVersion, kibanaVersion } = props; - const incompatibleVersions = isVersionMismatch(enterpriseSearchVersion, kibanaVersion); - +export const EnterpriseSearchSemanticSearch: React.FC = () => { return ( - {incompatibleVersions ? ( - - ) : ( - - )} + ); diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/error_state/error_state_prompt.scss b/x-pack/plugins/enterprise_search/public/applications/shared/error_state/error_state_prompt.scss deleted file mode 100644 index 0d9926ab147bf..0000000000000 --- a/x-pack/plugins/enterprise_search/public/applications/shared/error_state/error_state_prompt.scss +++ /dev/null @@ -1,12 +0,0 @@ -.troubleshootingSteps { - text-align: left; - - li { - margin: $euiSizeS auto; - } - - ul, - ol { - margin-bottom: 0; - } -} diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/error_state/error_state_prompt.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/error_state/error_state_prompt.test.tsx deleted file mode 100644 index 867702b8326ab..0000000000000 --- a/x-pack/plugins/enterprise_search/public/applications/shared/error_state/error_state_prompt.test.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; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import '../../__mocks__/shallow_useeffect.mock'; -import { setMockValues, mockKibanaValues } from '../../__mocks__/kea_logic'; - -import React from 'react'; - -import { mountWithIntl } from '../../test_helpers'; - -import { ErrorStatePrompt } from '.'; - -describe('ErrorState', () => { - const values = { - config: {}, - cloud: { isCloudEnabled: true }, - errorConnectingMessage: '502 Bad Gateway', - }; - - beforeAll(() => { - setMockValues(values); - }); - - it('renders an error message', () => { - const wrapper = mountWithIntl(); - expect(wrapper.text()).toContain('502 Bad Gateway'); - }); - - it('renders a cloud specific error on cloud deployments', () => { - setMockValues({ - ...values, - cloud: { isCloudEnabled: true }, - }); - const wrapper = mountWithIntl(); - - expect(wrapper.find('[data-test-subj="CloudError"]').exists()).toBe(true); - expect(wrapper.find('[data-test-subj="SelfManagedError"]').exists()).toBe(false); - }); - - it('renders a different error if not a cloud deployment', () => { - setMockValues({ - ...values, - cloud: { isCloudEnabled: false }, - }); - const wrapper = mountWithIntl(); - - expect(wrapper.find('[data-test-subj="CloudError"]').exists()).toBe(false); - expect(wrapper.find('[data-test-subj="SelfManagedError"]').exists()).toBe(true); - }); - - describe('chrome visiblity', () => { - it('sets chrome visibility to true when not on personal dashboard route', () => { - mockKibanaValues.history.location.pathname = '/overview'; - mountWithIntl(); - - expect(mockKibanaValues.setChromeIsVisible).toHaveBeenCalledWith(true); - }); - - it('sets chrome visibility to false when on personal dashboard route', () => { - mockKibanaValues.history.location.pathname = '/p/sources'; - mountWithIntl(); - - expect(mockKibanaValues.setChromeIsVisible).toHaveBeenCalledWith(false); - }); - }); -}); diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/error_state/error_state_prompt.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/error_state/error_state_prompt.tsx deleted file mode 100644 index e744d8d9b1250..0000000000000 --- a/x-pack/plugins/enterprise_search/public/applications/shared/error_state/error_state_prompt.tsx +++ /dev/null @@ -1,171 +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, { useEffect } from 'react'; - -import { useValues } from 'kea'; - -import { EuiEmptyPrompt, EuiCode, EuiLink, EuiCodeBlock, EuiCallOut } from '@elastic/eui'; -import { CloudSetup } from '@kbn/cloud-plugin/public'; -import { i18n } from '@kbn/i18n'; -import { FormattedMessage } from '@kbn/i18n-react'; - -import { HttpLogic } from '../http'; -import { KibanaLogic } from '../kibana'; -import { EuiButtonTo } from '../react_router_helpers'; - -import './error_state_prompt.scss'; - -/** - * Personal dashboard urls begin with /p/ - * EX: http://localhost:5601/app/enterprise_search/workplace_search/p/sources - */ -const WORKPLACE_SEARCH_PERSONAL_DASHBOARD_PATH = '/p/'; - -export const ErrorStatePrompt: React.FC = () => { - const { setChromeIsVisible, history } = useValues(KibanaLogic); - const isWorkplaceSearchPersonalDashboardRoute = history.location.pathname.includes( - WORKPLACE_SEARCH_PERSONAL_DASHBOARD_PATH - ); - - useEffect(() => { - // We hide the Kibana chrome for Workplace Search for Personal Dashboard routes. It is reenabled when the user enters the - // Workplace Search organization admin section of the product. If the Enterprise Search API is not working, we never show - // the chrome and this can have adverse effects when the user leaves thispage and returns to Kibana. To get around this, - // we always show the chrome when the error state is shown, unless the user is visiting the Personal Dashboard. - setChromeIsVisible(!isWorkplaceSearchPersonalDashboardRoute); - }, []); - - return ( - - - - } - titleSize="l" - body={} - actions={[ - - - , - ]} - /> - ); -}; - -export const ErrorStateCallout: React.FC = () => { - return ( - - - - - - - ); -}; - -const ErrorBody: React.FC = () => { - const { errorConnectingMessage } = useValues(HttpLogic); - const { config, cloud } = useValues(KibanaLogic); - return ( - <> -

        - - {config.host} - - ), - }} - /> -

        - {errorConnectingMessage} - {cloud?.isCloudEnabled ? cloudError(cloud) : nonCloudError()} - - ); -}; - -const cloudError = (cloud: Partial) => { - const deploymentUrl = cloud?.deploymentUrl; - return ( -

        - - {i18n.translate( - 'xpack.enterpriseSearch.errorConnectingState.cloudErrorMessageLinkText', - { - defaultMessage: 'Check your deployment settings', - } - )} - - ), - }} - /> -

        - ); -}; - -const nonCloudError = () => { - return ( -
          -
        1. - config/kibana.yml, - }} - /> -
        2. -
        3. - -
        4. -
        5. - -
            -
          • - -
          • -
          -
        6. -
        - ); -}; diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/version_mismatch/version_mismatch_error.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/version_mismatch/version_mismatch_error.test.tsx deleted file mode 100644 index f6d5ef4aa4212..0000000000000 --- a/x-pack/plugins/enterprise_search/public/applications/shared/version_mismatch/version_mismatch_error.test.tsx +++ /dev/null @@ -1,23 +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 { mount } from 'enzyme'; - -import { VersionMismatchError } from './version_mismatch_error'; - -describe('VersionMismatchError', () => { - it('renders', () => { - const wrapper = mount( - - ); - - expect(wrapper.find('EuiEmptyPrompt').text()).toContain('Enterprise Search version: 8.0.0'); - expect(wrapper.find('EuiEmptyPrompt').text()).toContain('Kibana version: 8.1.0'); - }); -}); diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/version_mismatch/version_mismatch_error.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/version_mismatch/version_mismatch_error.tsx deleted file mode 100644 index 56915663961de..0000000000000 --- a/x-pack/plugins/enterprise_search/public/applications/shared/version_mismatch/version_mismatch_error.tsx +++ /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; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; - -import { EuiEmptyPrompt, EuiSpacer } from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; - -interface Props { - enterpriseSearchVersion?: string; - kibanaVersion?: string; -} - -export const VersionMismatchError: React.FC = ({ - enterpriseSearchVersion, - kibanaVersion, -}) => { - return ( - - {i18n.translate('xpack.enterpriseSearch.versionMismatch.title', { - defaultMessage: 'Incompatible version error', - })} - - } - titleSize="l" - body={ - <> - {i18n.translate('xpack.enterpriseSearch.versionMismatch.body', { - defaultMessage: - 'Your Kibana and Enterprise Search versions do not match. To access Enterprise Search, use the same major and minor version for each service.', - })} - -
        - {i18n.translate('xpack.enterpriseSearch.versionMismatch.enterpriseSearchVersionText', { - defaultMessage: 'Enterprise Search version: {enterpriseSearchVersion}', - values: { enterpriseSearchVersion }, - })} -
        -
        - {i18n.translate('xpack.enterpriseSearch.versionMismatch.kibanaVersionText', { - defaultMessage: 'Kibana version: {kibanaVersion}', - values: { kibanaVersion }, - })} -
        - - } - /> - ); -}; diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/version_mismatch/version_mismatch_page.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/version_mismatch/version_mismatch_page.test.tsx deleted file mode 100644 index d86a1187bd4b9..0000000000000 --- a/x-pack/plugins/enterprise_search/public/applications/shared/version_mismatch/version_mismatch_page.test.tsx +++ /dev/null @@ -1,26 +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 { shallow } from 'enzyme'; - -import { VersionMismatchError } from './version_mismatch_error'; -import { VersionMismatchPage } from './version_mismatch_page'; - -describe('VersionMismatchPage', () => { - it('renders', () => { - const wrapper = shallow( - - ); - expect(wrapper.find(VersionMismatchError).exists()).toBe(true); - expect(wrapper.find(VersionMismatchError).props()).toEqual({ - kibanaVersion: '8.1.0', - enterpriseSearchVersion: '8.0.0', - }); - }); -}); diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/version_mismatch/version_mismatch_page.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/version_mismatch/version_mismatch_page.tsx deleted file mode 100644 index 0d730f9dee9ef..0000000000000 --- a/x-pack/plugins/enterprise_search/public/applications/shared/version_mismatch/version_mismatch_page.tsx +++ /dev/null @@ -1,23 +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 { KibanaPageTemplate } from '@kbn/shared-ux-page-kibana-template'; - -import { VersionMismatchError } from './version_mismatch_error'; - -interface Props { - enterpriseSearchVersion?: string; - kibanaVersion?: string; -} - -export const VersionMismatchPage: React.FC = (props) => ( - - - -); diff --git a/x-pack/plugins/enterprise_search/public/applications/vector_search/index.tsx b/x-pack/plugins/enterprise_search/public/applications/vector_search/index.tsx index ce678121253f0..2d85725dc552d 100644 --- a/x-pack/plugins/enterprise_search/public/applications/vector_search/index.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/vector_search/index.tsx @@ -12,29 +12,17 @@ import { Switch } from 'react-router-dom'; import { Route } from '@kbn/shared-ux-router'; -import { isVersionMismatch } from '../../../common/is_version_mismatch'; import { InitialAppData } from '../../../common/types'; -import { VersionMismatchPage } from '../shared/version_mismatch'; import { VectorSearchGuide } from './components/vector_search_guide/vector_search_guide'; import { ROOT_PATH } from './routes'; -export const EnterpriseSearchVectorSearch: React.FC = (props) => { - const { enterpriseSearchVersion, kibanaVersion } = props; - const incompatibleVersions = isVersionMismatch(enterpriseSearchVersion, kibanaVersion); - +export const EnterpriseSearchVectorSearch: React.FC = () => { return ( - {incompatibleVersions ? ( - - ) : ( - - )} + ); diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/index.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/index.test.tsx index 6771168239126..67b7469fcfe36 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/index.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/index.test.tsx @@ -15,12 +15,9 @@ import { Redirect } from 'react-router-dom'; import { shallow } from 'enzyme'; -import { VersionMismatchPage } from '../shared/version_mismatch'; - import { WorkplaceSearchHeaderActions } from './components/layout'; import { SourcesRouter } from './views/content_sources'; import { SourceAdded } from './views/content_sources/components/source_added'; -import { ErrorState } from './views/error_state'; import { NotFound } from './views/not_found'; import { Overview } from './views/overview'; import { RoleMappings } from './views/role_mappings'; @@ -34,14 +31,6 @@ import { } from '.'; describe('WorkplaceSearch', () => { - it('renders VersionMismatchPage when there are mismatching versions', () => { - const wrapper = shallow( - - ); - - expect(wrapper.find(VersionMismatchPage)).toHaveLength(1); - }); - it('renders WorkplaceSearchUnconfigured when config.host is not set', () => { setMockValues({ config: { host: '' } }); const wrapper = shallow(); @@ -55,26 +44,6 @@ describe('WorkplaceSearch', () => { expect(wrapper.find(WorkplaceSearchConfigured)).toHaveLength(1); }); - - it('renders ErrorState when not on SetupGuide', () => { - mockUseRouteMatch.mockReturnValue(false); - setMockValues({ errorConnectingMessage: '502 Bad Gateway' }); - - const wrapper = shallow(); - - const errorState = wrapper.find(ErrorState); - expect(errorState).toHaveLength(1); - }); - - it('does not render ErrorState when on SetupGuide', () => { - mockUseRouteMatch.mockReturnValue(true); - setMockValues({ errorConnectingMessage: '502 Bad Gateway' }); - - const wrapper = shallow(); - - const errorState = wrapper.find(ErrorState); - expect(errorState).toHaveLength(0); - }); }); describe('WorkplaceSearchUnconfigured', () => { diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/index.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/index.tsx index e9332fe81bdab..6233208119c44 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/index.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/index.tsx @@ -12,11 +12,8 @@ import { useActions, useValues } from 'kea'; import { Routes, Route } from '@kbn/shared-ux-router'; -import { isVersionMismatch } from '../../../common/is_version_mismatch'; import { InitialAppData } from '../../../common/types'; -import { HttpLogic } from '../shared/http'; import { KibanaLogic } from '../shared/kibana'; -import { VersionMismatchPage } from '../shared/version_mismatch'; import { AppLogic } from './app_logic'; import { WorkplaceSearchHeaderActions } from './components/layout'; @@ -39,7 +36,6 @@ import { AccountSettings } from './views/account_settings'; import { ApiKeys } from './views/api_keys'; import { SourcesRouter } from './views/content_sources'; import { SourceAdded } from './views/content_sources/components/source_added'; -import { ErrorState } from './views/error_state'; import { GroupsRouter } from './views/groups'; import { NotFound } from './views/not_found'; import { OAuthAuthorize } from './views/oauth_authorize'; @@ -52,22 +48,9 @@ import { SetupGuide } from './views/setup_guide'; export const WorkplaceSearch: React.FC = (props) => { const { config } = useValues(KibanaLogic); - const { errorConnectingMessage } = useValues(HttpLogic); - const { enterpriseSearchVersion, kibanaVersion } = props; - const incompatibleVersions = isVersionMismatch(enterpriseSearchVersion, kibanaVersion); - const isSetupGuidePath = !!useRouteMatch(SETUP_GUIDE_PATH); if (!config.host) { return ; - } else if (incompatibleVersions) { - return ( - - ); - } else if (errorConnectingMessage && !isSetupGuidePath) { - return ; } return ; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/error_state/error_state.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/error_state/error_state.test.tsx deleted file mode 100644 index 2c3b49230e394..0000000000000 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/error_state/error_state.test.tsx +++ /dev/null @@ -1,23 +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 { shallow } from 'enzyme'; - -import { ErrorStatePrompt } from '../../../shared/error_state'; - -import { ErrorState } from '.'; - -describe('ErrorState', () => { - it('renders', () => { - const wrapper = shallow(); - - const prompt = wrapper.find(ErrorStatePrompt); - expect(prompt).toHaveLength(1); - }); -}); diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/error_state/error_state.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/error_state/error_state.tsx deleted file mode 100644 index fc93896d931f7..0000000000000 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/error_state/error_state.tsx +++ /dev/null @@ -1,30 +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 { KibanaPageTemplate } from '@kbn/shared-ux-page-kibana-template'; - -import { WORKPLACE_SEARCH_PLUGIN } from '../../../../../common/constants'; -import { ErrorStatePrompt } from '../../../shared/error_state'; -import { SetWorkplaceSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome'; -import { SendWorkplaceSearchTelemetry as SendTelemetry } from '../../../shared/telemetry'; -import { ViewContentHeader } from '../../components/shared/view_content_header'; - -export const ErrorState: React.FC = () => { - return ( - <> - - - - - - - - - ); -}; diff --git a/x-pack/plugins/enterprise_search/server/lib/connectors/generate_config.ts b/x-pack/plugins/enterprise_search/server/lib/connectors/generate_config.ts index d9f0eefd0fb5c..c8b6c414510fd 100644 --- a/x-pack/plugins/enterprise_search/server/lib/connectors/generate_config.ts +++ b/x-pack/plugins/enterprise_search/server/lib/connectors/generate_config.ts @@ -7,7 +7,11 @@ import { IScopedClusterClient } from '@kbn/core/server'; -import { Connector, CONNECTORS_INDEX } from '@kbn/search-connectors'; +import { + Connector, + CONNECTORS_INDEX, + MANAGED_CONNECTOR_INDEX_PREFIX, +} from '@kbn/search-connectors'; import { createIndex } from '../indices/create_index'; import { indexOrAliasExists } from '../indices/exists_index'; @@ -20,10 +24,10 @@ export const generateConfig = async (client: IScopedClusterClient, connector: Co if (connector.index_name) { associatedIndex = connector.index_name; } else { - associatedIndex = await generatedIndexName( - client, - connector.name || connector.service_type || 'my-connector' // pass a default name to generate a readable index name rather than gibberish - ); + const indexPrefix = connector.is_native ? MANAGED_CONNECTOR_INDEX_PREFIX : ''; // managed connectors need to be prefixed with `content-` + const connectorReference = connector.name || connector.service_type || 'my-connector'; // pass a default name to generate a readable index name rather than gibberish + + associatedIndex = await generatedIndexName(client, indexPrefix + connectorReference); } if (!indexOrAliasExists(client, associatedIndex)) { diff --git a/x-pack/plugins/enterprise_search/server/lib/connectors/generate_connector_name.ts b/x-pack/plugins/enterprise_search/server/lib/connectors/generate_connector_name.ts index 56f849c551400..374e32861253b 100644 --- a/x-pack/plugins/enterprise_search/server/lib/connectors/generate_connector_name.ts +++ b/x-pack/plugins/enterprise_search/server/lib/connectors/generate_connector_name.ts @@ -9,22 +9,34 @@ import { v4 as uuidv4 } from 'uuid'; import { IScopedClusterClient } from '@kbn/core-elasticsearch-server'; +import { MANAGED_CONNECTOR_INDEX_PREFIX } from '@kbn/search-connectors'; + import { ErrorCode } from '../../../common/types/error_codes'; import { toAlphanumeric } from '../../../common/utils/to_alphanumeric'; import { indexOrAliasExists } from '../indices/exists_index'; +const addIndexPrefix = (indexName: string, isManagedConnector: boolean): string => { + const indexPrefix = isManagedConnector ? MANAGED_CONNECTOR_INDEX_PREFIX : 'connector-'; + return `${indexPrefix}${indexName}`; +}; + +const addConnectorPrefix = (indexName: string): string => { + return `connector-${indexName}`; +}; + export const generateConnectorName = async ( client: IScopedClusterClient, connectorType: string, - userConnectorName?: string + userConnectorName?: string, + isManagedConnector: boolean = false ): Promise<{ apiKeyName: string; connectorName: string; indexName: string }> => { const prefix = toAlphanumeric(connectorType); if (!prefix || prefix.length === 0) { throw new Error('Connector type or connectorName is required'); } if (userConnectorName) { - let indexName = `connector-${userConnectorName}`; + let indexName = addIndexPrefix(userConnectorName, isManagedConnector); const resultSameName = await indexOrAliasExists(client, indexName); // index with same name doesn't exist if (!resultSameName) { @@ -36,12 +48,14 @@ export const generateConnectorName = async ( } // if the index name already exists, we will generate until it doesn't for 20 times for (let i = 0; i < 20; i++) { - indexName = `connector-${userConnectorName}-${uuidv4().split('-')[1].slice(0, 4)}`; + const randomizedConnectorName = `${userConnectorName}-${uuidv4().split('-')[1].slice(0, 4)}`; + + indexName = addIndexPrefix(randomizedConnectorName, isManagedConnector); const result = await indexOrAliasExists(client, indexName); if (!result) { return { - apiKeyName: indexName, + apiKeyName: addConnectorPrefix(randomizedConnectorName), connectorName: userConnectorName, indexName, }; @@ -49,14 +63,15 @@ export const generateConnectorName = async ( } } else { for (let i = 0; i < 20; i++) { - const connectorName = `${prefix}-${uuidv4().split('-')[1].slice(0, 4)}`; - const indexName = `connector-${connectorName}`; + const randomizedConnectorName = `${prefix}-${uuidv4().split('-')[1].slice(0, 4)}`; + const indexName = addIndexPrefix(randomizedConnectorName, isManagedConnector); const result = await indexOrAliasExists(client, indexName); + if (!result) { return { - apiKeyName: indexName, - connectorName, + apiKeyName: addConnectorPrefix(randomizedConnectorName), + connectorName: randomizedConnectorName, indexName, }; } diff --git a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/connectors.ts b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/connectors.ts index 6108580463893..8a5f96f54edb6 100644 --- a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/connectors.ts +++ b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/connectors.ts @@ -842,17 +842,19 @@ export function registerConnectorRoutes({ router, log }: RouteDependencies) { body: schema.object({ connectorName: schema.maybe(schema.string()), connectorType: schema.string(), + isManagedConnector: schema.maybe(schema.boolean()), }), }, }, elasticsearchErrorHandler(log, async (context, request, response) => { const { client } = (await context.core).elasticsearch; - const { connectorType, connectorName } = request.body; + const { connectorType, connectorName, isManagedConnector } = request.body; try { const generatedNames = await generateConnectorName( client, connectorType ?? 'custom', - connectorName + connectorName, + isManagedConnector ); return response.ok({ body: generatedNames, diff --git a/x-pack/plugins/entity_manager/server/lib/entity_client.ts b/x-pack/plugins/entity_manager/server/lib/entity_client.ts index 7045bee1fc538..35abe63c5fd23 100644 --- a/x-pack/plugins/entity_manager/server/lib/entity_client.ts +++ b/x-pack/plugins/entity_manager/server/lib/entity_client.ts @@ -5,6 +5,7 @@ * 2.0. */ +import { without } from 'lodash'; import { EntityV2, EntityDefinition, EntityDefinitionUpdate } from '@kbn/entities-schema'; import { SavedObjectsClientContract } from '@kbn/core-saved-objects-api-server'; import { ElasticsearchClient } from '@kbn/core-elasticsearch-server'; @@ -23,10 +24,27 @@ import { stopTransforms } from './entities/stop_transforms'; import { deleteIndices } from './entities/delete_index'; import { EntityDefinitionWithState } from './entities/types'; import { EntityDefinitionUpdateConflict } from './entities/errors/entity_definition_update_conflict'; -import { EntitySource, getEntityInstancesQuery } from './queries'; +import { EntitySource, SortBy, getEntityInstancesQuery } from './queries'; import { mergeEntitiesList, runESQLQuery } from './queries/utils'; import { UnknownEntityType } from './entities/errors/unknown_entity_type'; +interface SearchCommon { + start: string; + end: string; + sort?: SortBy; + metadataFields?: string[]; + filters?: string[]; + limit?: number; +} + +export type SearchByType = SearchCommon & { + type: string; +}; + +export type SearchBySources = SearchCommon & { + sources: EntitySource[]; +}; + export class EntityClient { constructor( private options: { @@ -191,17 +209,11 @@ export class EntityClient { type, start, end, + sort, metadataFields = [], filters = [], limit = 10, - }: { - type: string; - start: string; - end: string; - metadataFields?: string[]; - filters?: string[]; - limit?: number; - }) { + }: SearchByType) { const sources = await this.getEntitySources({ type }); if (sources.length === 0) { throw new UnknownEntityType(`No sources found for entity type [${type}]`); @@ -213,6 +225,7 @@ export class EntityClient { end, metadataFields, filters, + sort, limit, }); } @@ -221,21 +234,22 @@ export class EntityClient { sources, start, end, + sort, metadataFields = [], filters = [], limit = 10, - }: { - sources: EntitySource[]; - start: string; - end: string; - metadataFields?: string[]; - filters?: string[]; - limit?: number; - }) { + }: SearchBySources) { const entities = await Promise.all( sources.map(async (source) => { - const mandatoryFields = [source.timestamp_field, ...source.identity_fields]; + const mandatoryFields = [ + ...source.identity_fields, + ...(source.timestamp_field ? [source.timestamp_field] : []), + ...(source.display_name ? [source.display_name] : []), + ]; const metaFields = [...metadataFields, ...source.metadata_fields]; + + // operations on an unmapped field result in a failing query so we verify + // field capabilities beforehand const { fields } = await this.options.esClient.fieldCaps({ index: source.index_patterns, fields: [...mandatoryFields, ...metaFields], @@ -244,15 +258,25 @@ export class EntityClient { const sourceHasMandatoryFields = mandatoryFields.every((field) => !!fields[field]); if (!sourceHasMandatoryFields) { // we can't build entities without id fields so we ignore the source. - // filters should likely behave similarly. + // TODO filters should likely behave similarly. we should also throw + const missingFields = mandatoryFields.filter((field) => !fields[field]); this.options.logger.info( - `Ignoring source for type [${source.type}] with index_patterns [${source.index_patterns}] because some mandatory fields [${mandatoryFields}] are not mapped` + `Ignoring source for type [${source.type}] with index_patterns [${ + source.index_patterns + }] because some mandatory fields [${missingFields.join(', ')}] are not mapped` ); return []; } // but metadata field not being available is fine const availableMetadataFields = metaFields.filter((field) => fields[field]); + if (availableMetadataFields.length < metaFields.length) { + this.options.logger.info( + `Ignoring unmapped fields [${without(metaFields, ...availableMetadataFields).join( + ', ' + )}]` + ); + } const query = getEntityInstancesQuery({ source: { @@ -262,6 +286,7 @@ export class EntityClient { }, start, end, + sort, limit, }); this.options.logger.debug(`Entity query: ${query}`); @@ -271,14 +296,10 @@ export class EntityClient { esClient: this.options.esClient, }); - return rawEntities.map((entity) => { - entity['entity.id'] = source.identity_fields.map((field) => entity[field]).join(':'); - entity['entity.type'] = source.type; - return entity; - }); + return rawEntities; }) ).then((results) => results.flat()); - return mergeEntitiesList(entities).slice(0, limit); + return mergeEntitiesList(sources, entities).slice(0, limit); } } diff --git a/x-pack/plugins/entity_manager/server/lib/queries/index.test.ts b/x-pack/plugins/entity_manager/server/lib/queries/index.test.ts index 539d20c464794..d8b3c9347cdd1 100644 --- a/x-pack/plugins/entity_manager/server/lib/queries/index.test.ts +++ b/x-pack/plugins/entity_manager/server/lib/queries/index.test.ts @@ -18,19 +18,21 @@ describe('getEntityInstancesQuery', () => { metadata_fields: ['host.name'], filters: [], timestamp_field: 'custom_timestamp_field', + display_name: 'service.id', }, limit: 5, start: '2024-11-20T19:00:00.000Z', end: '2024-11-20T20:00:00.000Z', + sort: { field: 'entity.id', direction: 'DESC' }, }); expect(query).toEqual( - 'FROM logs-*,metrics-*|' + - 'WHERE custom_timestamp_field >= "2024-11-20T19:00:00.000Z"|' + - 'WHERE custom_timestamp_field <= "2024-11-20T20:00:00.000Z"|' + - 'WHERE service.name IS NOT NULL|' + - 'STATS entity.last_seen_timestamp=MAX(custom_timestamp_field),metadata.host.name=VALUES(host.name) BY service.name|' + - 'SORT entity.last_seen_timestamp DESC|' + + 'FROM logs-*, metrics-* | ' + + 'WHERE service.name IS NOT NULL | ' + + 'WHERE custom_timestamp_field >= "2024-11-20T19:00:00.000Z" AND custom_timestamp_field <= "2024-11-20T20:00:00.000Z" | ' + + 'STATS host.name = VALUES(host.name), entity.last_seen_timestamp = MAX(custom_timestamp_field), service.id = MAX(service.id) BY service.name | ' + + 'EVAL entity.type = "service", entity.id = service.name, entity.display_name = COALESCE(service.id, entity.id) | ' + + 'SORT entity.id DESC | ' + 'LIMIT 5' ); }); diff --git a/x-pack/plugins/entity_manager/server/lib/queries/index.ts b/x-pack/plugins/entity_manager/server/lib/queries/index.ts index 9fc7ae00c9aa6..83c25d756c170 100644 --- a/x-pack/plugins/entity_manager/server/lib/queries/index.ts +++ b/x-pack/plugins/entity_manager/server/lib/queries/index.ts @@ -9,29 +9,35 @@ import { z } from '@kbn/zod'; export const entitySourceSchema = z.object({ type: z.string(), - timestamp_field: z.optional(z.string()).default('@timestamp'), + timestamp_field: z.optional(z.string()), index_patterns: z.array(z.string()), identity_fields: z.array(z.string()), metadata_fields: z.array(z.string()), filters: z.array(z.string()), + display_name: z.optional(z.string()), }); +export interface SortBy { + field: string; + direction: 'ASC' | 'DESC'; +} + export type EntitySource = z.infer; const sourceCommand = ({ source }: { source: EntitySource }) => { - let query = `FROM ${source.index_patterns}`; + let query = `FROM ${source.index_patterns.join(', ')}`; const esMetadataFields = source.metadata_fields.filter((field) => ['_index', '_id'].includes(field) ); if (esMetadataFields.length) { - query += ` METADATA ${esMetadataFields.join(',')}`; + query += ` METADATA ${esMetadataFields.join(', ')}`; } return query; }; -const filterCommands = ({ +const whereCommand = ({ source, start, end, @@ -40,32 +46,65 @@ const filterCommands = ({ start: string; end: string; }) => { - const commands = [ - `WHERE ${source.timestamp_field} >= "${start}"`, - `WHERE ${source.timestamp_field} <= "${end}"`, + const filters = [ + source.identity_fields.map((field) => `${field} IS NOT NULL`).join(' AND '), + ...source.filters, ]; - source.identity_fields.forEach((field) => { - commands.push(`WHERE ${field} IS NOT NULL`); - }); - - source.filters.forEach((filter) => { - commands.push(`WHERE ${filter}`); - }); + if (source.timestamp_field) { + filters.push( + `${source.timestamp_field} >= "${start}" AND ${source.timestamp_field} <= "${end}"` + ); + } - return commands; + return filters.map((filter) => `WHERE ${filter}`).join(' | '); }; const statsCommand = ({ source }: { source: EntitySource }) => { - const aggs = [ - // default 'last_seen' attribute - `entity.last_seen_timestamp=MAX(${source.timestamp_field})`, - ...source.metadata_fields - .filter((field) => !source.identity_fields.some((idField) => idField === field)) - .map((field) => `metadata.${field}=VALUES(${field})`), - ]; + const aggs = source.metadata_fields + .filter((field) => !source.identity_fields.some((idField) => idField === field)) + .map((field) => `${field} = VALUES(${field})`); + + if (source.timestamp_field) { + aggs.push(`entity.last_seen_timestamp = MAX(${source.timestamp_field})`); + } + + if (source.display_name) { + // ideally we want the latest value but there's no command yet + // so we use MAX for now + aggs.push(`${source.display_name} = MAX(${source.display_name})`); + } + + return `STATS ${aggs.join(', ')} BY ${source.identity_fields.join(', ')}`; +}; + +const evalCommand = ({ source }: { source: EntitySource }) => { + const id = + source.identity_fields.length === 1 + ? source.identity_fields[0] + : `CONCAT(${source.identity_fields.join(', ":", ')})`; + + const displayName = source.display_name + ? `COALESCE(${source.display_name}, entity.id)` + : 'entity.id'; + + return `EVAL ${[ + `entity.type = "${source.type}"`, + `entity.id = ${id}`, + `entity.display_name = ${displayName}`, + ].join(', ')}`; +}; + +const sortCommand = ({ source, sort }: { source: EntitySource; sort?: SortBy }) => { + if (sort) { + return `SORT ${sort.field} ${sort.direction}`; + } + + if (source.timestamp_field) { + return `SORT entity.last_seen_timestamp DESC`; + } - return `STATS ${aggs.join(',')} BY ${source.identity_fields.join(',')}`; + return `SORT entity.id ASC`; }; export function getEntityInstancesQuery({ @@ -73,19 +112,22 @@ export function getEntityInstancesQuery({ limit, start, end, + sort, }: { source: EntitySource; limit: number; start: string; end: string; + sort?: SortBy; }): string { const commands = [ sourceCommand({ source }), - ...filterCommands({ source, start, end }), + whereCommand({ source, start, end }), statsCommand({ source }), - `SORT entity.last_seen_timestamp DESC`, + evalCommand({ source }), + sortCommand({ source, sort }), `LIMIT ${limit}`, ]; - return commands.join('|'); + return commands.join(' | '); } diff --git a/x-pack/plugins/entity_manager/server/lib/queries/utils.test.ts b/x-pack/plugins/entity_manager/server/lib/queries/utils.test.ts index 5d57025671726..df5c8a2a4a826 100644 --- a/x-pack/plugins/entity_manager/server/lib/queries/utils.test.ts +++ b/x-pack/plugins/entity_manager/server/lib/queries/utils.test.ts @@ -5,6 +5,7 @@ * 2.0. */ +import { EntitySource } from '.'; import { mergeEntitiesList } from './utils'; describe('mergeEntitiesList', () => { @@ -15,20 +16,23 @@ describe('mergeEntitiesList', () => { 'entity.id': 'foo', 'entity.last_seen_timestamp': '2024-11-20T18:00:00.000Z', 'entity.type': 'service', + 'entity.display_name': 'foo', }, { 'entity.id': 'foo', 'entity.last_seen_timestamp': '2024-11-20T18:00:00.000Z', 'entity.type': 'service', + 'entity.display_name': 'foo', }, ]; - const mergedEntities = mergeEntitiesList(entities); + const mergedEntities = mergeEntitiesList([], entities); expect(mergedEntities.length).toEqual(1); expect(mergedEntities[0]).toEqual({ 'entity.id': 'foo', 'entity.last_seen_timestamp': '2024-11-20T18:00:00.000Z', 'entity.type': 'service', + 'entity.display_name': 'foo', }); }); @@ -38,33 +42,46 @@ describe('mergeEntitiesList', () => { 'entity.id': 'foo', 'entity.last_seen_timestamp': '2024-11-20T18:00:00.000Z', 'entity.type': 'service', - 'metadata.host.name': 'host-1', - 'metadata.agent.name': 'agent-1', - 'metadata.service.environment': ['dev', 'staging'], - 'metadata.only_in_record_1': 'foo', + 'entity.display_name': 'foo', + 'host.name': 'host-1', + 'agent.name': 'agent-1', + 'service.environment': ['dev', 'staging'], + only_in_record_1: 'foo', }, { 'entity.id': 'foo', 'entity.last_seen_timestamp': '2024-11-20T18:00:00.000Z', 'entity.type': 'service', - 'metadata.host.name': ['host-2', 'host-3'], - 'metadata.agent.name': 'agent-2', - 'metadata.service.environment': 'prod', - 'metadata.only_in_record_2': 'bar', + 'entity.display_name': 'foo', + 'host.name': ['host-2', 'host-3'], + 'agent.name': 'agent-2', + 'service.environment': 'prod', + only_in_record_2: 'bar', }, ]; - const mergedEntities = mergeEntitiesList(entities); + const mergedEntities = mergeEntitiesList( + [ + { + metadata_fields: ['host.name', 'agent.name', 'service.environment', 'only_in_record_1'], + }, + { + metadata_fields: ['host.name', 'agent.name', 'service.environment', 'only_in_record_2'], + }, + ] as EntitySource[], + entities + ); expect(mergedEntities.length).toEqual(1); expect(mergedEntities[0]).toEqual({ 'entity.id': 'foo', 'entity.last_seen_timestamp': '2024-11-20T18:00:00.000Z', 'entity.type': 'service', - 'metadata.host.name': ['host-1', 'host-2', 'host-3'], - 'metadata.agent.name': ['agent-1', 'agent-2'], - 'metadata.service.environment': ['dev', 'staging', 'prod'], - 'metadata.only_in_record_1': 'foo', - 'metadata.only_in_record_2': 'bar', + 'entity.display_name': 'foo', + 'host.name': ['host-1', 'host-2', 'host-3'], + 'agent.name': ['agent-1', 'agent-2'], + 'service.environment': ['dev', 'staging', 'prod'], + only_in_record_1: 'foo', + only_in_record_2: 'bar', }); }); @@ -74,29 +91,78 @@ describe('mergeEntitiesList', () => { 'entity.id': 'foo', 'entity.last_seen_timestamp': '2024-11-20T18:00:00.000Z', 'entity.type': 'service', - 'metadata.host.name': 'host-1', + 'entity.display_name': 'foo', + 'host.name': 'host-1', }, { 'entity.id': 'foo', 'entity.last_seen_timestamp': '2024-11-20T20:00:00.000Z', 'entity.type': 'service', - 'metadata.host.name': 'host-2', + 'entity.display_name': 'foo', + 'host.name': 'host-2', }, { 'entity.id': 'foo', 'entity.last_seen_timestamp': '2024-11-20T16:00:00.000Z', 'entity.type': 'service', - 'metadata.host.name': 'host-3', + 'entity.display_name': 'foo', + 'host.name': 'host-3', + }, + { + 'entity.id': 'foo', + 'entity.type': 'service', + 'entity.display_name': 'foo', + 'host.name': 'host-3', }, ]; - const mergedEntities = mergeEntitiesList(entities); + const mergedEntities = mergeEntitiesList( + [ + { + metadata_fields: ['host.name'], + }, + { + metadata_fields: ['host.name'], + }, + ] as EntitySource[], + entities + ); expect(mergedEntities.length).toEqual(1); expect(mergedEntities[0]).toEqual({ 'entity.id': 'foo', 'entity.last_seen_timestamp': '2024-11-20T20:00:00.000Z', 'entity.type': 'service', - 'metadata.host.name': ['host-1', 'host-2', 'host-3'], + 'entity.display_name': 'foo', + 'host.name': ['host-1', 'host-2', 'host-3'], + }); + }); + + it('works without entity.last_seen_timestamp', () => { + const entities = [ + { + 'entity.id': 'foo', + 'entity.type': 'service', + 'entity.display_name': 'foo', + 'host.name': 'host-1', + }, + { + 'entity.id': 'foo', + 'entity.type': 'service', + 'entity.display_name': 'foo', + 'host.name': 'host-2', + }, + ]; + + const mergedEntities = mergeEntitiesList( + [{ metadata_fields: ['host.name'] }, { metadata_fields: ['host.name'] }] as EntitySource[], + entities + ); + expect(mergedEntities.length).toEqual(1); + expect(mergedEntities[0]).toEqual({ + 'entity.id': 'foo', + 'entity.type': 'service', + 'entity.display_name': 'foo', + 'host.name': ['host-1', 'host-2'], }); }); @@ -106,29 +172,43 @@ describe('mergeEntitiesList', () => { 'entity.id': 'foo', 'entity.last_seen_timestamp': '2024-11-20T18:00:00.000Z', 'entity.type': 'service', - 'metadata.host.name': 'host-1', + 'entity.display_name': 'foo', + 'host.name': 'host-1', }, { 'entity.id': 'foo', 'entity.last_seen_timestamp': '2024-11-20T20:00:00.000Z', 'entity.type': 'service', - 'metadata.host.name': 'host-2', + 'entity.display_name': 'foo', + 'host.name': 'host-2', }, { 'entity.id': 'foo', 'entity.last_seen_timestamp': '2024-11-20T16:00:00.000Z', 'entity.type': 'service', - 'metadata.host.name': ['host-1', 'host-2'], + 'entity.display_name': 'foo', + 'host.name': ['host-1', 'host-2'], }, ]; - const mergedEntities = mergeEntitiesList(entities); + const mergedEntities = mergeEntitiesList( + [ + { + metadata_fields: ['host.name'], + }, + { + metadata_fields: ['host.name'], + }, + ] as EntitySource[], + entities + ); expect(mergedEntities.length).toEqual(1); expect(mergedEntities[0]).toEqual({ 'entity.id': 'foo', 'entity.last_seen_timestamp': '2024-11-20T20:00:00.000Z', 'entity.type': 'service', - 'metadata.host.name': ['host-1', 'host-2'], + 'entity.display_name': 'foo', + 'host.name': ['host-1', 'host-2'], }); }); }); diff --git a/x-pack/plugins/entity_manager/server/lib/queries/utils.ts b/x-pack/plugins/entity_manager/server/lib/queries/utils.ts index 68f5b0f11aff2..a18f6fb837140 100644 --- a/x-pack/plugins/entity_manager/server/lib/queries/utils.ts +++ b/x-pack/plugins/entity_manager/server/lib/queries/utils.ts @@ -5,24 +5,33 @@ * 2.0. */ +import { compact, uniq } from 'lodash'; import { ElasticsearchClient } from '@kbn/core-elasticsearch-server'; import { EntityV2 } from '@kbn/entities-schema'; import { ESQLSearchResponse } from '@kbn/es-types'; -import { uniq } from 'lodash'; - -function mergeEntities(entity1: EntityV2, entity2: EntityV2): EntityV2 { - const merged: EntityV2 = { - ...entity1, - 'entity.last_seen_timestamp': new Date( - Math.max( - Date.parse(entity1['entity.last_seen_timestamp']), - Date.parse(entity2['entity.last_seen_timestamp']) - ) - ).toISOString(), - }; +import { EntitySource } from '.'; + +function getLatestDate(date1?: string, date2?: string) { + if (!date1 && !date2) return; + + return new Date( + Math.max(date1 ? Date.parse(date1) : 0, date2 ? Date.parse(date2) : 0) + ).toISOString(); +} + +function mergeEntities(metadataFields: string[], entity1: EntityV2, entity2: EntityV2): EntityV2 { + const merged: EntityV2 = { ...entity1 }; + + const latestTimestamp = getLatestDate( + entity1['entity.last_seen_timestamp'], + entity2['entity.last_seen_timestamp'] + ); + if (latestTimestamp) { + merged['entity.last_seen_timestamp'] = latestTimestamp; + } for (const [key, value] of Object.entries(entity2).filter(([_key]) => - _key.startsWith('metadata.') + metadataFields.includes(_key) )) { if (merged[key]) { merged[key] = uniq([ @@ -36,7 +45,10 @@ function mergeEntities(entity1: EntityV2, entity2: EntityV2): EntityV2 { return merged; } -export function mergeEntitiesList(entities: EntityV2[]): EntityV2[] { +export function mergeEntitiesList(sources: EntitySource[], entities: EntityV2[]): EntityV2[] { + const metadataFields = uniq( + sources.flatMap((source) => compact([source.timestamp_field, ...source.metadata_fields])) + ); const instances: { [key: string]: EntityV2 } = {}; for (let i = 0; i < entities.length; i++) { @@ -44,7 +56,7 @@ export function mergeEntitiesList(entities: EntityV2[]): EntityV2[] { const id = entity['entity.id']; if (instances[id]) { - instances[id] = mergeEntities(instances[id], entity); + instances[id] = mergeEntities(metadataFields, instances[id], entity); } else { instances[id] = entity; } diff --git a/x-pack/plugins/entity_manager/server/routes/v2/search.ts b/x-pack/plugins/entity_manager/server/routes/v2/search.ts index 0b975da748a86..451ff7cfff43f 100644 --- a/x-pack/plugins/entity_manager/server/routes/v2/search.ts +++ b/x-pack/plugins/entity_manager/server/routes/v2/search.ts @@ -22,20 +22,34 @@ export const searchEntitiesRoute = createEntityManagerServerRoute({ .optional(z.string()) .default(() => moment().subtract(5, 'minutes').toISOString()) .refine((val) => moment(val).isValid(), { - message: 'start should be a date in ISO format', + message: '[start] should be a date in ISO format', }), end: z .optional(z.string()) .default(() => moment().toISOString()) .refine((val) => moment(val).isValid(), { - message: 'start should be a date in ISO format', + message: '[end] should be a date in ISO format', }), + sort: z.optional( + z.object({ + field: z.string(), + direction: z.enum(['ASC', 'DESC']), + }) + ), limit: z.optional(z.number()).default(10), }), }), handler: async ({ request, response, params, logger, getScopedClient }) => { try { - const { type, start, end, limit, filters, metadata_fields: metadataFields } = params.body; + const { + type, + start, + end, + limit, + filters, + sort, + metadata_fields: metadataFields, + } = params.body; const client = await getScopedClient({ request }); const entities = await client.searchEntities({ @@ -44,6 +58,7 @@ export const searchEntitiesRoute = createEntityManagerServerRoute({ metadataFields, start, end, + sort, limit, }); @@ -69,25 +84,32 @@ export const searchEntitiesPreviewRoute = createEntityManagerServerRoute({ .optional(z.string()) .default(() => moment().subtract(5, 'minutes').toISOString()) .refine((val) => moment(val).isValid(), { - message: 'start should be a date in ISO format', + message: '[start] should be a date in ISO format', }), end: z .optional(z.string()) .default(() => moment().toISOString()) .refine((val) => moment(val).isValid(), { - message: 'start should be a date in ISO format', + message: '[end] should be a date in ISO format', }), + sort: z.optional( + z.object({ + field: z.string(), + direction: z.enum(['ASC', 'DESC']), + }) + ), limit: z.optional(z.number()).default(10), }), }), - handler: async ({ request, response, params, logger, getScopedClient }) => { - const { sources, start, end, limit } = params.body; + handler: async ({ request, response, params, getScopedClient }) => { + const { sources, start, end, limit, sort } = params.body; const client = await getScopedClient({ request }); const entities = await client.searchEntitiesBySources({ sources, start, end, + sort, limit, }); diff --git a/x-pack/plugins/features/common/alerting_kibana_privilege.ts b/x-pack/plugins/features/common/alerting_kibana_privilege.ts new file mode 100644 index 0000000000000..4a435b5c651c7 --- /dev/null +++ b/x-pack/plugins/features/common/alerting_kibana_privilege.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. + */ + +/** + * Interface for registering an alerting privilege. + * Alerting privilege registration allows plugins to + * specify for which rule types and consumers the feature + * has access to. + */ + +export type AlertingKibanaPrivilege = ReadonlyArray<{ + ruleTypeId: string; + consumers: readonly string[]; +}>; diff --git a/x-pack/plugins/features/common/feature_kibana_privileges.ts b/x-pack/plugins/features/common/feature_kibana_privileges.ts index 1939d0b5e4e49..a7d39669ef00a 100644 --- a/x-pack/plugins/features/common/feature_kibana_privileges.ts +++ b/x-pack/plugins/features/common/feature_kibana_privileges.ts @@ -5,6 +5,7 @@ * 2.0. */ +import { AlertingKibanaPrivilege } from './alerting_kibana_privilege'; import { FeatureKibanaPrivilegesReference } from './feature_kibana_privileges_reference'; /** @@ -97,47 +98,47 @@ export interface FeatureKibanaPrivileges { alerting?: { rule?: { /** - * List of rule types which users should have full read/write access to when granted this privilege. + * List of rule types and consumers for which users should have full read/write access to when granted this privilege. * @example * ```ts * { - * all: ['my-alert-type-within-my-feature'] + * all: [{ ruleTypeId: 'my-alert-type-within-my-feature', consumers: ['my-consumer-within-my-feature'] }] * } * ``` */ - all?: readonly string[]; + all?: AlertingKibanaPrivilege; /** - * List of rule types which users should have read-only access to when granted this privilege. + * List of rule types and consumers for which users should have read-only access to when granted this privilege. * @example * ```ts * { - * read: ['my-alert-type'] + * read: [{ ruleTypeId: 'my-alert-type-within-my-feature', consumers: ['my-consumer-within-my-feature'] }] * } * ``` */ - read?: readonly string[]; + read?: AlertingKibanaPrivilege; }; alert?: { /** - * List of rule types for which users should have full read/write access their alert data to when granted this privilege. + * List of rule types and consumers for which users should have full read/write access their alert data to when granted this privilege. * @example * ```ts * { - * all: ['my-alert-type-within-my-feature'] + * all: [{ ruleTypeId: 'my-alert-type-within-my-feature', consumers: ['my-consumer-within-my-feature'] }] * } * ``` */ - all?: readonly string[]; + all?: AlertingKibanaPrivilege; /** - * List of rule types for which users should have read-only access to their alert data when granted this privilege. + * List of rule types and consumers for which users should have read-only access to their alert data when granted this privilege. * @example * ```ts * { - * read: ['my-alert-type'] + * read: [{ ruleTypeId: 'my-alert-type-within-my-feature', consumers: ['my-consumer-within-my-feature'] }] * } * ``` */ - read?: readonly string[]; + read?: AlertingKibanaPrivilege; }; }; diff --git a/x-pack/plugins/features/common/kibana_feature.ts b/x-pack/plugins/features/common/kibana_feature.ts index 3a5d9fc2a0e50..dba79a1663fca 100644 --- a/x-pack/plugins/features/common/kibana_feature.ts +++ b/x-pack/plugins/features/common/kibana_feature.ts @@ -11,6 +11,7 @@ import { LicenseType } from '@kbn/licensing-plugin/common/types'; import { FeatureKibanaPrivileges } from './feature_kibana_privileges'; import { SubFeatureConfig, SubFeature as KibanaSubFeature } from './sub_feature'; import { ReservedKibanaPrivilege } from './reserved_kibana_privilege'; +import { AlertingKibanaPrivilege } from './alerting_kibana_privilege'; /** * Enum for allowed feature scope values. @@ -107,11 +108,12 @@ export interface KibanaFeatureConfig { catalogue?: readonly string[]; /** - * If your feature grants access to specific Alert Types, you can specify them here to control visibility based on the current space. - * Include both Alert Types registered by the feature and external Alert Types such as built-in - * Alert Types and Alert Types provided by other features to which you wish to grant access. + * If your feature grants access to specific rule types, you can specify them here to control visibility based on the current space. + * Include both rule types registered by the feature and external rule types such as built-in + * rule types and rule types provided by other features to which you wish to grant access. For each rule type + * you can specify the consumers the feature has access to. */ - alerting?: readonly string[]; + alerting?: AlertingKibanaPrivilege; /** * If your feature grants access to specific case types, you can specify them here to control visibility based on the current space. diff --git a/x-pack/plugins/features/server/__snapshots__/oss_features.test.ts.snap b/x-pack/plugins/features/server/__snapshots__/oss_features.test.ts.snap index b8df9e9c2117b..b5614562f18a4 100644 --- a/x-pack/plugins/features/server/__snapshots__/oss_features.test.ts.snap +++ b/x-pack/plugins/features/server/__snapshots__/oss_features.test.ts.snap @@ -881,6 +881,9 @@ exports[`buildOSSFeatures with a basic license returns the indexPatterns feature Array [ Object { "privilege": Object { + "api": Array [ + "indexPatterns:manage", + ], "app": Array [ "kibana", ], @@ -1520,6 +1523,9 @@ exports[`buildOSSFeatures with a enterprise license returns the indexPatterns fe Array [ Object { "privilege": Object { + "api": Array [ + "indexPatterns:manage", + ], "app": Array [ "kibana", ], diff --git a/x-pack/plugins/features/server/feature_privilege_iterator/feature_privilege_iterator.test.ts b/x-pack/plugins/features/server/feature_privilege_iterator/feature_privilege_iterator.test.ts index c7d501bb17cf8..c4e542a7ebcde 100644 --- a/x-pack/plugins/features/server/feature_privilege_iterator/feature_privilege_iterator.test.ts +++ b/x-pack/plugins/features/server/feature_privilege_iterator/feature_privilege_iterator.test.ts @@ -62,11 +62,11 @@ describe('featurePrivilegeIterator', () => { }, alerting: { rule: { - all: ['alerting-all-type'], - read: ['alerting-read-type'], + all: [{ ruleTypeId: 'alerting-all-type', consumers: ['foo'] }], + read: [{ ruleTypeId: 'alerting-read-type', consumers: ['foo'] }], }, alert: { - all: ['alerting-all-type'], + all: [{ ruleTypeId: 'alerting-all-type', consumers: ['foo'] }], read: [], }, }, @@ -96,10 +96,10 @@ describe('featurePrivilegeIterator', () => { }, alerting: { rule: { - read: ['alerting-read-type'], + read: [{ ruleTypeId: 'alerting-read-type', consumers: ['foo'] }], }, alert: { - read: ['alerting-read-type'], + read: [{ ruleTypeId: 'alerting-read-type', consumers: ['foo'] }], }, }, cases: { @@ -134,11 +134,11 @@ describe('featurePrivilegeIterator', () => { }, alerting: { rule: { - all: ['alerting-all-type'], - read: ['alerting-read-type'], + all: [{ ruleTypeId: 'alerting-all-type', consumers: ['foo'] }], + read: [{ ruleTypeId: 'alerting-read-type', consumers: ['foo'] }], }, alert: { - all: ['alerting-all-type'], + all: [{ ruleTypeId: 'alerting-all-type', consumers: ['foo'] }], read: [], }, }, @@ -171,10 +171,10 @@ describe('featurePrivilegeIterator', () => { }, alerting: { rule: { - read: ['alerting-read-type'], + read: [{ ruleTypeId: 'alerting-read-type', consumers: ['foo'] }], }, alert: { - read: ['alerting-read-type'], + read: [{ ruleTypeId: 'alerting-read-type', consumers: ['foo'] }], }, }, cases: { @@ -205,12 +205,12 @@ describe('featurePrivilegeIterator', () => { }, alerting: { rule: { - all: ['alerting-all-type'], - read: ['alerting-read-type'], + all: [{ ruleTypeId: 'alerting-all-type', consumers: ['foo'] }], + read: [{ ruleTypeId: 'alerting-read-type', consumers: ['foo'] }], }, alert: { - all: ['alerting-all-type'], - read: ['alerting-read-type-alerts'], + all: [{ ruleTypeId: 'alerting-all-type', consumers: ['foo'] }], + read: [{ ruleTypeId: 'alerting-read-type-alerts', consumers: ['foo'] }], }, }, cases: { @@ -239,10 +239,10 @@ describe('featurePrivilegeIterator', () => { }, alerting: { rule: { - read: ['alerting-read-type'], + read: [{ ruleTypeId: 'alerting-read-type', consumers: ['foo'] }], }, alert: { - read: ['alerting-read-type'], + read: [{ ruleTypeId: 'alerting-read-type', consumers: ['foo'] }], }, }, cases: { @@ -278,12 +278,12 @@ describe('featurePrivilegeIterator', () => { }, alerting: { rule: { - all: ['alerting-all-type'], - read: ['alerting-read-type'], + all: [{ ruleTypeId: 'alerting-all-type', consumers: ['foo'] }], + read: [{ ruleTypeId: 'alerting-read-type', consumers: ['foo'] }], }, alert: { - all: ['alerting-all-type'], - read: ['alerting-read-type-alerts'], + all: [{ ruleTypeId: 'alerting-all-type', consumers: ['foo'] }], + read: [{ ruleTypeId: 'alerting-read-type-alerts', consumers: ['foo'] }], }, }, cases: { @@ -323,10 +323,10 @@ describe('featurePrivilegeIterator', () => { }, alerting: { rule: { - all: ['alerting-all-type'], + all: [{ ruleTypeId: 'alerting-all-type', consumers: ['foo'] }], }, alert: { - read: ['alerting-another-read-type'], + read: [{ ruleTypeId: 'alerting-another-read-type', consumers: ['foo'] }], }, }, cases: { @@ -355,10 +355,10 @@ describe('featurePrivilegeIterator', () => { }, alerting: { rule: { - read: ['alerting-read-type'], + read: [{ ruleTypeId: 'alerting-read-type', consumers: ['foo'] }], }, alert: { - read: ['alerting-read-type'], + read: [{ ruleTypeId: 'alerting-read-type', consumers: ['foo'] }], }, }, cases: { @@ -390,7 +390,7 @@ describe('featurePrivilegeIterator', () => { }, alerting: { alert: { - all: ['alerting-all-sub-type'], + all: [{ ruleTypeId: 'alerting-all-sub-type', consumers: ['foo'] }], }, }, cases: { @@ -436,10 +436,10 @@ describe('featurePrivilegeIterator', () => { }, alerting: { rule: { - all: ['alerting-all-type'], + all: [{ ruleTypeId: 'alerting-all-type', consumers: ['foo'] }], }, alert: { - read: ['alerting-another-read-type'], + read: [{ ruleTypeId: 'alerting-another-read-type', consumers: ['foo'] }], }, }, cases: { @@ -471,10 +471,10 @@ describe('featurePrivilegeIterator', () => { }, alerting: { rule: { - read: ['alerting-read-type'], + read: [{ ruleTypeId: 'alerting-read-type', consumers: ['foo'] }], }, alert: { - read: ['alerting-read-type'], + read: [{ ruleTypeId: 'alerting-read-type', consumers: ['foo'] }], }, }, cases: { @@ -506,10 +506,10 @@ describe('featurePrivilegeIterator', () => { }, alerting: { rule: { - all: ['alerting-all-type'], + all: [{ ruleTypeId: 'alerting-all-type', consumers: ['foo'] }], }, alert: { - read: ['alerting-another-read-type'], + read: [{ ruleTypeId: 'alerting-another-read-type', consumers: ['foo'] }], }, }, cases: { @@ -538,10 +538,10 @@ describe('featurePrivilegeIterator', () => { }, alerting: { rule: { - read: ['alerting-read-type'], + read: [{ ruleTypeId: 'alerting-read-type', consumers: ['foo'] }], }, alert: { - read: ['alerting-read-type'], + read: [{ ruleTypeId: 'alerting-read-type', consumers: ['foo'] }], }, }, cases: { @@ -573,7 +573,7 @@ describe('featurePrivilegeIterator', () => { }, alerting: { alert: { - all: ['alerting-all-sub-type'], + all: [{ ruleTypeId: 'alerting-all-sub-type', consumers: ['foo'] }], }, }, cases: { @@ -619,10 +619,10 @@ describe('featurePrivilegeIterator', () => { }, alerting: { rule: { - all: ['alerting-all-type'], + all: [{ ruleTypeId: 'alerting-all-type', consumers: ['foo'] }], }, alert: { - read: ['alerting-another-read-type'], + read: [{ ruleTypeId: 'alerting-another-read-type', consumers: ['foo'] }], }, }, cases: { @@ -654,10 +654,10 @@ describe('featurePrivilegeIterator', () => { }, alerting: { rule: { - read: ['alerting-read-type'], + read: [{ ruleTypeId: 'alerting-read-type', consumers: ['foo'] }], }, alert: { - read: ['alerting-read-type'], + read: [{ ruleTypeId: 'alerting-read-type', consumers: ['foo'] }], }, }, cases: { @@ -689,10 +689,10 @@ describe('featurePrivilegeIterator', () => { }, alerting: { rule: { - all: ['alerting-all-type'], + all: [{ ruleTypeId: 'alerting-all-type', consumers: ['foo'] }], }, alert: { - read: ['alerting-another-read-type'], + read: [{ ruleTypeId: 'alerting-another-read-type', consumers: ['foo'] }], }, }, cases: { @@ -721,10 +721,10 @@ describe('featurePrivilegeIterator', () => { }, alerting: { rule: { - read: ['alerting-read-type'], + read: [{ ruleTypeId: 'alerting-read-type', consumers: ['foo'] }], }, alert: { - read: ['alerting-read-type'], + read: [{ ruleTypeId: 'alerting-read-type', consumers: ['foo'] }], }, }, cases: { @@ -757,7 +757,7 @@ describe('featurePrivilegeIterator', () => { }, alerting: { alert: { - all: ['alerting-all-sub-type'], + all: [{ ruleTypeId: 'alerting-all-sub-type', consumers: ['foo'] }], }, }, cases: { @@ -804,12 +804,12 @@ describe('featurePrivilegeIterator', () => { }, alerting: { rule: { - all: ['alerting-all-type'], + all: [{ ruleTypeId: 'alerting-all-type', consumers: ['foo'] }], read: [], }, alert: { - all: ['alerting-all-sub-type'], - read: ['alerting-another-read-type'], + all: [{ ruleTypeId: 'alerting-all-sub-type', consumers: ['foo'] }], + read: [{ ruleTypeId: 'alerting-another-read-type', consumers: ['foo'] }], }, }, cases: { @@ -843,11 +843,11 @@ describe('featurePrivilegeIterator', () => { alerting: { rule: { all: [], - read: ['alerting-read-type'], + read: [{ ruleTypeId: 'alerting-read-type', consumers: ['foo'] }], }, alert: { - all: ['alerting-all-sub-type'], - read: ['alerting-read-type'], + all: [{ ruleTypeId: 'alerting-all-sub-type', consumers: ['foo'] }], + read: [{ ruleTypeId: 'alerting-read-type', consumers: ['foo'] }], }, }, cases: { @@ -887,12 +887,12 @@ describe('featurePrivilegeIterator', () => { }, alerting: { rule: { - all: ['alerting-all-type'], - read: ['alerting-read-type'], + all: [{ ruleTypeId: 'alerting-all-type', consumers: ['foo'] }], + read: [{ ruleTypeId: 'alerting-read-type', consumers: ['foo'] }], }, alert: { all: [], - read: ['alerting-read-type'], + read: [{ ruleTypeId: 'alerting-read-type', consumers: ['foo'] }], }, }, cases: { @@ -921,10 +921,10 @@ describe('featurePrivilegeIterator', () => { }, alerting: { rule: { - read: ['alerting-read-type'], + read: [{ ruleTypeId: 'alerting-read-type', consumers: ['foo'] }], }, alert: { - read: ['alerting-read-type'], + read: [{ ruleTypeId: 'alerting-read-type', consumers: ['foo'] }], }, }, cases: { @@ -956,7 +956,7 @@ describe('featurePrivilegeIterator', () => { }, alerting: { alert: { - all: ['alerting-read-type'], + all: [{ ruleTypeId: 'alerting-read-type', consumers: ['foo'] }], }, }, cases: { @@ -994,12 +994,12 @@ describe('featurePrivilegeIterator', () => { }, alerting: { rule: { - all: ['alerting-all-type'], - read: ['alerting-read-type'], + all: [{ ruleTypeId: 'alerting-all-type', consumers: ['foo'] }], + read: [{ ruleTypeId: 'alerting-read-type', consumers: ['foo'] }], }, alert: { - all: ['alerting-read-type'], - read: ['alerting-read-type'], + all: [{ ruleTypeId: 'alerting-read-type', consumers: ['foo'] }], + read: [{ ruleTypeId: 'alerting-read-type', consumers: ['foo'] }], }, }, cases: { @@ -1032,11 +1032,11 @@ describe('featurePrivilegeIterator', () => { alerting: { rule: { all: [], - read: ['alerting-read-type'], + read: [{ ruleTypeId: 'alerting-read-type', consumers: ['foo'] }], }, alert: { - all: ['alerting-read-type'], - read: ['alerting-read-type'], + all: [{ ruleTypeId: 'alerting-read-type', consumers: ['foo'] }], + read: [{ ruleTypeId: 'alerting-read-type', consumers: ['foo'] }], }, }, cases: { @@ -1076,10 +1076,10 @@ describe('featurePrivilegeIterator', () => { }, alerting: { rule: { - all: ['alerting-all-type'], + all: [{ ruleTypeId: 'alerting-all-type', consumers: ['foo'] }], }, alert: { - read: ['alerting-another-read-type'], + read: [{ ruleTypeId: 'alerting-another-read-type', consumers: ['foo'] }], }, }, cases: { @@ -1108,10 +1108,10 @@ describe('featurePrivilegeIterator', () => { }, alerting: { rule: { - read: ['alerting-read-type'], + read: [{ ruleTypeId: 'alerting-read-type', consumers: ['foo'] }], }, alert: { - read: ['alerting-read-type'], + read: [{ ruleTypeId: 'alerting-read-type', consumers: ['foo'] }], }, }, cases: { @@ -1144,7 +1144,7 @@ describe('featurePrivilegeIterator', () => { }, alerting: { alert: { - all: ['alerting-all-sub-type'], + all: [{ ruleTypeId: 'alerting-all-sub-type', consumers: ['foo'] }], }, }, cases: { @@ -1191,12 +1191,12 @@ describe('featurePrivilegeIterator', () => { }, alerting: { rule: { - all: ['alerting-all-type'], + all: [{ ruleTypeId: 'alerting-all-type', consumers: ['foo'] }], read: [], }, alert: { - all: ['alerting-all-sub-type'], - read: ['alerting-another-read-type'], + all: [{ ruleTypeId: 'alerting-all-sub-type', consumers: ['foo'] }], + read: [{ ruleTypeId: 'alerting-another-read-type', consumers: ['foo'] }], }, }, cases: { @@ -1228,10 +1228,10 @@ describe('featurePrivilegeIterator', () => { }, alerting: { rule: { - read: ['alerting-read-type'], + read: [{ ruleTypeId: 'alerting-read-type', consumers: ['foo'] }], }, alert: { - read: ['alerting-read-type'], + read: [{ ruleTypeId: 'alerting-read-type', consumers: ['foo'] }], }, }, cases: { @@ -1390,8 +1390,8 @@ describe('featurePrivilegeIterator', () => { }, alerting: { rule: { - all: ['alerting-all-sub-type'], - read: ['alerting-read-sub-type'], + all: [{ ruleTypeId: 'alerting-all-sub-type', consumers: ['foo'] }], + read: [{ ruleTypeId: 'alerting-read-sub-type', consumers: ['foo'] }], }, }, cases: { @@ -1438,8 +1438,8 @@ describe('featurePrivilegeIterator', () => { }, alerting: { rule: { - all: ['alerting-all-sub-type'], - read: ['alerting-read-sub-type'], + all: [{ ruleTypeId: 'alerting-all-sub-type', consumers: ['foo'] }], + read: [{ ruleTypeId: 'alerting-read-sub-type', consumers: ['foo'] }], }, alert: { all: [], @@ -1476,8 +1476,8 @@ describe('featurePrivilegeIterator', () => { }, alerting: { rule: { - all: ['alerting-all-sub-type'], - read: ['alerting-read-sub-type'], + all: [{ ruleTypeId: 'alerting-all-sub-type', consumers: ['foo'] }], + read: [{ ruleTypeId: 'alerting-read-sub-type', consumers: ['foo'] }], }, alert: { all: [], @@ -1521,10 +1521,10 @@ describe('featurePrivilegeIterator', () => { }, alerting: { rule: { - all: ['alerting-all-type'], + all: [{ ruleTypeId: 'alerting-all-type', consumers: ['foo'] }], }, alert: { - read: ['alerting-another-read-type'], + read: [{ ruleTypeId: 'alerting-another-read-type', consumers: ['foo'] }], }, }, cases: { @@ -1553,10 +1553,10 @@ describe('featurePrivilegeIterator', () => { }, alerting: { rule: { - read: ['alerting-read-type'], + read: [{ ruleTypeId: 'alerting-read-type', consumers: ['foo'] }], }, alert: { - read: ['alerting-read-type'], + read: [{ ruleTypeId: 'alerting-read-type', consumers: ['foo'] }], }, }, cases: { @@ -1612,12 +1612,12 @@ describe('featurePrivilegeIterator', () => { }, alerting: { rule: { - all: ['alerting-all-type'], + all: [{ ruleTypeId: 'alerting-all-type', consumers: ['foo'] }], read: [], }, alert: { all: [], - read: ['alerting-another-read-type'], + read: [{ ruleTypeId: 'alerting-another-read-type', consumers: ['foo'] }], }, }, cases: { @@ -1650,11 +1650,11 @@ describe('featurePrivilegeIterator', () => { alerting: { rule: { all: [], - read: ['alerting-read-type'], + read: [{ ruleTypeId: 'alerting-read-type', consumers: ['foo'] }], }, alert: { all: [], - read: ['alerting-read-type'], + read: [{ ruleTypeId: 'alerting-read-type', consumers: ['foo'] }], }, }, cases: { diff --git a/x-pack/plugins/features/server/feature_privilege_iterator/feature_privilege_iterator.ts b/x-pack/plugins/features/server/feature_privilege_iterator/feature_privilege_iterator.ts index a9d7336ea0a22..45518004430a4 100644 --- a/x-pack/plugins/features/server/feature_privilege_iterator/feature_privilege_iterator.ts +++ b/x-pack/plugins/features/server/feature_privilege_iterator/feature_privilege_iterator.ts @@ -8,6 +8,7 @@ import _ from 'lodash'; import type { LicenseType } from '@kbn/licensing-plugin/server'; +import { AlertingKibanaPrivilege } from '../../common/alerting_kibana_privilege'; import type { FeatureKibanaPrivileges, KibanaFeature } from '..'; import { subFeaturePrivilegeIterator } from './sub_feature_privilege_iterator'; @@ -108,26 +109,46 @@ function mergeWithSubFeatures( subFeaturePrivilege.savedObject.read ); + /** + * Merges all alerting rule types and consumers + * from features and sub features. + * Removes duplicated values. + */ + const mergeAlertingEntries = (entries: AlertingKibanaPrivilege): AlertingKibanaPrivilege => { + const alertingMap = new Map>(); + + for (const entry of entries) { + const consumers = alertingMap.get(entry.ruleTypeId) ?? new Set(); + entry.consumers.forEach((consumer) => consumers.add(consumer)); + alertingMap.set(entry.ruleTypeId, consumers); + } + + return Array.from(alertingMap).map(([ruleTypeId, consumers]) => ({ + ruleTypeId, + consumers: Array.from(consumers), + })); + }; + mergedConfig.alerting = { rule: { - all: mergeArrays( - mergedConfig.alerting?.rule?.all ?? [], - subFeaturePrivilege.alerting?.rule?.all ?? [] - ), - read: mergeArrays( - mergedConfig.alerting?.rule?.read ?? [], - subFeaturePrivilege.alerting?.rule?.read ?? [] - ), + all: mergeAlertingEntries([ + ...(mergedConfig.alerting?.rule?.all ?? []), + ...(subFeaturePrivilege.alerting?.rule?.all ?? []), + ]), + read: mergeAlertingEntries([ + ...(mergedConfig.alerting?.rule?.read ?? []), + ...(subFeaturePrivilege.alerting?.rule?.read ?? []), + ]), }, alert: { - all: mergeArrays( - mergedConfig.alerting?.alert?.all ?? [], - subFeaturePrivilege.alerting?.alert?.all ?? [] - ), - read: mergeArrays( - mergedConfig.alerting?.alert?.read ?? [], - subFeaturePrivilege.alerting?.alert?.read ?? [] - ), + all: mergeAlertingEntries([ + ...(mergedConfig.alerting?.alert?.all ?? []), + ...(subFeaturePrivilege.alerting?.alert?.all ?? []), + ]), + read: mergeAlertingEntries([ + ...(mergedConfig.alerting?.alert?.read ?? []), + ...(subFeaturePrivilege.alerting?.alert?.read ?? []), + ]), }, }; diff --git a/x-pack/plugins/features/server/feature_registry.test.ts b/x-pack/plugins/features/server/feature_registry.test.ts index 08da08e0a19bd..9ed7a207560b0 100644 --- a/x-pack/plugins/features/server/feature_registry.test.ts +++ b/x-pack/plugins/features/server/feature_registry.test.ts @@ -868,404 +868,688 @@ describe('FeatureRegistry', () => { ); }); - it(`prevents privileges from specifying alerting/rule entries that don't exist at the root level`, () => { - const feature: KibanaFeatureConfig = { - id: 'test-feature', - name: 'Test Feature', - app: [], - category: { id: 'foo', label: 'foo' }, - alerting: ['bar'], - privileges: { - all: { - alerting: { - rule: { - all: ['foo', 'bar'], - read: ['baz'], + describe('alerting', () => { + it(`prevents privileges from specifying rule types that don't exist at the root level`, () => { + const feature: KibanaFeatureConfig = { + id: 'test-feature', + name: 'Test Feature', + app: [], + category: { id: 'foo', label: 'foo' }, + alerting: [{ ruleTypeId: 'bar', consumers: ['test-feature'] }], + privileges: { + all: { + alerting: { + rule: { + all: [ + { ruleTypeId: 'foo', consumers: ['test-feature'] }, + { ruleTypeId: 'bar', consumers: ['test-feature'] }, + ], + read: [{ ruleTypeId: 'baz', consumers: ['test-feature'] }], + }, }, - }, - savedObject: { - all: [], - read: [], - }, - ui: [], - app: [], - }, - read: { - alerting: { - rule: { - read: ['foo', 'bar', 'baz'], + savedObject: { + all: [], + read: [], }, + ui: [], + app: [], }, - savedObject: { - all: [], - read: [], + read: { + alerting: { + rule: { + read: [{ ruleTypeId: 'bar', consumers: ['test-feature'] }], + }, + }, + savedObject: { + all: [], + read: [], + }, + ui: [], + app: [], }, - ui: [], - app: [], }, - }, - }; + }; - const featureRegistry = new FeatureRegistry(); + const featureRegistry = new FeatureRegistry(); - expect(() => - featureRegistry.registerKibanaFeature(feature) - ).toThrowErrorMatchingInlineSnapshot( - `"Feature privilege test-feature.all has unknown alerting entries: foo, baz"` - ); - }); + expect(() => + featureRegistry.registerKibanaFeature(feature) + ).toThrowErrorMatchingInlineSnapshot( + `"Feature privilege test-feature.all has unknown ruleTypeId: foo"` + ); + }); - it(`prevents privileges from specifying alerting/alert entries that don't exist at the root level`, () => { - const feature: KibanaFeatureConfig = { - id: 'test-feature', - name: 'Test Feature', - app: [], - category: { id: 'foo', label: 'foo' }, - alerting: ['bar'], - privileges: { - all: { - alerting: { - alert: { - all: ['foo', 'bar'], - read: ['baz'], + it(`prevents privileges from specifying rule types entries that don't exist at the root level`, () => { + const feature: KibanaFeatureConfig = { + id: 'test-feature', + name: 'Test Feature', + app: [], + category: { id: 'foo', label: 'foo' }, + alerting: [{ ruleTypeId: 'bar', consumers: ['test-feature'] }], + privileges: { + all: { + alerting: { + alert: { + all: [ + { ruleTypeId: 'foo', consumers: ['test-feature'] }, + { ruleTypeId: 'bar', consumers: ['test-feature'] }, + ], + read: [{ ruleTypeId: 'baz', consumers: ['test-feature'] }], + }, }, - }, - savedObject: { - all: [], - read: [], - }, - ui: [], - app: [], - }, - read: { - alerting: { - alert: { - read: ['foo', 'bar', 'baz'], + savedObject: { + all: [], + read: [], }, + ui: [], + app: [], }, - savedObject: { - all: [], - read: [], + read: { + alerting: { + alert: { + read: [{ ruleTypeId: 'bar', consumers: ['test-feature'] }], + }, + }, + savedObject: { + all: [], + read: [], + }, + ui: [], + app: [], }, - ui: [], - app: [], }, - }, - }; + }; - const featureRegistry = new FeatureRegistry(); + const featureRegistry = new FeatureRegistry(); - expect(() => - featureRegistry.registerKibanaFeature(feature) - ).toThrowErrorMatchingInlineSnapshot( - `"Feature privilege test-feature.all has unknown alerting entries: foo, baz"` - ); - }); + expect(() => + featureRegistry.registerKibanaFeature(feature) + ).toThrowErrorMatchingInlineSnapshot( + `"Feature privilege test-feature.all has unknown ruleTypeId: foo"` + ); + }); - it(`prevents features from specifying alerting/rule entries that don't exist at the privilege level`, () => { - const feature: KibanaFeatureConfig = { - id: 'test-feature', - name: 'Test Feature', - app: [], - category: { id: 'foo', label: 'foo' }, - alerting: ['foo', 'bar', 'baz'], - privileges: { - all: { - alerting: { - rule: { - all: ['foo'], + it(`prevents features from specifying rule types that don't exist at the privilege level`, () => { + const feature: KibanaFeatureConfig = { + id: 'test-feature', + name: 'Test Feature', + app: [], + category: { id: 'foo', label: 'foo' }, + alerting: [ + { ruleTypeId: 'foo', consumers: ['test-feature'] }, + { ruleTypeId: 'bar', consumers: ['test-feature'] }, + { ruleTypeId: 'baz', consumers: ['test-feature'] }, + ], + privileges: { + all: { + alerting: { + rule: { + all: [{ ruleTypeId: 'foo', consumers: ['test-feature'] }], + }, + }, + savedObject: { + all: [], + read: [], }, + ui: [], + app: [], }, - savedObject: { - all: [], - read: [], + read: { + alerting: { + rule: { + all: [{ ruleTypeId: 'foo', consumers: ['test-feature'] }], + }, + }, + savedObject: { + all: [], + read: [], + }, + ui: [], + app: [], }, - ui: [], - app: [], }, - read: { - alerting: { - rule: { - all: ['foo'], + subFeatures: [ + { + name: 'my sub feature', + privilegeGroups: [ + { + groupType: 'independent', + privileges: [ + { + id: 'cool-sub-feature-privilege', + name: 'cool privilege', + includeIn: 'none', + savedObject: { + all: [], + read: [], + }, + ui: [], + alerting: { + rule: { + all: [{ ruleTypeId: 'bar', consumers: ['test-feature'] }], + }, + }, + }, + ], + }, + ], + }, + ], + }; + + const featureRegistry = new FeatureRegistry(); + + expect(() => + featureRegistry.registerKibanaFeature(feature) + ).toThrowErrorMatchingInlineSnapshot( + `"Feature test-feature specifies alerting rule types which are not granted to any privileges: baz"` + ); + }); + + it(`prevents features from specifying rule types entries that don't exist at the privilege level`, () => { + const feature: KibanaFeatureConfig = { + id: 'test-feature', + name: 'Test Feature', + app: [], + category: { id: 'foo', label: 'foo' }, + alerting: [ + { ruleTypeId: 'foo', consumers: ['test-feature'] }, + { ruleTypeId: 'bar', consumers: ['test-feature'] }, + { ruleTypeId: 'baz', consumers: ['test-feature'] }, + ], + privileges: { + all: { + alerting: { + alert: { + all: [{ ruleTypeId: 'foo', consumers: ['test-feature'] }], + }, }, + savedObject: { + all: [], + read: [], + }, + ui: [], + app: [], }, - savedObject: { - all: [], - read: [], + read: { + alerting: { + alert: { + all: [{ ruleTypeId: 'foo', consumers: ['test-feature'] }], + }, + }, + savedObject: { + all: [], + read: [], + }, + ui: [], + app: [], }, - ui: [], - app: [], }, - }, - subFeatures: [ - { - name: 'my sub feature', - privilegeGroups: [ - { - groupType: 'independent', - privileges: [ - { - id: 'cool-sub-feature-privilege', - name: 'cool privilege', - includeIn: 'none', - savedObject: { - all: [], - read: [], - }, - ui: [], - alerting: { - rule: { - all: ['bar'], + subFeatures: [ + { + name: 'my sub feature', + privilegeGroups: [ + { + groupType: 'independent', + privileges: [ + { + id: 'cool-sub-feature-privilege', + name: 'cool privilege', + includeIn: 'none', + savedObject: { + all: [], + read: [], }, + ui: [], + alerting: { + alert: { + all: [{ ruleTypeId: 'bar', consumers: ['test-feature'] }], + }, + }, + }, + ], + }, + ], + }, + ], + }; + + const featureRegistry = new FeatureRegistry(); + + expect(() => + featureRegistry.registerKibanaFeature(feature) + ).toThrowErrorMatchingInlineSnapshot( + `"Feature test-feature specifies alerting rule types which are not granted to any privileges: baz"` + ); + }); + + it(`prevents reserved privileges from specifying rule types that don't exist at the root level`, () => { + const feature: KibanaFeatureConfig = { + id: 'test-feature', + name: 'Test Feature', + app: [], + category: { id: 'foo', label: 'foo' }, + alerting: [{ ruleTypeId: 'bar', consumers: ['test-feature'] }], + privileges: null, + reserved: { + description: 'something', + privileges: [ + { + id: 'reserved', + privilege: { + alerting: { + rule: { + all: [ + { ruleTypeId: 'foo', consumers: ['test-feature'] }, + { ruleTypeId: 'bar', consumers: ['test-feature'] }, + { ruleTypeId: 'baz', consumers: ['test-feature'] }, + ], }, }, - ], + savedObject: { + all: [], + read: [], + }, + ui: [], + app: [], + }, }, ], }, - ], - }; + }; - const featureRegistry = new FeatureRegistry(); + const featureRegistry = new FeatureRegistry(); - expect(() => - featureRegistry.registerKibanaFeature(feature) - ).toThrowErrorMatchingInlineSnapshot( - `"Feature test-feature specifies alerting entries which are not granted to any privileges: baz"` - ); - }); + expect(() => + featureRegistry.registerKibanaFeature(feature) + ).toThrowErrorMatchingInlineSnapshot( + `"Feature privilege test-feature.reserved has unknown ruleTypeId: foo"` + ); + }); - it(`prevents features from specifying alerting/alert entries that don't exist at the privilege level`, () => { - const feature: KibanaFeatureConfig = { - id: 'test-feature', - name: 'Test Feature', - app: [], - category: { id: 'foo', label: 'foo' }, - alerting: ['foo', 'bar', 'baz'], - privileges: { - all: { - alerting: { - alert: { - all: ['foo'], + it(`prevents reserved privileges from specifying rule types entries that don't exist at the root level`, () => { + const feature: KibanaFeatureConfig = { + id: 'test-feature', + name: 'Test Feature', + app: [], + category: { id: 'foo', label: 'foo' }, + alerting: [{ ruleTypeId: 'bar', consumers: ['test-feature'] }], + privileges: null, + reserved: { + description: 'something', + privileges: [ + { + id: 'reserved', + privilege: { + alerting: { + alert: { + all: [ + { ruleTypeId: 'foo', consumers: ['test-feature'] }, + { ruleTypeId: 'bar', consumers: ['test-feature'] }, + { ruleTypeId: 'baz', consumers: ['test-feature'] }, + ], + }, + }, + savedObject: { + all: [], + read: [], + }, + ui: [], + app: [], + }, }, - }, - savedObject: { - all: [], - read: [], - }, - ui: [], - app: [], + ], }, - read: { - alerting: { - alert: { - all: ['foo'], + }; + + const featureRegistry = new FeatureRegistry(); + + expect(() => + featureRegistry.registerKibanaFeature(feature) + ).toThrowErrorMatchingInlineSnapshot( + `"Feature privilege test-feature.reserved has unknown ruleTypeId: foo"` + ); + }); + + it(`prevents features from specifying rule types that don't exist at the reserved privilege level`, () => { + const feature: KibanaFeatureConfig = { + id: 'test-feature', + name: 'Test Feature', + app: [], + category: { id: 'foo', label: 'foo' }, + alerting: [ + { ruleTypeId: 'foo', consumers: ['test-feature'] }, + { ruleTypeId: 'bar', consumers: ['test-feature'] }, + { ruleTypeId: 'baz', consumers: ['test-feature'] }, + ], + privileges: null, + reserved: { + description: 'something', + privileges: [ + { + id: 'reserved', + privilege: { + alerting: { + rule: { + all: [ + { ruleTypeId: 'foo', consumers: ['test-feature'] }, + { ruleTypeId: 'bar', consumers: ['test-feature'] }, + ], + }, + }, + savedObject: { + all: [], + read: [], + }, + ui: [], + app: [], + }, }, - }, - savedObject: { - all: [], - read: [], - }, - ui: [], - app: [], + ], }, - }, - subFeatures: [ - { - name: 'my sub feature', - privilegeGroups: [ + }; + + const featureRegistry = new FeatureRegistry(); + + expect(() => + featureRegistry.registerKibanaFeature(feature) + ).toThrowErrorMatchingInlineSnapshot( + `"Feature test-feature specifies alerting rule types which are not granted to any privileges: baz"` + ); + }); + + it(`prevents features from specifying rule types entries that don't exist at the reserved privilege level`, () => { + const feature: KibanaFeatureConfig = { + id: 'test-feature', + name: 'Test Feature', + app: [], + category: { id: 'foo', label: 'foo' }, + alerting: [ + { ruleTypeId: 'foo', consumers: ['test-feature'] }, + { ruleTypeId: 'bar', consumers: ['test-feature'] }, + { ruleTypeId: 'baz', consumers: ['test-feature'] }, + ], + privileges: null, + reserved: { + description: 'something', + privileges: [ { - groupType: 'independent', - privileges: [ - { - id: 'cool-sub-feature-privilege', - name: 'cool privilege', - includeIn: 'none', - savedObject: { - all: [], - read: [], - }, - ui: [], - alerting: { - alert: { - all: ['bar'], - }, + id: 'reserved', + privilege: { + alerting: { + alert: { + all: [ + { ruleTypeId: 'foo', consumers: ['test-feature'] }, + { ruleTypeId: 'bar', consumers: ['test-feature'] }, + ], }, }, - ], + savedObject: { + all: [], + read: [], + }, + ui: [], + app: [], + }, }, ], }, - ], - }; + }; - const featureRegistry = new FeatureRegistry(); + const featureRegistry = new FeatureRegistry(); - expect(() => - featureRegistry.registerKibanaFeature(feature) - ).toThrowErrorMatchingInlineSnapshot( - `"Feature test-feature specifies alerting entries which are not granted to any privileges: baz"` - ); - }); + expect(() => + featureRegistry.registerKibanaFeature(feature) + ).toThrowErrorMatchingInlineSnapshot( + `"Feature test-feature specifies alerting rule types which are not granted to any privileges: baz"` + ); + }); - it(`prevents reserved privileges from specifying alerting/rule entries that don't exist at the root level`, () => { - const feature: KibanaFeatureConfig = { - id: 'test-feature', - name: 'Test Feature', - app: [], - category: { id: 'foo', label: 'foo' }, - alerting: ['bar'], - privileges: null, - reserved: { - description: 'something', - privileges: [ - { - id: 'reserved', - privilege: { - alerting: { - rule: { - all: ['foo', 'bar', 'baz'], - }, + it(`prevents privileges from specifying rule types without consumers`, () => { + const feature: KibanaFeatureConfig = { + id: 'test-feature', + name: 'Test Feature', + app: [], + category: { id: 'foo', label: 'foo' }, + alerting: [{ ruleTypeId: 'foo', consumers: [] }], + privileges: { + all: { + alerting: { + rule: { + all: [{ ruleTypeId: 'foo', consumers: [] }], }, - savedObject: { - all: [], - read: [], + }, + savedObject: { + all: [], + read: [], + }, + ui: [], + app: [], + }, + read: { + alerting: { + rule: { + read: [{ ruleTypeId: 'foo', consumers: [] }], }, - ui: [], - app: [], }, + savedObject: { + all: [], + read: [], + }, + ui: [], + app: [], }, - ], - }, - }; + }, + }; - const featureRegistry = new FeatureRegistry(); + const featureRegistry = new FeatureRegistry(); - expect(() => - featureRegistry.registerKibanaFeature(feature) - ).toThrowErrorMatchingInlineSnapshot( - `"Feature privilege test-feature.reserved has unknown alerting entries: foo, baz"` - ); - }); + expect(() => + featureRegistry.registerKibanaFeature(feature) + ).toThrowErrorMatchingInlineSnapshot( + `"[alerting.0.consumers]: array size is [0], but cannot be smaller than [1]"` + ); + }); - it(`prevents reserved privileges from specifying alerting/alert entries that don't exist at the root level`, () => { - const feature: KibanaFeatureConfig = { - id: 'test-feature', - name: 'Test Feature', - app: [], - category: { id: 'foo', label: 'foo' }, - alerting: ['bar'], - privileges: null, - reserved: { - description: 'something', - privileges: [ - { - id: 'reserved', - privilege: { - alerting: { - alert: { - all: ['foo', 'bar', 'baz'], - }, + it(`prevents privileges from specifying consumers entries that don't exist at the root level`, () => { + const feature: KibanaFeatureConfig = { + id: 'test-feature', + name: 'Test Feature', + app: [], + category: { id: 'foo', label: 'foo' }, + alerting: [{ ruleTypeId: 'bar', consumers: ['test-feature'] }], + privileges: { + all: { + alerting: { + rule: { + all: [{ ruleTypeId: 'bar', consumers: ['not-exist'] }], + read: [{ ruleTypeId: 'bar', consumers: ['test-feature'] }], }, - savedObject: { - all: [], - read: [], + }, + savedObject: { + all: [], + read: [], + }, + ui: [], + app: [], + }, + read: { + alerting: { + rule: { + read: [{ ruleTypeId: 'bar', consumers: ['test-feature'] }], }, - ui: [], - app: [], }, + savedObject: { + all: [], + read: [], + }, + ui: [], + app: [], }, - ], - }, - }; + }, + }; - const featureRegistry = new FeatureRegistry(); + const featureRegistry = new FeatureRegistry(); - expect(() => - featureRegistry.registerKibanaFeature(feature) - ).toThrowErrorMatchingInlineSnapshot( - `"Feature privilege test-feature.reserved has unknown alerting entries: foo, baz"` - ); - }); + expect(() => + featureRegistry.registerKibanaFeature(feature) + ).toThrowErrorMatchingInlineSnapshot( + `"Feature privilege test-feature.all.bar has unknown consumer: not-exist"` + ); + }); - it(`prevents features from specifying alerting/rule entries that don't exist at the reserved privilege level`, () => { - const feature: KibanaFeatureConfig = { - id: 'test-feature', - name: 'Test Feature', - app: [], - category: { id: 'foo', label: 'foo' }, - alerting: ['foo', 'bar', 'baz'], - privileges: null, - reserved: { - description: 'something', - privileges: [ - { - id: 'reserved', - privilege: { - alerting: { - rule: { - all: ['foo', 'bar'], - }, + it(`prevents features from specifying consumers that don't exist at the privilege level`, () => { + const feature: KibanaFeatureConfig = { + id: 'test-feature', + name: 'Test Feature', + app: [], + category: { id: 'foo', label: 'foo' }, + alerting: [{ ruleTypeId: 'foo', consumers: ['test-feature', 'should-exist', 'foo'] }], + privileges: { + all: { + alerting: { + alert: { + all: [{ ruleTypeId: 'foo', consumers: ['test-feature'] }], }, - savedObject: { - all: [], - read: [], + }, + savedObject: { + all: [], + read: [], + }, + ui: [], + app: [], + }, + read: { + alerting: { + alert: { + all: [{ ruleTypeId: 'foo', consumers: ['test-feature'] }], }, - ui: [], - app: [], }, + savedObject: { + all: [], + read: [], + }, + ui: [], + app: [], + }, + }, + subFeatures: [ + { + name: 'my sub feature', + privilegeGroups: [ + { + groupType: 'independent', + privileges: [ + { + id: 'cool-sub-feature-privilege', + name: 'cool privilege', + includeIn: 'none', + savedObject: { + all: [], + read: [], + }, + ui: [], + alerting: { + alert: { + all: [{ ruleTypeId: 'foo', consumers: ['foo'] }], + }, + }, + }, + ], + }, + ], }, ], - }, - }; + }; - const featureRegistry = new FeatureRegistry(); + const featureRegistry = new FeatureRegistry(); - expect(() => - featureRegistry.registerKibanaFeature(feature) - ).toThrowErrorMatchingInlineSnapshot( - `"Feature test-feature specifies alerting entries which are not granted to any privileges: baz"` - ); - }); + expect(() => + featureRegistry.registerKibanaFeature(feature) + ).toThrowErrorMatchingInlineSnapshot( + `"Feature test-feature specifies alerting consumers which are not granted to any privileges: should-exist"` + ); + }); - it(`prevents features from specifying alerting/alert entries that don't exist at the reserved privilege level`, () => { - const feature: KibanaFeatureConfig = { - id: 'test-feature', - name: 'Test Feature', - app: [], - category: { id: 'foo', label: 'foo' }, - alerting: ['foo', 'bar', 'baz'], - privileges: null, - reserved: { - description: 'something', - privileges: [ - { - id: 'reserved', - privilege: { - alerting: { - alert: { - all: ['foo', 'bar'], + it(`prevents reserved privileges from specifying consumers that don't exist at the root level`, () => { + const feature: KibanaFeatureConfig = { + id: 'test-feature', + name: 'Test Feature', + app: [], + category: { id: 'foo', label: 'foo' }, + alerting: [{ ruleTypeId: 'bar', consumers: ['test-feature'] }], + privileges: null, + reserved: { + description: 'something', + privileges: [ + { + id: 'reserved', + privilege: { + alerting: { + rule: { + all: [{ ruleTypeId: 'bar', consumers: ['not-exist'] }], + }, + }, + savedObject: { + all: [], + read: [], }, + ui: [], + app: [], }, - savedObject: { - all: [], - read: [], + }, + ], + }, + }; + + const featureRegistry = new FeatureRegistry(); + + expect(() => + featureRegistry.registerKibanaFeature(feature) + ).toThrowErrorMatchingInlineSnapshot( + `"Feature privilege test-feature.reserved.bar has unknown consumer: not-exist"` + ); + }); + + it(`prevents features from specifying consumers that don't exist at the reserved privilege level`, () => { + const feature: KibanaFeatureConfig = { + id: 'test-feature', + name: 'Test Feature', + app: [], + category: { id: 'foo', label: 'foo' }, + alerting: [{ ruleTypeId: 'foo', consumers: ['test-feature', 'should-exist'] }], + privileges: null, + reserved: { + description: 'something', + privileges: [ + { + id: 'reserved', + privilege: { + alerting: { + rule: { + all: [{ ruleTypeId: 'foo', consumers: ['test-feature'] }], + }, + }, + savedObject: { + all: [], + read: [], + }, + ui: [], + app: [], }, - ui: [], - app: [], }, - }, - ], - }, - }; + ], + }, + }; - const featureRegistry = new FeatureRegistry(); + const featureRegistry = new FeatureRegistry(); - expect(() => - featureRegistry.registerKibanaFeature(feature) - ).toThrowErrorMatchingInlineSnapshot( - `"Feature test-feature specifies alerting entries which are not granted to any privileges: baz"` - ); + expect(() => + featureRegistry.registerKibanaFeature(feature) + ).toThrowErrorMatchingInlineSnapshot( + `"Feature test-feature specifies alerting consumers which are not granted to any privileges: should-exist"` + ); + }); }); it(`prevents privileges from specifying cases entries that don't exist at the root level`, () => { @@ -2068,11 +2352,15 @@ describe('FeatureRegistry', () => { all: { ui: [], savedObject: { all: [], read: [] }, - alerting: { alert: { all: ['one'] } }, + alerting: { + alert: { + all: [{ ruleTypeId: 'one', consumers: ['featureE'] }], + }, + }, }, read: { ui: [], savedObject: { all: [], read: [] } }, }, - alerting: ['one'], + alerting: [{ ruleTypeId: 'one', consumers: ['featureE'] }], }, ]; features.forEach((f) => registry.registerKibanaFeature(f)); diff --git a/x-pack/plugins/features/server/feature_schema.ts b/x-pack/plugins/features/server/feature_schema.ts index ce444c41e477d..3923eb31dbecb 100644 --- a/x-pack/plugins/features/server/feature_schema.ts +++ b/x-pack/plugins/features/server/feature_schema.ts @@ -11,6 +11,7 @@ import { difference } from 'lodash'; import { Capabilities as UICapabilities } from '@kbn/core/server'; import { KibanaFeatureConfig, KibanaFeatureScope } from '../common'; import { FeatureKibanaPrivileges, ElasticsearchFeatureConfig } from '.'; +import { AlertingKibanaPrivilege } from '../common/alerting_kibana_privilege'; // Each feature gets its own property on the UICapabilities object, // but that object has a few built-in properties which should not be overwritten. @@ -63,7 +64,13 @@ const managementSchema = schema.recordOf( listOfCapabilitiesSchema ); const catalogueSchema = listOfCapabilitiesSchema; -const alertingSchema = schema.arrayOf(schema.string()); +const alertingSchema = schema.arrayOf( + schema.object({ + ruleTypeId: schema.string(), + consumers: schema.arrayOf(schema.string(), { minSize: 1 }), + }) +); + const casesSchema = schema.arrayOf(schema.string()); const appCategorySchema = schema.object({ @@ -331,7 +338,14 @@ export function validateKibanaFeature(feature: KibanaFeatureConfig) { const unseenCatalogue = new Set(catalogue); - const unseenAlertTypes = new Set(alerting); + const alertingMap = new Map( + alerting.map(({ ruleTypeId, consumers }) => [ruleTypeId, new Set(consumers)]) + ); + + const unseenAlertingRyleTypeIds = new Set(alertingMap.keys()); + const unseenAlertingConsumers = new Set( + alerting.flatMap(({ consumers }) => Array.from(consumers.values())) + ); const unseenCasesTypes = new Set(cases); @@ -362,20 +376,40 @@ export function validateKibanaFeature(feature: KibanaFeatureConfig) { } function validateAlertingEntry(privilegeId: string, entry: FeatureKibanaPrivileges['alerting']) { - const all: string[] = [...(entry?.rule?.all ?? []), ...(entry?.alert?.all ?? [])]; - const read: string[] = [...(entry?.rule?.read ?? []), ...(entry?.alert?.read ?? [])]; + const seenRuleTypeIds = new Set(); + const seenConsumers = new Set(); + + const validateAlertingPrivilege = (alertingPrivilege?: AlertingKibanaPrivilege) => { + for (const { ruleTypeId, consumers } of alertingPrivilege ?? []) { + if (!alertingMap.has(ruleTypeId)) { + throw new Error( + `Feature privilege ${feature.id}.${privilegeId} has unknown ruleTypeId: ${ruleTypeId}` + ); + } + + const alertingMapConsumers = alertingMap.get(ruleTypeId)!; + + for (const consumer of consumers) { + if (!alertingMapConsumers.has(consumer)) { + throw new Error( + `Feature privilege ${feature.id}.${privilegeId}.${ruleTypeId} has unknown consumer: ${consumer}` + ); + } - all.forEach((privilegeAlertTypes) => unseenAlertTypes.delete(privilegeAlertTypes)); - read.forEach((privilegeAlertTypes) => unseenAlertTypes.delete(privilegeAlertTypes)); + seenConsumers.add(consumer); + } - const unknownAlertingEntries = difference([...all, ...read], alerting); - if (unknownAlertingEntries.length > 0) { - throw new Error( - `Feature privilege ${ - feature.id - }.${privilegeId} has unknown alerting entries: ${unknownAlertingEntries.join(', ')}` - ); - } + seenRuleTypeIds.add(ruleTypeId); + } + }; + + validateAlertingPrivilege(entry?.rule?.all); + validateAlertingPrivilege(entry?.rule?.read); + validateAlertingPrivilege(entry?.alert?.all); + validateAlertingPrivilege(entry?.alert?.read); + + seenRuleTypeIds.forEach((ruleTypeId: string) => unseenAlertingRyleTypeIds.delete(ruleTypeId)); + seenConsumers.forEach((consumer: string) => unseenAlertingConsumers.delete(consumer)); } function validateCasesEntry(privilegeId: string, entry: FeatureKibanaPrivileges['cases']) { @@ -510,12 +544,22 @@ export function validateKibanaFeature(feature: KibanaFeatureConfig) { ); } - if (unseenAlertTypes.size > 0) { + if (unseenAlertingRyleTypeIds.size > 0) { + throw new Error( + `Feature ${ + feature.id + } specifies alerting rule types which are not granted to any privileges: ${Array.from( + unseenAlertingRyleTypeIds.keys() + ).join(',')}` + ); + } + + if (unseenAlertingConsumers.size > 0) { throw new Error( `Feature ${ feature.id - } specifies alerting entries which are not granted to any privileges: ${Array.from( - unseenAlertTypes.values() + } specifies alerting consumers which are not granted to any privileges: ${Array.from( + unseenAlertingConsumers.keys() ).join(',')}` ); } diff --git a/x-pack/plugins/features/server/oss_features.ts b/x-pack/plugins/features/server/oss_features.ts index 19001fe19547e..0f243e7e6bda8 100644 --- a/x-pack/plugins/features/server/oss_features.ts +++ b/x-pack/plugins/features/server/oss_features.ts @@ -401,6 +401,7 @@ export const buildOSSFeatures = ({ read: [], }, ui: ['save'], + api: ['indexPatterns:manage'], }, read: { app: ['kibana'], diff --git a/x-pack/plugins/fleet/common/services/package_to_package_policy.test.ts b/x-pack/plugins/fleet/common/services/package_to_package_policy.test.ts index 0918fcaa08d7f..8f96c3ffc197d 100644 --- a/x-pack/plugins/fleet/common/services/package_to_package_policy.test.ts +++ b/x-pack/plugins/fleet/common/services/package_to_package_policy.test.ts @@ -469,6 +469,45 @@ describe('Fleet - packageToPackagePolicy', () => { }); }); + it('returns package policy with inputs variables', () => { + const mockPackageWithPolicyTemplates = { + ...mockPackage, + policy_templates: [ + { inputs: [{ type: 'foo' }] }, + { inputs: [{ type: 'bar', vars: [{ default: 'bar-var-value', name: 'var-name' }] }] }, + ], + } as unknown as PackageInfo; + + expect( + packageToPackagePolicy( + mockPackageWithPolicyTemplates, + 'policy-id-1', + 'default', + 'pkgPolicy-1' + ) + ).toEqual({ + policy_id: 'policy-id-1', + policy_ids: ['policy-id-1'], + namespace: 'default', + enabled: true, + inputs: [ + { type: 'foo', enabled: true, streams: [] }, + { + type: 'bar', + enabled: true, + streams: [], + vars: { 'var-name': { value: 'bar-var-value' } }, + }, + ], + name: 'pkgPolicy-1', + package: { + name: 'mock-package', + title: 'Mock package', + version: '0.0.0', + }, + }); + }); + it('returns package policy with multiple policy templates (aka has integrations', () => { expect( packageToPackagePolicy( diff --git a/x-pack/plugins/fleet/common/services/package_to_package_policy.ts b/x-pack/plugins/fleet/common/services/package_to_package_policy.ts index a830cfd903007..6aed76b0a115b 100644 --- a/x-pack/plugins/fleet/common/services/package_to_package_policy.ts +++ b/x-pack/plugins/fleet/common/services/package_to_package_policy.ts @@ -147,9 +147,7 @@ export const packageToPackagePolicyInputs = ( return stream; }); - // If non-integration package, collect input-level vars, otherwise skip them, - // we do not support input-level vars for packages with integrations yet) - if (packageInput.vars?.length && !hasIntegrations) { + if (packageInput.vars?.length) { varsForInput = packageInput.vars.reduce(varsReducer, {}); } diff --git a/x-pack/plugins/fleet/cypress/e2e/agents/agentless.cy.ts b/x-pack/plugins/fleet/cypress/e2e/agents/agentless.cy.ts new file mode 100644 index 0000000000000..2003a9f165d3b --- /dev/null +++ b/x-pack/plugins/fleet/cypress/e2e/agents/agentless.cy.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 { ADD_PACKAGE_POLICY_BTN } from '../../screens/fleet'; +import { login } from '../../tasks/login'; + +describe('View agentless policy details', () => { + beforeEach(() => { + login(); + cy.intercept('/api/fleet/agent_policies/policy-1', { + item: { + id: 'policy-1', + name: 'Agentless policy for cspm-1', + description: '', + namespace: 'default', + monitoring_enabled: ['logs', 'metrics'], + status: 'active', + supports_agentless: true, + package_policies: [ + { + id: 'cspm-1', + name: 'cspm-1', + policy_id: 'policy-1', + policy_ids: ['policy-1'], + inputs: [], + }, + ], + }, + }); + }); + + it('should not show the add integration button if the policy support agentless', () => { + cy.visit('/app/fleet/policies/policy-1'); + cy.getBySel(ADD_PACKAGE_POLICY_BTN).should('not.exist'); + }); +}); diff --git a/x-pack/plugins/fleet/public/applications/fleet/hooks/use_apm_service_href.test.ts b/x-pack/plugins/fleet/public/applications/fleet/hooks/use_apm_service_href.test.ts index da4d0e2c2594d..9d2f6ba4ccf01 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/hooks/use_apm_service_href.test.ts +++ b/x-pack/plugins/fleet/public/applications/fleet/hooks/use_apm_service_href.test.ts @@ -20,7 +20,8 @@ jest.mock('../../../hooks/use_locator', () => { }); const apmLocatorMock = useLocatorModule.useLocator('APM_LOCATOR')?.getUrl; -describe('useApmServiceHref hook', () => { +// FLAKY: https://github.com/elastic/kibana/issues/201876 +describe.skip('useApmServiceHref hook', () => { afterEach(() => { jest.clearAllMocks(); }); diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/details_page/components/package_policies/package_policies_table.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/details_page/components/package_policies/package_policies_table.tsx index 83e18d77f2a06..3fe016d5e35f1 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/details_page/components/package_policies/package_policies_table.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/details_page/components/package_policies/package_policies_table.tsx @@ -400,45 +400,46 @@ export const PackagePoliciesTable: React.FunctionComponent = ({ }} {...rest} search={{ - toolsRight: agentPolicy.is_managed - ? [] - : [ - { - application.navigateToApp(INTEGRATIONS_PLUGIN_ID, { - path: pagePathGetters.integrations_all({})[1], - state: { forAgentPolicyId: agentPolicy.id }, - }); - }} - data-test-subj="addPackagePolicyButton" - tooltip={ - !canWriteIntegrationPolicies - ? { - content: missingSecurityConfiguration ? ( - - ) : ( - - ), - } - : undefined - } - > - - , - ], + toolsRight: + agentPolicy.is_managed || agentPolicy.supports_agentless + ? [] + : [ + { + application.navigateToApp(INTEGRATIONS_PLUGIN_ID, { + path: pagePathGetters.integrations_all({})[1], + state: { forAgentPolicyId: agentPolicy.id }, + }); + }} + data-test-subj="addPackagePolicyButton" + tooltip={ + !canWriteIntegrationPolicies + ? { + content: missingSecurityConfiguration ? ( + + ) : ( + + ), + } + : undefined + } + > + + , + ], box: { incremental: true, schema: true, diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/agent_policy_outputs_summary.test.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/agent_policy_outputs_summary.test.tsx index 255b2efb94026..b56494311f6a9 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/agent_policy_outputs_summary.test.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/agent_policy_outputs_summary.test.tsx @@ -15,7 +15,8 @@ import type { OutputsForAgentPolicy } from '../../../../../../../common/types'; import { AgentPolicyOutputsSummary } from './agent_policy_outputs_summary'; -describe('MultipleAgentPolicySummaryLine', () => { +// FLAKY: https://github.com/elastic/kibana/issues/200819 +describe.skip('MultipleAgentPolicySummaryLine', () => { let testRenderer: TestRenderer; const outputsForPolicy: OutputsForAgentPolicy = { agentPolicyId: 'policy-1', diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/multi_row_input/index.test.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/multi_row_input/index.test.tsx index f3fcdfabc7722..bfd9028f5d0ce 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/multi_row_input/index.test.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/multi_row_input/index.test.tsx @@ -6,7 +6,7 @@ */ import React from 'react'; -import { fireEvent, act } from '@testing-library/react'; +import { fireEvent, waitFor } from '@testing-library/react'; import { createFleetTestRendererMock } from '../../../../../../mock'; @@ -44,13 +44,9 @@ test('it should allow to add a new host', async () => { test('it should allow to remove an host', async () => { const { utils, mockOnChange } = renderInput(['http://host1.com', 'http://host2.com']); - await act(async () => { - const deleteRowEl = await utils.container.querySelector('[aria-label="Delete row"]'); - if (!deleteRowEl) { - throw new Error('Delete row button not found'); - } - fireEvent.click(deleteRowEl); - }); + const deleteRowEl = await utils.container.querySelector('[aria-label="Delete row"]'); + expect(deleteRowEl).not.toBeNull(); + fireEvent.click(deleteRowEl!); expect(mockOnChange).toHaveBeenCalledWith(['http://host2.com']); }); @@ -95,7 +91,7 @@ test('Should display errors in order', async () => { { message: 'Error 3', index: 2 }, ] ); - await act(async () => { + await waitFor(async () => { const errors = await utils.queryAllByText(/Error [1-3]/); expect(errors[0]).toHaveTextContent('Error 1'); expect(errors[1]).toHaveTextContent('Error 2'); @@ -126,18 +122,14 @@ test('Should remove error when item deleted', async () => { ); }); - await act(async () => { - const deleteRowButtons = await utils.container.querySelectorAll('[aria-label="Delete row"]'); - if (deleteRowButtons.length !== 3) { - throw new Error('Delete row buttons not found'); - } + const deleteRowButtons = await utils.container.querySelectorAll('[aria-label="Delete row"]'); + expect(deleteRowButtons.length).toEqual(3); - fireEvent.click(deleteRowButtons[1]); - expect(mockOnChange).toHaveBeenCalled(); + fireEvent.click(deleteRowButtons[1]); + expect(mockOnChange).toHaveBeenCalled(); - const renderedErrors = await utils.queryAllByText(/Error [1-3]/); - expect(renderedErrors).toHaveLength(2); - expect(renderedErrors[0]).toHaveTextContent('Error 1'); - expect(renderedErrors[1]).toHaveTextContent('Error 3'); - }); + const renderedErrors = await utils.queryAllByText(/Error [1-3]/); + expect(renderedErrors).toHaveLength(2); + expect(renderedErrors[0]).toHaveTextContent('Error 1'); + expect(renderedErrors[1]).toHaveTextContent('Error 3'); }); diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/index.test.tsx b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/index.test.tsx index 6c9be4796f205..400c5f3a5aa6d 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/index.test.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/index.test.tsx @@ -7,7 +7,7 @@ import React, { lazy, memo } from 'react'; import { Route } from '@kbn/shared-ux-router'; -import { act, cleanup } from '@testing-library/react'; +import { act } from '@testing-library/react'; import { INTEGRATIONS_ROUTING_PATHS, pagePathGetters } from '../../../../constants'; import type { @@ -65,10 +65,6 @@ describe('When on integration detail', () => { act(() => testRenderer.mountHistory.push(detailPageUrlPath)); }); - afterEach(() => { - cleanup(); - }); - describe('and the package is installed', () => { beforeEach(async () => { await render(); diff --git a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_enrollment_flyout.test.tsx b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_enrollment_flyout.test.tsx index 19709c55665fc..13ecfc2282226 100644 --- a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_enrollment_flyout.test.tsx +++ b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_enrollment_flyout.test.tsx @@ -8,7 +8,7 @@ import './agent_enrollment_flyout.test.mocks'; import React from 'react'; -import { act, cleanup, fireEvent, waitFor } from '@testing-library/react'; +import { fireEvent, waitFor } from '@testing-library/react'; import type { RenderResult } from '@testing-library/react'; import { createFleetTestRendererMock } from '../../mock'; @@ -23,11 +23,8 @@ import type { FlyOutProps } from './types'; import { AgentEnrollmentFlyout } from '.'; const render = (props?: Partial) => { - cleanup(); const renderer = createFleetTestRendererMock(); - const results = renderer.render(); - - return results; + return renderer.render(); }; const testAgentPolicy: AgentPolicy = { @@ -46,7 +43,7 @@ const testAgentPolicy: AgentPolicy = { describe('', () => { let results: RenderResult; - beforeEach(async () => { + beforeEach(() => { jest.mocked(useAuthz).mockReturnValue({ fleet: { readAgentPolicies: true, @@ -88,10 +85,6 @@ describe('', () => { agentPolicies: [{ id: 'fleet-server-policy' } as AgentPolicy], refreshAgentPolicies: jest.fn(), }); - - act(() => { - results = render(); - }); }); afterEach(() => { @@ -113,6 +106,8 @@ describe('', () => { describe('managed instructions', () => { it('uses the agent policy selection step', () => { + results = render(); + expect(results.queryByTestId('agentEnrollmentFlyout')).not.toBeNull(); expect(results.queryByTestId('agent-policy-selection-step')).not.toBeNull(); expect(results.queryByTestId('agent-enrollment-key-selection-step')).toBeNull(); @@ -154,24 +149,22 @@ describe('', () => { describe('standalone instructions', () => { function goToStandaloneTab() { - act(() => { - fireEvent.click(results.getByTestId('standaloneTab')); - }); + fireEvent.click(results.getByTestId('standaloneTab')); } - beforeEach(() => { + it('uses the agent policy selection step', async () => { results = render({ isIntegrationFlow: true, }); - }); - it('uses the agent policy selection step', async () => { goToStandaloneTab(); - expect(results.queryByTestId('agentEnrollmentFlyout')).not.toBeNull(); - expect(results.queryByTestId('agent-policy-selection-step')).not.toBeNull(); - expect(results.queryByTestId('agent-enrollment-key-selection-step')).toBeNull(); - expect(results.queryByTestId('configure-standalone-step')).not.toBeNull(); + await waitFor(() => { + expect(results.queryByTestId('agentEnrollmentFlyout')).not.toBeNull(); + expect(results.queryByTestId('agent-policy-selection-step')).not.toBeNull(); + expect(results.queryByTestId('agent-enrollment-key-selection-step')).toBeNull(); + expect(results.queryByTestId('configure-standalone-step')).not.toBeNull(); + }); }); describe('with a specific policy', () => { @@ -185,13 +178,15 @@ describe('', () => { }); }); - it('does not use either of the agent policy selection or enrollment key steps', () => { + it('does not use either of the agent policy selection or enrollment key steps', async () => { goToStandaloneTab(); - expect(results.queryByTestId('agentEnrollmentFlyout')).not.toBeNull(); - expect(results.queryByTestId('agent-policy-selection-step')).toBeNull(); - expect(results.queryByTestId('agent-enrollment-key-selection-step')).toBeNull(); - expect(results.queryByTestId('configure-standalone-step')).not.toBeNull(); + await waitFor(() => { + expect(results.queryByTestId('agentEnrollmentFlyout')).not.toBeNull(); + expect(results.queryByTestId('agent-policy-selection-step')).toBeNull(); + expect(results.queryByTestId('agent-enrollment-key-selection-step')).toBeNull(); + expect(results.queryByTestId('configure-standalone-step')).not.toBeNull(); + }); }); }); }); diff --git a/x-pack/plugins/fleet/public/components/enrollment_instructions/root_privileges_callout.test.tsx b/x-pack/plugins/fleet/public/components/enrollment_instructions/root_privileges_callout.test.tsx index 86cbd1a1a5a10..6cf1f68673ac7 100644 --- a/x-pack/plugins/fleet/public/components/enrollment_instructions/root_privileges_callout.test.tsx +++ b/x-pack/plugins/fleet/public/components/enrollment_instructions/root_privileges_callout.test.tsx @@ -7,16 +7,14 @@ import React from 'react'; -import { cleanup, waitFor } from '@testing-library/react'; +import { waitFor } from '@testing-library/react'; import { createFleetTestRendererMock } from '../../mock'; import { RootPrivilegesCallout } from './root_privileges_callout'; -// FLAKY: https://github.com/elastic/kibana/issues/201210 -describe.skip('RootPrivilegesCallout', () => { +describe('RootPrivilegesCallout', () => { function render(rootIntegrations?: Array<{ name: string; title: string }>) { - cleanup(); const renderer = createFleetTestRendererMock(); const results = renderer.render(); diff --git a/x-pack/plugins/fleet/public/components/multiple_agent_policy_summary_line.test.tsx b/x-pack/plugins/fleet/public/components/multiple_agent_policy_summary_line.test.tsx index b14caf7a73517..22efe3f84d435 100644 --- a/x-pack/plugins/fleet/public/components/multiple_agent_policy_summary_line.test.tsx +++ b/x-pack/plugins/fleet/public/components/multiple_agent_policy_summary_line.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { act, fireEvent } from '@testing-library/react'; +import { fireEvent, waitFor } from '@testing-library/react'; import React from 'react'; import type { TestRenderer } from '../mock'; @@ -15,8 +15,7 @@ import type { AgentPolicy } from '../types'; import { MultipleAgentPoliciesSummaryLine } from './multiple_agent_policy_summary_line'; -// FLAKY: https://github.com/elastic/kibana/issues/200786 -describe.skip('MultipleAgentPolicySummaryLine', () => { +describe('MultipleAgentPolicySummaryLine', () => { let testRenderer: TestRenderer; const render = (agentPolicies: AgentPolicy[]) => @@ -32,7 +31,7 @@ describe.skip('MultipleAgentPolicySummaryLine', () => { testRenderer = createFleetTestRendererMock(); }); - test('it should only render the policy name when there is only one policy', async () => { + test('it should only render the policy name when there is only one policy', () => { const results = render([{ name: 'Test policy', revision: 2 }] as AgentPolicy[]); expect(results.container.textContent).toBe('Test policyrev. 2'); expect(results.queryByTestId('agentPolicyNameLink')).toBeInTheDocument(); @@ -49,19 +48,18 @@ describe.skip('MultipleAgentPolicySummaryLine', () => { expect(results.queryByTestId('agentPoliciesNumberBadge')).toBeInTheDocument(); expect(results.container.textContent).toBe('Test policy 1+2'); - await act(async () => { - fireEvent.click(results.getByTestId('agentPoliciesNumberBadge')); - }); - expect(results.queryByTestId('agentPoliciesPopover')).toBeInTheDocument(); - expect(results.queryByTestId('agentPoliciesPopoverButton')).toBeInTheDocument(); - expect(results.queryByTestId('policy-0001')).toBeInTheDocument(); - expect(results.queryByTestId('policy-0002')).toBeInTheDocument(); - expect(results.queryByTestId('policy-0003')).toBeInTheDocument(); + fireEvent.click(results.getByTestId('agentPoliciesNumberBadge')); - await act(async () => { - fireEvent.click(results.getByTestId('agentPoliciesPopoverButton')); + await waitFor(() => { + expect(results.queryByTestId('agentPoliciesPopover')).toBeInTheDocument(); + expect(results.queryByTestId('agentPoliciesPopoverButton')).toBeInTheDocument(); + expect(results.queryByTestId('policy-0001')).toBeInTheDocument(); + expect(results.queryByTestId('policy-0002')).toBeInTheDocument(); + expect(results.queryByTestId('policy-0003')).toBeInTheDocument(); }); + fireEvent.click(results.getByTestId('agentPoliciesPopoverButton')); + expect(results.queryByTestId('manageAgentPoliciesModal')).toBeInTheDocument(); }); }); diff --git a/x-pack/plugins/fleet/public/components/package_policy_actions_menu.test.tsx b/x-pack/plugins/fleet/public/components/package_policy_actions_menu.test.tsx index b7759438986d5..3c4b2c7f1bf3e 100644 --- a/x-pack/plugins/fleet/public/components/package_policy_actions_menu.test.tsx +++ b/x-pack/plugins/fleet/public/components/package_policy_actions_menu.test.tsx @@ -7,7 +7,7 @@ import React from 'react'; -import { act } from '@testing-library/react'; +import { waitFor } from '@testing-library/react'; import type { AgentPolicy, InMemoryPackagePolicy } from '../types'; import { createIntegrationsTestRendererMock } from '../mock'; @@ -109,8 +109,8 @@ function createMockPackagePolicy( ...props, }; } -// FLAKY: https://github.com/elastic/kibana/issues/191804 -describe.skip('PackagePolicyActionsMenu', () => { + +describe('PackagePolicyActionsMenu', () => { beforeAll(() => { useMultipleAgentPoliciesMock.mockReturnValue({ canUseMultipleAgentPolicies: false }); }); @@ -119,7 +119,8 @@ describe.skip('PackagePolicyActionsMenu', () => { const agentPolicies = createMockAgentPolicies(); const packagePolicy = createMockPackagePolicy({ hasUpgrade: false }); const { utils } = renderMenu({ agentPolicies, packagePolicy }); - await act(async () => { + + await waitFor(() => { expect(utils.queryByTestId('PackagePolicyActionsUpgradeItem')).toBeNull(); }); }); @@ -129,7 +130,7 @@ describe.skip('PackagePolicyActionsMenu', () => { const packagePolicy = createMockPackagePolicy({ hasUpgrade: true }); const { utils } = renderMenu({ agentPolicies, packagePolicy }); - await act(async () => { + await waitFor(() => { const upgradeButton = utils.getByTestId('PackagePolicyActionsUpgradeItem'); expect(upgradeButton).not.toBeDisabled(); }); @@ -140,7 +141,7 @@ describe.skip('PackagePolicyActionsMenu', () => { const packagePolicy = createMockPackagePolicy({ hasUpgrade: true }); const { utils } = renderMenu({ agentPolicies, packagePolicy }); - await act(async () => { + await waitFor(() => { const upgradeButton = utils.getByTestId('PackagePolicyActionsUpgradeItem'); expect(upgradeButton).toBeDisabled(); }); @@ -150,7 +151,7 @@ describe.skip('PackagePolicyActionsMenu', () => { const agentPolicies = createMockAgentPolicies({ is_managed: true }); const packagePolicy = createMockPackagePolicy(); const { utils } = renderMenu({ agentPolicies, packagePolicy }); - await act(async () => { + await waitFor(() => { expect(utils.queryByText('Delete integration')).toBeNull(); }); }); @@ -159,7 +160,7 @@ describe.skip('PackagePolicyActionsMenu', () => { const agentPolicies = createMockAgentPolicies({ is_managed: false }); const packagePolicy = createMockPackagePolicy(); const { utils } = renderMenu({ agentPolicies, packagePolicy }); - await act(async () => { + await waitFor(() => { expect(utils.queryByText('Delete integration')).not.toBeNull(); }); }); @@ -168,7 +169,7 @@ describe.skip('PackagePolicyActionsMenu', () => { const agentPolicies = createMockAgentPolicies({ is_managed: false, supports_agentless: true }); const packagePolicy = createMockPackagePolicy(); const { utils } = renderMenu({ agentPolicies, packagePolicy }); - await act(async () => { + await waitFor(() => { expect(utils.queryByText('Delete integration')).not.toBeNull(); }); }); @@ -177,7 +178,7 @@ describe.skip('PackagePolicyActionsMenu', () => { const agentPolicies = createMockAgentPolicies(); const packagePolicy = createMockPackagePolicy({ hasUpgrade: true }); const { utils } = renderMenu({ agentPolicies, packagePolicy, showAddAgent: true }); - await act(async () => { + await waitFor(() => { expect(utils.queryByText('Add agent')).not.toBeNull(); }); }); @@ -186,7 +187,7 @@ describe.skip('PackagePolicyActionsMenu', () => { const agentPolicies = createMockAgentPolicies({ is_managed: true }); const packagePolicy = createMockPackagePolicy({ hasUpgrade: true }); const { utils } = renderMenu({ agentPolicies, packagePolicy, showAddAgent: true }); - await act(async () => { + await waitFor(() => { expect(utils.queryByText('Add agent')).toBeNull(); }); }); @@ -195,7 +196,7 @@ describe.skip('PackagePolicyActionsMenu', () => { const agentPolicies = createMockAgentPolicies({ supports_agentless: true }); const packagePolicy = createMockPackagePolicy({ hasUpgrade: true }); const { utils } = renderMenu({ agentPolicies, packagePolicy, showAddAgent: true }); - await act(async () => { + await waitFor(() => { expect(utils.queryByText('Add agent')).toBeNull(); }); }); @@ -204,7 +205,7 @@ describe.skip('PackagePolicyActionsMenu', () => { const agentPolicies = createMockAgentPolicies(); const packagePolicy = createMockPackagePolicy(); const { utils } = renderMenu({ agentPolicies, packagePolicy }); - await act(async () => { + await waitFor(() => { const editButton = utils.getByTestId('PackagePolicyActionsEditItem'); expect(editButton).not.toHaveAttribute('disabled'); expect(editButton).toHaveAttribute('href'); @@ -227,7 +228,7 @@ describe.skip('PackagePolicyActionsMenu', () => { agentPolicies: [], packagePolicy, }); - await act(async () => { + await waitFor(() => { const editButton = utils.getByTestId('PackagePolicyActionsEditItem'); expect(editButton).not.toHaveAttribute('disabled'); expect(editButton).toHaveAttribute('href'); diff --git a/x-pack/plugins/fleet/public/components/package_policy_delete_provider.test.tsx b/x-pack/plugins/fleet/public/components/package_policy_delete_provider.test.tsx index a71172411ef9d..75fce0507f5af 100644 --- a/x-pack/plugins/fleet/public/components/package_policy_delete_provider.test.tsx +++ b/x-pack/plugins/fleet/public/components/package_policy_delete_provider.test.tsx @@ -7,7 +7,7 @@ import React from 'react'; -import { act, fireEvent } from '@testing-library/react'; +import { fireEvent, waitFor } from '@testing-library/react'; import { EuiContextMenuItem } from '@elastic/eui'; @@ -24,13 +24,15 @@ jest.mock('../hooks', () => { useMultipleAgentPolicies: jest.fn(), useStartServices: jest.fn().mockReturnValue({ notifications: { - toasts: { addSuccess: jest.fn() }, + toasts: { addSuccess: jest.fn(), addDanger: jest.fn() }, }, }), sendGetAgents: jest.fn(), useConfig: jest.fn().mockReturnValue({ agents: { enabled: true }, }), + sendDeletePackagePolicy: jest.fn().mockResolvedValue({ data: [] }), + sendDeleteAgentPolicy: jest.fn().mockResolvedValue({ data: [] }), }; }); @@ -56,6 +58,7 @@ function renderMenu({ onClick={() => { deletePackagePoliciesPrompt(packagePolicyIds, () => {}); }} + data-test-subj="deleteIntegrationBtn" > Delete integration @@ -134,8 +137,7 @@ function createMockAgentPolicies( } } -// FLAKY: https://github.com/elastic/kibana/issues/199204 -describe.skip('PackagePolicyDeleteProvider', () => { +describe('PackagePolicyDeleteProvider', () => { it('Should show delete integrations action and cancel modal', async () => { useMultipleAgentPoliciesMock.mockReturnValue({ canUseMultipleAgentPolicies: false }); sendGetAgentsMock.mockResolvedValue({ @@ -155,15 +157,16 @@ describe.skip('PackagePolicyDeleteProvider', () => { agentPolicies, packagePolicyIds: ['integration-0001'], }); - await act(async () => { - const button = utils.getByRole('button'); - fireEvent.click(button); + const button = utils.getByTestId('deleteIntegrationBtn'); + fireEvent.click(button); + await waitFor(() => { + const calloutText = utils.getByTestId('affectedAgentsCallOut').textContent; + expect(calloutText).toContain('This action will affect 5 agents.'); + expect(calloutText).toContain('is already in use by some of your agents'); + expect(utils.getByTestId('confirmModalBodyText').textContent).toContain( + 'This action can not be undone. Are you sure you wish to continue?' + ); }); - expect(utils.getByText('This action will affect 5 agents.')).toBeInTheDocument(); - expect( - utils.getByText('This action can not be undone. Are you sure you wish to continue?') - ).toBeInTheDocument(); - expect(utils.getAllByText(/is already in use by some of your agents./).length).toBe(1); }); it('When multiple agent policies are present and agents are enrolled show additional warnings', async () => { @@ -185,18 +188,19 @@ describe.skip('PackagePolicyDeleteProvider', () => { agentPolicies, packagePolicyIds: ['integration-0001'], }); - await act(async () => { - const button = utils.getByRole('button'); - fireEvent.click(button); + const button = utils.getByTestId('deleteIntegrationBtn'); + fireEvent.click(button); + + await waitFor(() => { + const calloutText = utils.getByTestId('affectedAgentsCallOut').textContent; + expect(calloutText).toContain('This action will affect 5 agents.'); + expect(utils.getByTestId('sharedAgentPolicyCallOut').textContent).toContain( + 'This integration is shared by multiple agent policies.' + ); + expect(utils.getByTestId('confirmModalBodyText').textContent).toContain( + 'This action can not be undone. Are you sure you wish to continue?' + ); }); - expect(utils.getByText('This action will affect 5 agents.')).toBeInTheDocument(); - expect( - utils.getByText('This integration is shared by multiple agent policies.') - ).toBeInTheDocument(); - expect( - utils.getByText('This action can not be undone. Are you sure you wish to continue?') - ).toBeInTheDocument(); - expect(utils.queryAllByText(/is already in use by some of your agents./).length).toBe(0); }); it('When multiple agent policies are present and no agents are enrolled show additional warnings', async () => { @@ -213,18 +217,18 @@ describe.skip('PackagePolicyDeleteProvider', () => { agentPolicies, packagePolicyIds: ['integration-0001'], }); - await act(async () => { - const button = utils.getByRole('button'); - fireEvent.click(button); + const button = utils.getByTestId('deleteIntegrationBtn'); + fireEvent.click(button); + + await waitFor(() => { + expect(utils.queryByTestId('affectedAgentsCallOut')).not.toBeInTheDocument(); + expect(utils.getByTestId('sharedAgentPolicyCallOut').textContent).toContain( + 'This integration is shared by multiple agent policies.' + ); + expect(utils.getByTestId('confirmModalBodyText').textContent).toContain( + 'This action can not be undone. Are you sure you wish to continue?' + ); }); - expect(utils.queryByText('This action will affect 5 agents.')).not.toBeInTheDocument(); - expect(utils.queryAllByText(/is already in use by some of your agents./).length).toBe(0); - expect( - utils.getByText('This integration is shared by multiple agent policies.') - ).toBeInTheDocument(); - expect( - utils.getByText('This action can not be undone. Are you sure you wish to continue?') - ).toBeInTheDocument(); }); it('When agentless should show a different set of warnings', async () => { @@ -246,16 +250,19 @@ describe.skip('PackagePolicyDeleteProvider', () => { agentPolicies, packagePolicyIds: ['integration-0001'], }); - await act(async () => { - const button = utils.getByRole('button'); - fireEvent.click(button); + const button = utils.getByTestId('deleteIntegrationBtn'); + fireEvent.click(button); + + await waitFor(() => { + expect(utils.getByTestId('affectedAgentsCallOut').textContent).not.toContain( + 'This action will affect 5 agents.' + ); + expect(utils.getByTestId('confirmModalBodyText').textContent).toContain( + 'This action can not be undone. Are you sure you wish to continue?' + ); + expect(utils.getByTestId('confirmModalTitleText').textContent).toContain( + 'about to delete an integration' + ); }); - // utils.debug(); - expect(utils.queryByText('This action will affect 5 agents.')).not.toBeInTheDocument(); - expect(utils.getByText(/about to delete an integration/)).toBeInTheDocument(); - expect( - utils.getByText('This action can not be undone. Are you sure you wish to continue?') - ).toBeInTheDocument(); - expect(utils.getAllByText(/integration will stop data ingestion./).length).toBe(1); }); }); diff --git a/x-pack/plugins/fleet/public/components/package_policy_delete_provider.tsx b/x-pack/plugins/fleet/public/components/package_policy_delete_provider.tsx index f12c4cf371ed5..70e7d77636fcc 100644 --- a/x-pack/plugins/fleet/public/components/package_policy_delete_provider.tsx +++ b/x-pack/plugins/fleet/public/components/package_policy_delete_provider.tsx @@ -247,6 +247,7 @@ export const PackagePolicyDeleteProvider: React.FunctionComponent = ({ defaultMessage="This integration is shared by multiple agent policies." /> } + data-test-subj="sharedAgentPolicyCallOut" /> @@ -261,6 +262,7 @@ export const PackagePolicyDeleteProvider: React.FunctionComponent = ({ <> (agentPolicy.unprivileged_agents = total)); return Promise.all([totalAgents, unprivilegedAgents]); }, - { concurrency: 10 } + { concurrency: MAX_CONCURRENT_AGENT_POLICIES_OPERATIONS_10 } ); } diff --git a/x-pack/plugins/fleet/server/routes/data_streams/handlers.ts b/x-pack/plugins/fleet/server/routes/data_streams/handlers.ts index 7ed4b5bacf336..2a4ab12ad0055 100644 --- a/x-pack/plugins/fleet/server/routes/data_streams/handlers.ts +++ b/x-pack/plugins/fleet/server/routes/data_streams/handlers.ts @@ -17,6 +17,7 @@ import type { GetDataStreamsResponse } from '../../../common/types'; import { getPackageSavedObjects } from '../../services/epm/packages/get'; import type { MeteringStats } from '../../services/data_streams'; import { dataStreamService } from '../../services/data_streams'; +import { MAX_CONCURRENT_DATASTREAM_OPERATIONS } from '../../constants'; import { appContextService } from '../../services'; import { getDataStreamsQueryMetadata } from './get_data_streams_query_metadata'; @@ -233,7 +234,7 @@ export const getListHandler: RequestHandler = async (context, request, response) // After filtering out data streams that are missing dataset/namespace/type/package fields body.data_streams = ( await pMap(dataStreamNames, (dataStreamName) => queryDataStreamInfo(dataStreamName), { - concurrency: 50, + concurrency: MAX_CONCURRENT_DATASTREAM_OPERATIONS, }) ) .filter(({ dataset, namespace, type }) => dataset && namespace && type) diff --git a/x-pack/plugins/fleet/server/routes/fleet_proxies/handler.ts b/x-pack/plugins/fleet/server/routes/fleet_proxies/handler.ts index 2d63b357347db..880b042de4350 100644 --- a/x-pack/plugins/fleet/server/routes/fleet_proxies/handler.ts +++ b/x-pack/plugins/fleet/server/routes/fleet_proxies/handler.ts @@ -31,6 +31,7 @@ import type { DownloadSource, } from '../../types'; import { agentPolicyService } from '../../services'; +import { MAX_CONCURRENT_AGENT_POLICIES_OPERATIONS_20 } from '../../constants'; async function bumpRelatedPolicies( soClient: SavedObjectsClientContract, @@ -49,7 +50,7 @@ async function bumpRelatedPolicies( outputs, (output) => agentPolicyService.bumpAllAgentPoliciesForOutput(esClient, output.id), { - concurrency: 20, + concurrency: MAX_CONCURRENT_AGENT_POLICIES_OPERATIONS_20, } ); await pMap( @@ -57,7 +58,7 @@ async function bumpRelatedPolicies( (fleetServerHost) => agentPolicyService.bumpAllAgentPoliciesForFleetServerHosts(esClient, fleetServerHost.id), { - concurrency: 20, + concurrency: MAX_CONCURRENT_AGENT_POLICIES_OPERATIONS_20, } ); @@ -66,7 +67,7 @@ async function bumpRelatedPolicies( (downloadSource) => agentPolicyService.bumpAllAgentPoliciesForDownloadSource(esClient, downloadSource.id), { - concurrency: 20, + concurrency: MAX_CONCURRENT_AGENT_POLICIES_OPERATIONS_20, } ); } diff --git a/x-pack/plugins/fleet/server/services/agent_policy.ts b/x-pack/plugins/fleet/server/services/agent_policy.ts index 21614d2a97481..eed9b058ad03f 100644 --- a/x-pack/plugins/fleet/server/services/agent_policy.ts +++ b/x-pack/plugins/fleet/server/services/agent_policy.ts @@ -97,6 +97,11 @@ import type { FullAgentConfigMap } from '../../common/types/models/agent_cm'; import { fullAgentConfigMapToYaml } from '../../common/services/agent_cm_to_yaml'; +import { + MAX_CONCURRENT_AGENT_POLICIES_OPERATIONS, + MAX_CONCURRENT_AGENT_POLICIES_OPERATIONS_20, +} from '../constants'; + import { appContextService } from '.'; import { mapAgentPolicySavedObjectToAgentPolicy } from './agent_policies/utils'; @@ -550,7 +555,7 @@ class AgentPolicyService { } return agentPolicy; }, - { concurrency: 50 } + { concurrency: MAX_CONCURRENT_AGENT_POLICIES_OPERATIONS } ); const result = agentPolicies.filter( @@ -657,7 +662,7 @@ class AgentPolicyService { return agentPolicy; }, - { concurrency: 50 } + { concurrency: MAX_CONCURRENT_AGENT_POLICIES_OPERATIONS } ); } @@ -955,7 +960,7 @@ class AgentPolicyService { ); }, { - concurrency: 50, + concurrency: MAX_CONCURRENT_AGENT_POLICIES_OPERATIONS, } ); await pMap( @@ -970,7 +975,7 @@ class AgentPolicyService { }); }, { - concurrency: 50, + concurrency: MAX_CONCURRENT_AGENT_POLICIES_OPERATIONS, } ); } @@ -1014,7 +1019,7 @@ class AgentPolicyService { } ), { - concurrency: 50, + concurrency: MAX_CONCURRENT_AGENT_POLICIES_OPERATIONS, } ); } @@ -1083,7 +1088,7 @@ class AgentPolicyService { this.triggerAgentPolicyUpdatedEvent(esClient, 'updated', policy.id, { spaceId: policy.namespaces?.[0], }), - { concurrency: 50 } + { concurrency: MAX_CONCURRENT_AGENT_POLICIES_OPERATIONS } ); } @@ -1352,7 +1357,7 @@ class AgentPolicyService { agentPolicy: agentPolicies?.find((policy) => policy.id === agentPolicyId), }), { - concurrency: 20, + concurrency: MAX_CONCURRENT_AGENT_POLICIES_OPERATIONS_20, } ); @@ -1423,27 +1428,29 @@ class AgentPolicyService { ); } - await Promise.all( - fleetServerPolicies - .filter((fleetServerPolicy) => { - const policy = policiesMap[fleetServerPolicy.policy_id]; - return ( - !policy.schema_version || lt(policy.schema_version, FLEET_AGENT_POLICIES_SCHEMA_VERSION) - ); - }) - .map((fleetServerPolicy) => - // There are some potential performance concerns around using `agentPolicyService.update` in this context. - // This could potentially be a bottleneck in environments with several thousand agent policies being deployed here. - agentPolicyService.update( - soClient, - esClient, - fleetServerPolicy.policy_id, - { - schema_version: FLEET_AGENT_POLICIES_SCHEMA_VERSION, - }, - { force: true } - ) - ) + const filteredFleetServerPolicies = fleetServerPolicies.filter((fleetServerPolicy) => { + const policy = policiesMap[fleetServerPolicy.policy_id]; + return ( + !policy.schema_version || lt(policy.schema_version, FLEET_AGENT_POLICIES_SCHEMA_VERSION) + ); + }); + await pMap( + filteredFleetServerPolicies, + (fleetServerPolicy) => + // There are some potential performance concerns around using `agentPolicyService.update` in this context. + // This could potentially be a bottleneck in environments with several thousand agent policies being deployed here. + agentPolicyService.update( + soClient, + esClient, + fleetServerPolicy.policy_id, + { + schema_version: FLEET_AGENT_POLICIES_SCHEMA_VERSION, + }, + { force: true } + ), + { + concurrency: MAX_CONCURRENT_AGENT_POLICIES_OPERATIONS, + } ); } @@ -1589,7 +1596,7 @@ class AgentPolicyService { } ), { - concurrency: 50, + concurrency: MAX_CONCURRENT_AGENT_POLICIES_OPERATIONS, } ); } @@ -1890,7 +1897,7 @@ class AgentPolicyService { return { integrationPolicyName: pkgPolicy?.name, id: pkgPolicy?.output_id ?? '' }; }, { - concurrency: 20, + concurrency: MAX_CONCURRENT_AGENT_POLICIES_OPERATIONS_20, } ); } @@ -1923,7 +1930,7 @@ class AgentPolicyService { return { agentPolicyId: agentPolicy.id, ...output }; }, { - concurrency: 50, + concurrency: MAX_CONCURRENT_AGENT_POLICIES_OPERATIONS, } ); return allOutputs; diff --git a/x-pack/plugins/fleet/server/services/agents/actions.ts b/x-pack/plugins/fleet/server/services/agents/actions.ts index f0dcd9a1ac62d..f2faf26fd96af 100644 --- a/x-pack/plugins/fleet/server/services/agents/actions.ts +++ b/x-pack/plugins/fleet/server/services/agents/actions.ts @@ -8,6 +8,7 @@ import { v4 as uuidv4 } from 'uuid'; import type { ElasticsearchClient, SavedObjectsClientContract } from '@kbn/core/server'; import apm from 'elastic-apm-node'; +import pMap from 'p-map'; import { partition } from 'lodash'; @@ -33,6 +34,8 @@ import { getAgentIdsForAgentPolicies } from '../agent_policies/agent_policies_to import { getCurrentNamespace } from '../spaces/get_current_namespace'; import { addNamespaceFilteringToQuery } from '../spaces/query_namespaces_filtering'; +import { MAX_CONCURRENT_CREATE_ACTIONS } from '../../constants'; + import { bulkUpdateAgents } from './crud'; const ONE_MONTH_IN_MS = 2592000000; @@ -110,40 +113,47 @@ export async function bulkCreateAgentActions( } const messageSigningService = appContextService.getMessageSigningService(); - await esClient.bulk({ - index: AGENT_ACTIONS_INDEX, - body: await Promise.all( - actions.flatMap(async (action) => { - const body: FleetServerAgentAction = { - '@timestamp': new Date().toISOString(), - expiration: action.expiration ?? new Date(Date.now() + ONE_MONTH_IN_MS).toISOString(), - start_time: action.start_time, - rollout_duration_seconds: action.rollout_duration_seconds, - agents: action.agents, - action_id: action.id, - data: action.data, - type: action.type, - traceparent: apm.currentTraceparent, - }; - if (SIGNED_ACTIONS.has(action.type) && messageSigningService) { - const signedBody = await messageSigningService.sign(body); - body.signed = { - data: signedBody.data.toString('base64'), - signature: signedBody.signature, - }; - } + const fleetServerAgentActions = await pMap( + actions, + async (action) => { + const body: FleetServerAgentAction = { + '@timestamp': new Date().toISOString(), + expiration: action.expiration ?? new Date(Date.now() + ONE_MONTH_IN_MS).toISOString(), + start_time: action.start_time, + rollout_duration_seconds: action.rollout_duration_seconds, + agents: action.agents, + action_id: action.id, + data: action.data, + type: action.type, + traceparent: apm.currentTraceparent, + }; + + if (SIGNED_ACTIONS.has(action.type) && messageSigningService) { + const signedBody = await messageSigningService.sign(body); + body.signed = { + data: signedBody.data.toString('base64'), + signature: signedBody.signature, + }; + } - return [ - { - create: { - _id: action.id, - }, + return [ + { + create: { + _id: action.id, }, - body, - ]; - }) - ), + }, + body, + ].flat(); + }, + { + concurrency: MAX_CONCURRENT_CREATE_ACTIONS, + } + ); + + await esClient.bulk({ + index: AGENT_ACTIONS_INDEX, + body: fleetServerAgentActions, }); for (const action of actions) { diff --git a/x-pack/plugins/fleet/server/services/epm/elasticsearch/datastream_ilm/install.ts b/x-pack/plugins/fleet/server/services/epm/elasticsearch/datastream_ilm/install.ts index 6a14c1c301aa8..eafda9a99e4fc 100644 --- a/x-pack/plugins/fleet/server/services/epm/elasticsearch/datastream_ilm/install.ts +++ b/x-pack/plugins/fleet/server/services/epm/elasticsearch/datastream_ilm/install.ts @@ -6,6 +6,7 @@ */ import type { ElasticsearchClient, Logger, SavedObjectsClientContract } from '@kbn/core/server'; +import pMap from 'p-map'; import { ElasticsearchAssetType, @@ -18,6 +19,8 @@ import { getAssetFromAssetsMap } from '../../archive'; import { getESAssetMetadata } from '../meta'; import { retryTransientEsErrors } from '../retry'; +import { MAX_CONCURRENT_DATASTREAMS_ILM_OPERATIONS } from '../../../../constants'; + import { deleteIlms } from './remove'; interface IlmInstallation { @@ -111,11 +114,15 @@ export const installIlmForDataStream = async ( } ); - const installationPromises = ilmInstallations.map(async (ilmInstallation) => { - return handleIlmInstall({ esClient, ilmInstallation, logger }); - }); - - installedIlms = await Promise.all(installationPromises).then((results) => results.flat()); + installedIlms = await pMap( + ilmInstallations, + async (ilmInstallation) => { + return handleIlmInstall({ esClient, ilmInstallation, logger }); + }, + { + concurrency: MAX_CONCURRENT_DATASTREAMS_ILM_OPERATIONS, + } + ).then((results) => results.flat()); } return { installedIlms, esReferences }; diff --git a/x-pack/plugins/fleet/server/services/epm/elasticsearch/datastream_ilm/remove.ts b/x-pack/plugins/fleet/server/services/epm/elasticsearch/datastream_ilm/remove.ts index 331088d195d0b..b8f4849934757 100644 --- a/x-pack/plugins/fleet/server/services/epm/elasticsearch/datastream_ilm/remove.ts +++ b/x-pack/plugins/fleet/server/services/epm/elasticsearch/datastream_ilm/remove.ts @@ -7,9 +7,17 @@ import type { ElasticsearchClient } from '@kbn/core/server'; +import pMap from 'p-map'; + +import { appContextService } from '../../../app_context'; +import { MAX_CONCURRENT_ILM_POLICIES_OPERATIONS } from '../../../../constants'; + export const deleteIlms = async (esClient: ElasticsearchClient, ilmPolicyIds: string[]) => { - await Promise.all( - ilmPolicyIds.map(async (ilmPolicyId) => { + const logger = appContextService.getLogger(); + + await pMap( + ilmPolicyIds, + async (ilmPolicyId) => { await esClient.transport.request( { method: 'DELETE', @@ -19,6 +27,10 @@ export const deleteIlms = async (esClient: ElasticsearchClient, ilmPolicyIds: st ignore: [404, 400], } ); - }) + logger.debug(`Deleted ilm policy with id: ${ilmPolicyId}`); + }, + { + concurrency: MAX_CONCURRENT_ILM_POLICIES_OPERATIONS, + } ); }; diff --git a/x-pack/plugins/fleet/server/services/epm/elasticsearch/ilm/install.ts b/x-pack/plugins/fleet/server/services/epm/elasticsearch/ilm/install.ts index 6596650a94c53..1203ec02ba9ac 100644 --- a/x-pack/plugins/fleet/server/services/epm/elasticsearch/ilm/install.ts +++ b/x-pack/plugins/fleet/server/services/epm/elasticsearch/ilm/install.ts @@ -6,6 +6,7 @@ */ import type { ElasticsearchClient, Logger, SavedObjectsClientContract } from '@kbn/core/server'; +import pMap from 'p-map'; import type { EsAssetReference } from '../../../../types'; @@ -16,6 +17,7 @@ import { getESAssetMetadata } from '../meta'; import { retryTransientEsErrors } from '../retry'; import { PackageInvalidArchiveError } from '../../../../errors'; import type { PackageInstallContext } from '../../../../../common/types'; +import { MAX_CONCURRENT_ILM_POLICIES_OPERATIONS } from '../../../../constants'; export async function installILMPolicy( packageInstallContext: PackageInstallContext, @@ -48,8 +50,9 @@ export async function installILMPolicy( })), }); - await Promise.all( - ilmPolicies.map(async (policy) => { + await pMap( + ilmPolicies, + async (policy) => { try { await retryTransientEsErrors( () => @@ -63,7 +66,10 @@ export async function installILMPolicy( } catch (err) { throw new PackageInvalidArchiveError(`Couldn't install ilm policies: ${err.message}`); } - }) + }, + { + concurrency: MAX_CONCURRENT_ILM_POLICIES_OPERATIONS, + } ); return esReferences; diff --git a/x-pack/plugins/fleet/server/services/epm/elasticsearch/ingest_pipeline/remove.ts b/x-pack/plugins/fleet/server/services/epm/elasticsearch/ingest_pipeline/remove.ts index aab876652756c..242365d5cc214 100644 --- a/x-pack/plugins/fleet/server/services/epm/elasticsearch/ingest_pipeline/remove.ts +++ b/x-pack/plugins/fleet/server/services/epm/elasticsearch/ingest_pipeline/remove.ts @@ -7,11 +7,14 @@ import type { ElasticsearchClient, SavedObjectsClientContract } from '@kbn/core/server'; +import pMap from 'p-map'; + import { appContextService } from '../../..'; import { ElasticsearchAssetType } from '../../../../types'; import { FleetError } from '../../../../errors'; import type { EsAssetReference } from '../../../../../common/types'; import { updateEsAssetReferences } from '../../packages/es_assets_reference'; +import { MAX_CONCURRENT_PIPELINES_DELETIONS } from '../../../../constants'; export const deletePreviousPipelines = async ( esClient: ElasticsearchClient, @@ -26,10 +29,15 @@ export const deletePreviousPipelines = async ( type === ElasticsearchAssetType.ingestPipeline && id.includes(previousPkgVersion) ); try { - await Promise.all( - installedPipelines.map(({ type, id }) => { + await pMap( + installedPipelines, + ({ type, id }) => { + logger.debug(`Deleting pipeline with id: ${id}`); return deletePipeline(esClient, id); - }) + }, + { + concurrency: MAX_CONCURRENT_PIPELINES_DELETIONS, + } ); } catch (e) { logger.error(e); diff --git a/x-pack/plugins/fleet/server/services/epm/elasticsearch/ml_model/remove.ts b/x-pack/plugins/fleet/server/services/epm/elasticsearch/ml_model/remove.ts index 3abd19bd8035e..7852787da0d76 100644 --- a/x-pack/plugins/fleet/server/services/epm/elasticsearch/ml_model/remove.ts +++ b/x-pack/plugins/fleet/server/services/epm/elasticsearch/ml_model/remove.ts @@ -7,17 +7,24 @@ import type { ElasticsearchClient } from '@kbn/core/server'; +import pMap from 'p-map'; + import { appContextService } from '../../../app_context'; +import { MAX_CONCURRENT_ML_MODELS_OPERATIONS } from '../../../../constants'; export const deleteMlModel = async (esClient: ElasticsearchClient, mlModelIds: string[]) => { const logger = appContextService.getLogger(); if (mlModelIds.length) { logger.info(`Deleting currently installed ml model ids ${mlModelIds}`); } - await Promise.all( - mlModelIds.map(async (modelId) => { + await pMap( + mlModelIds, + async (modelId) => { await esClient.ml.deleteTrainedModel({ model_id: modelId }, { ignore: [404] }); logger.info(`Deleted: ${modelId}`); - }) + }, + { + concurrency: MAX_CONCURRENT_ML_MODELS_OPERATIONS, + } ); }; 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 2a17768ac1f9c..a15e8cb71923c 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 @@ -8,6 +8,7 @@ import { merge, concat, uniqBy, omit } from 'lodash'; import Boom from '@hapi/boom'; import type { ElasticsearchClient, Logger } from '@kbn/core/server'; +import pMap from 'p-map'; import type { IndicesCreateRequest, @@ -38,6 +39,7 @@ import { PACKAGE_TEMPLATE_SUFFIX, USER_SETTINGS_TEMPLATE_SUFFIX, STACK_COMPONENT_TEMPLATES, + MAX_CONCURRENT_COMPONENT_TEMPLATES, } from '../../../../constants'; import { getESAssetMetadata } from '../meta'; import { retryTransientEsErrors } from '../retry'; @@ -103,15 +105,18 @@ export const prepareToInstallTemplates = ( await installPreBuiltComponentTemplates(packageInstallContext, esClient, logger); await installPreBuiltTemplates(packageInstallContext, esClient, logger); - await Promise.all( - templates.map((template) => + await pMap( + templates, + (template) => installComponentAndIndexTemplateForDataStream({ esClient, logger, componentTemplates: template.componentTemplates, indexTemplate: template.indexTemplate, - }) - ) + }), + { + concurrency: MAX_CONCURRENT_COMPONENT_TEMPLATES, + } ); return templates.map((template) => template.indexTemplate); @@ -125,32 +130,37 @@ const installPreBuiltTemplates = async ( logger: Logger ) => { const templatePaths = packageInstallContext.paths.filter((path) => isTemplate(path)); - const templateInstallPromises = templatePaths.map(async (path) => { - const { file } = getPathParts(path); - const templateName = file.substr(0, file.lastIndexOf('.')); - const content = JSON.parse( - getAssetFromAssetsMap(packageInstallContext.assetsMap, path).toString('utf8') - ); - - const esClientParams = { name: templateName, body: content }; - const esClientRequestOptions = { ignore: [404] }; - - if (Object.hasOwn(content, 'template') || Object.hasOwn(content, 'composed_of')) { - // Template is v2 - return retryTransientEsErrors( - () => esClient.indices.putIndexTemplate(esClientParams, esClientRequestOptions), - { logger } - ); - } else { - // template is V1 - return retryTransientEsErrors( - () => esClient.indices.putTemplate(esClientParams, esClientRequestOptions), - { logger } - ); - } - }); try { - return await Promise.all(templateInstallPromises); + await pMap( + templatePaths, + async (path) => { + const { file } = getPathParts(path); + const templateName = file.substr(0, file.lastIndexOf('.')); + const content = JSON.parse( + getAssetFromAssetsMap(packageInstallContext.assetsMap, path).toString('utf8') + ); + + const esClientParams = { name: templateName, body: content }; + const esClientRequestOptions = { ignore: [404] }; + + if (Object.hasOwn(content, 'template') || Object.hasOwn(content, 'composed_of')) { + // Template is v2 + return retryTransientEsErrors( + () => esClient.indices.putIndexTemplate(esClientParams, esClientRequestOptions), + { logger } + ); + } else { + // template is V1 + return retryTransientEsErrors( + () => esClient.indices.putTemplate(esClientParams, esClientRequestOptions), + { logger } + ); + } + }, + { + concurrency: MAX_CONCURRENT_COMPONENT_TEMPLATES, + } + ); } catch (e) { throw new Boom.Boom(`Error installing prebuilt index templates ${e.message}`, { statusCode: 400, @@ -164,26 +174,30 @@ const installPreBuiltComponentTemplates = async ( logger: Logger ) => { const templatePaths = packageInstallContext.paths.filter((path) => isComponentTemplate(path)); - const templateInstallPromises = templatePaths.map(async (path) => { - const { file } = getPathParts(path); - const templateName = file.substr(0, file.lastIndexOf('.')); - const content = JSON.parse( - getAssetFromAssetsMap(packageInstallContext.assetsMap, path).toString('utf8') - ); - - const esClientParams = { - name: templateName, - body: content, - }; - - return retryTransientEsErrors( - () => esClient.cluster.putComponentTemplate(esClientParams, { ignore: [404] }), - { logger } - ); - }); - try { - return await Promise.all(templateInstallPromises); + await pMap( + templatePaths, + async (path) => { + const { file } = getPathParts(path); + const templateName = file.substr(0, file.lastIndexOf('.')); + const content = JSON.parse( + getAssetFromAssetsMap(packageInstallContext.assetsMap, path).toString('utf8') + ); + + const esClientParams = { + name: templateName, + body: content, + }; + + return retryTransientEsErrors( + () => esClient.cluster.putComponentTemplate(esClientParams, { ignore: [404] }), + { logger } + ); + }, + { + concurrency: MAX_CONCURRENT_COMPONENT_TEMPLATES, + } + ); } catch (e) { throw new Boom.Boom(`Error installing prebuilt component templates ${e.message}`, { statusCode: 400, @@ -450,8 +464,9 @@ async function installDataStreamComponentTemplates({ logger: Logger; componentTemplates: TemplateMap; }) { - await Promise.all( - Object.entries(componentTemplates).map(async ([name, body]) => { + await pMap( + Object.entries(componentTemplates), + async ([name, body]) => { // @custom component template should be lazily created by user if (isUserSettingsTemplate(name)) { return; @@ -459,7 +474,10 @@ async function installDataStreamComponentTemplates({ const { clusterPromise } = putComponentTemplate(esClient, logger, { body, name }); return clusterPromise; - }) + }, + { + concurrency: MAX_CONCURRENT_COMPONENT_TEMPLATES, + } ); } @@ -467,10 +485,12 @@ export async function ensureDefaultComponentTemplates( esClient: ElasticsearchClient, logger: Logger ) { - return Promise.all( - FLEET_COMPONENT_TEMPLATES.map(({ name, body }) => - ensureComponentTemplate(esClient, logger, name, body) - ) + return await pMap( + FLEET_COMPONENT_TEMPLATES, + ({ name, body }) => ensureComponentTemplate(esClient, logger, name, body), + { + concurrency: MAX_CONCURRENT_COMPONENT_TEMPLATES, + } ); } 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 bb38480fd66b7..b6d357193b14d 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 @@ -19,6 +19,7 @@ import { FLEET_EVENT_INGESTED_COMPONENT_TEMPLATE_NAME, STACK_COMPONENT_TEMPLATE_LOGS_MAPPINGS, } from '../../../../constants/fleet_es_assets'; +import { MAX_CONCURRENT_DATASTREAM_OPERATIONS } from '../../../../constants'; import type { Field, Fields } from '../../fields/field'; import type { @@ -931,10 +932,15 @@ const queryDataStreamsFromTemplates = async ( esClient: ElasticsearchClient, templates: IndexTemplateEntry[] ): Promise => { - const dataStreamPromises = templates.map((template) => { - return getDataStreams(esClient, template); - }); - const dataStreamObjects = await Promise.all(dataStreamPromises); + const dataStreamObjects = await pMap( + templates, + (template) => { + return getDataStreams(esClient, template); + }, + { + concurrency: MAX_CONCURRENT_DATASTREAM_OPERATIONS, + } + ); return dataStreamObjects.filter(isCurrentDataStream).flat(); }; @@ -997,8 +1003,7 @@ const updateAllDataStreams = async ( }); }, { - // Limit concurrent putMapping/rollover requests to avoid overwhelming ES cluster - concurrency: 20, + concurrency: MAX_CONCURRENT_DATASTREAM_OPERATIONS, } ); }; diff --git a/x-pack/plugins/fleet/server/services/epm/elasticsearch/transform/install.ts b/x-pack/plugins/fleet/server/services/epm/elasticsearch/transform/install.ts index cbdde6feee64c..85ae293455c9e 100644 --- a/x-pack/plugins/fleet/server/services/epm/elasticsearch/transform/install.ts +++ b/x-pack/plugins/fleet/server/services/epm/elasticsearch/transform/install.ts @@ -10,6 +10,7 @@ import { errors } from '@elastic/elasticsearch'; import { load } from 'js-yaml'; import { isPopulatedObject } from '@kbn/ml-is-populated-object'; import { uniqBy } from 'lodash'; +import pMap from 'p-map'; import type { HTTPAuthorizationHeader } from '../../../../../common/http_authorization_header'; @@ -44,6 +45,8 @@ import { getInstallation } from '../../packages'; import { retryTransientEsErrors } from '../retry'; import { isUserSettingsTemplate } from '../template/utils'; +import { MAX_CONCURRENT_TRANSFORMS_OPERATIONS } from '../../../../constants'; + import { deleteTransforms } from './remove'; import { getDestinationIndexAliases } from './transform_utils'; import { loadMappingForTransform } from './mappings'; @@ -573,17 +576,21 @@ const installTransformsAssets = async ( } } else { // Else, create & start all the transforms at once for speed - const transformsPromises = transforms.map(async (transform) => { - return handleTransformInstall({ - esClient, - logger, - transform, - startTransform: transformsSpecifications.get(transform.transformModuleId)?.get('start'), - secondaryAuth: transform.runAsKibanaSystem !== false ? undefined : secondaryAuth, - }); - }); - - installedTransforms = await Promise.all(transformsPromises).then((results) => results.flat()); + installedTransforms = await pMap( + transforms, + async (transform) => { + return handleTransformInstall({ + esClient, + logger, + transform, + startTransform: transformsSpecifications.get(transform.transformModuleId)?.get('start'), + secondaryAuth: transform.runAsKibanaSystem !== false ? undefined : secondaryAuth, + }); + }, + { + concurrency: MAX_CONCURRENT_TRANSFORMS_OPERATIONS, + } + ).then((results) => results.flat()); } // If user does not have sufficient permissions to start the transforms, diff --git a/x-pack/plugins/fleet/server/services/epm/elasticsearch/transform/reauthorize.ts b/x-pack/plugins/fleet/server/services/epm/elasticsearch/transform/reauthorize.ts index d1a492cb213a9..8d53a952608fa 100644 --- a/x-pack/plugins/fleet/server/services/epm/elasticsearch/transform/reauthorize.ts +++ b/x-pack/plugins/fleet/server/services/epm/elasticsearch/transform/reauthorize.ts @@ -10,6 +10,7 @@ import type { Logger } from '@kbn/logging'; import type { SavedObjectsClientContract } from '@kbn/core-saved-objects-api-server'; import { sortBy, uniqBy } from 'lodash'; +import pMap from 'p-map'; import { isPopulatedObject } from '@kbn/ml-is-populated-object'; import type { ErrorResponseBase } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; @@ -19,6 +20,7 @@ import type { Installation } from '../../../../../common'; import { ElasticsearchAssetType, PACKAGES_SAVED_OBJECT_TYPE } from '../../../../../common'; import { retryTransientEsErrors } from '../retry'; +import { MAX_CONCURRENT_TRANSFORMS_OPERATIONS } from '../../../../constants'; interface FleetTransformMetadata { fleet_transform_version?: string; @@ -119,8 +121,9 @@ export async function handleTransformReauthorizeAndStart({ ); } - const transformInfos = await Promise.all( - transforms.map(({ transformId }) => + const transformInfos = await pMap( + transforms, + ({ transformId }) => retryTransientEsErrors( () => esClient.transform.getTransform( @@ -130,8 +133,10 @@ export async function handleTransformReauthorizeAndStart({ { ...(secondaryAuth ? secondaryAuth : {}), ignore: [404] } ), { logger, additionalResponseStatuses: [400] } - ) - ) + ), + { + concurrency: MAX_CONCURRENT_TRANSFORMS_OPERATIONS, + } ); const transformsMetadata: FleetTransformMetadata[] = transformInfos @@ -168,17 +173,20 @@ export async function handleTransformReauthorizeAndStart({ } } else { // Else, create & start all the transforms at once for speed - const transformsPromises = transformsMetadata.map(async ({ transformId, ...meta }) => { - return await reauthorizeAndStartTransform({ - esClient, - logger, - transformId, - secondaryAuth, - meta: { ...meta, last_authorized_by: username }, - }); - }); - - authorizedTransforms = await Promise.all(transformsPromises).then((results) => results.flat()); + authorizedTransforms = await pMap( + transformsMetadata, + async ({ transformId, ...meta }) => + reauthorizeAndStartTransform({ + esClient, + logger, + transformId, + secondaryAuth, + meta: { ...meta, last_authorized_by: username }, + }), + { + concurrency: MAX_CONCURRENT_TRANSFORMS_OPERATIONS, + } + ).then((results) => results.flat()); } const so = await savedObjectsClient.get(PACKAGES_SAVED_OBJECT_TYPE, pkgName); diff --git a/x-pack/plugins/fleet/server/services/epm/elasticsearch/transform/remove.ts b/x-pack/plugins/fleet/server/services/epm/elasticsearch/transform/remove.ts index 4149d15899166..8a2d5cd13c59d 100644 --- a/x-pack/plugins/fleet/server/services/epm/elasticsearch/transform/remove.ts +++ b/x-pack/plugins/fleet/server/services/epm/elasticsearch/transform/remove.ts @@ -6,6 +6,7 @@ */ import type { ElasticsearchClient, SavedObjectsClientContract } from '@kbn/core/server'; +import pMap from 'p-map'; import type { SecondaryAuthorizationHeader } from '../../../../../common/types/models/transform_api_key'; import { ElasticsearchAssetType } from '../../../../types'; @@ -14,6 +15,7 @@ import { PACKAGES_SAVED_OBJECT_TYPE } from '../../../../../common/constants'; import { appContextService } from '../../../app_context'; import { retryTransientEsErrors } from '../retry'; +import { MAX_CONCURRENT_TRANSFORMS_OPERATIONS } from '../../../../constants'; export const stopTransforms = async (transformIds: string[], esClient: ElasticsearchClient) => { for (const transformId of transformIds) { @@ -34,8 +36,10 @@ export const deleteTransforms = async ( if (transformIds.length) { logger.info(`Deleting currently installed transform ids ${transformIds}`); } - await Promise.all( - transformIds.map(async (transformId) => { + + await pMap( + transformIds, + async (transformId) => { await stopTransforms([transformId], esClient); await retryTransientEsErrors(() => esClient.transform.deleteTransform( @@ -48,7 +52,10 @@ export const deleteTransforms = async ( ) ); logger.info(`Deleted: ${transformId}`); - }) + }, + { + concurrency: MAX_CONCURRENT_TRANSFORMS_OPERATIONS, + } ); }; diff --git a/x-pack/plugins/fleet/server/services/epm/kibana/index_pattern/install.ts b/x-pack/plugins/fleet/server/services/epm/kibana/index_pattern/install.ts index 3ae1c4a6cffba..3ecdfe02319a9 100644 --- a/x-pack/plugins/fleet/server/services/epm/kibana/index_pattern/install.ts +++ b/x-pack/plugins/fleet/server/services/epm/kibana/index_pattern/install.ts @@ -6,10 +6,12 @@ */ import type { SavedObjectsClientContract } from '@kbn/core/server'; +import pMap from 'p-map'; import { dataTypes, installationStatuses } from '../../../../../common/constants'; import { appContextService } from '../../..'; import { getPackageSavedObjects } from '../../packages/get'; +import { MAX_CONCURRENT_INDEX_PATTERN_OPERATIONS } from '../../../../constants'; const INDEX_PATTERN_SAVED_OBJECT_TYPE = 'index-pattern'; export const indexPatternTypes = [dataTypes.Logs, dataTypes.Metrics]; @@ -72,9 +74,9 @@ export async function removeUnusedIndexPatterns(savedObjectsClient: SavedObjects // eslint-disable-next-line @typescript-eslint/naming-convention const idsToDelete = resolvedObjects.map(({ saved_object }) => saved_object.id); - - return Promise.all( - idsToDelete.map(async (id) => { + await pMap( + idsToDelete, + async (id) => { try { logger.debug(`deleting index pattern ${id}`); await savedObjectsClient.delete(INDEX_PATTERN_SAVED_OBJECT_TYPE, id); @@ -83,6 +85,9 @@ export async function removeUnusedIndexPatterns(savedObjectsClient: SavedObjects logger.debug(`Non fatal error encountered deleting index pattern ${id} : ${err}`); } return; - }) + }, + { + concurrency: MAX_CONCURRENT_INDEX_PATTERN_OPERATIONS, + } ); } diff --git a/x-pack/plugins/fleet/server/services/epm/package_service.mock.ts b/x-pack/plugins/fleet/server/services/epm/package_service.mock.ts index eeaa80b0c9449..e72b218ab1fcc 100644 --- a/x-pack/plugins/fleet/server/services/epm/package_service.mock.ts +++ b/x-pack/plugins/fleet/server/services/epm/package_service.mock.ts @@ -17,6 +17,7 @@ const createClientMock = (): jest.Mocked => ({ fetchFindLatestPackage: jest.fn(), readBundledPackage: jest.fn(), getAgentPolicyConfigYAML: jest.fn(), + getLatestPackageInfo: jest.fn(), getPackage: jest.fn(), getPackageFieldsMetadata: jest.fn(), getPackages: jest.fn(), diff --git a/x-pack/plugins/fleet/server/services/epm/package_service.test.ts b/x-pack/plugins/fleet/server/services/epm/package_service.test.ts index 479d355c00e68..ea7586b9ebd78 100644 --- a/x-pack/plugins/fleet/server/services/epm/package_service.test.ts +++ b/x-pack/plugins/fleet/server/services/epm/package_service.test.ts @@ -43,6 +43,7 @@ const testKeys = [ 'getInstallation', 'ensureInstalledPackage', 'fetchFindLatestPackage', + 'getLatestPackageInfo', 'getPackage', 'getPackageFieldsMetadata', 'reinstallEsAssets', @@ -112,6 +113,23 @@ function getTest( }; break; case testKeys[3]: + test = { + method: mocks.packageClient.getLatestPackageInfo.bind(mocks.packageClient), + args: ['package name'], + spy: jest.spyOn(epmPackagesGet, 'getPackageInfo'), + spyArgs: [ + { + pkgName: 'package name', + pkgVersion: '', + savedObjectsClient: mocks.soClient, + prerelease: undefined, + }, + ], + spyResponse: { name: 'getLatestPackageInfo test' }, + expectedReturnValue: { name: 'getLatestPackageInfo test' }, + }; + break; + case testKeys[4]: test = { method: mocks.packageClient.getPackage.bind(mocks.packageClient), args: ['package name', '8.0.0'], @@ -127,7 +145,7 @@ function getTest( }, }; break; - case testKeys[4]: + case testKeys[5]: test = { method: mocks.packageClient.getPackageFieldsMetadata.bind(mocks.packageClient), args: [{ packageName: 'package_name', datasetName: 'dataset_name' }], @@ -141,7 +159,7 @@ function getTest( }, }; break; - case testKeys[5]: + case testKeys[6]: const pkg: InstallablePackage = { format_version: '1.0.0', name: 'package name', @@ -187,7 +205,7 @@ function getTest( ], }; break; - case testKeys[6]: + case testKeys[7]: const bundledPackage = { name: 'package name', version: '8.0.0', diff --git a/x-pack/plugins/fleet/server/services/epm/package_service.ts b/x-pack/plugins/fleet/server/services/epm/package_service.ts index a097db584b460..782aeffb6a85c 100644 --- a/x-pack/plugins/fleet/server/services/epm/package_service.ts +++ b/x-pack/plugins/fleet/server/services/epm/package_service.ts @@ -56,6 +56,7 @@ import { getPackages, installPackage, getTemplateInputs, + getPackageInfo, } from './packages'; import { generatePackageInfoFromArchiveBuffer } from './archive'; import { getEsPackage } from './archive/storage'; @@ -113,6 +114,11 @@ export interface PackageClient { options?: Parameters['1'] ): ReturnType; + getLatestPackageInfo( + packageName: string, + prerelease?: boolean + ): ReturnType; + getPackages(params?: { excludeInstallStatus?: false; category?: CategoryId; @@ -328,6 +334,16 @@ class PackageClientImpl implements PackageClient { return getPackageFieldsMetadata(params, options); } + public async getLatestPackageInfo(packageName: string, prerelease?: boolean) { + await this.#runPreflight(READ_PACKAGE_INFO_AUTHZ); + return getPackageInfo({ + savedObjectsClient: this.internalSoClient, + pkgName: packageName, + pkgVersion: '', + prerelease, + }); + } + public async getPackages(params?: { excludeInstallStatus?: false; category?: CategoryId; diff --git a/x-pack/plugins/fleet/server/services/epm/packages/get.ts b/x-pack/plugins/fleet/server/services/epm/packages/get.ts index 2ab0856063367..5b0e3df279cdc 100644 --- a/x-pack/plugins/fleet/server/services/epm/packages/get.ts +++ b/x-pack/plugins/fleet/server/services/epm/packages/get.ts @@ -39,7 +39,10 @@ import type { PackageSpecManifest, AssetsMap, } from '../../../../common/types'; -import { PACKAGES_SAVED_OBJECT_TYPE } from '../../../constants'; +import { + PACKAGES_SAVED_OBJECT_TYPE, + MAX_CONCURRENT_EPM_PACKAGES_INSTALLATIONS, +} from '../../../constants'; import type { ArchivePackage, RegistryPackage, @@ -142,7 +145,7 @@ export async function getPackages( ); } }, - { concurrency: 10 } + { concurrency: MAX_CONCURRENT_EPM_PACKAGES_INSTALLATIONS } ) ).filter((p): p is Installable => p !== null); diff --git a/x-pack/plugins/fleet/server/services/epm/packages/remove.ts b/x-pack/plugins/fleet/server/services/epm/packages/remove.ts index 84c8a8eb9e104..0557027a3c0a6 100644 --- a/x-pack/plugins/fleet/server/services/epm/packages/remove.ts +++ b/x-pack/plugins/fleet/server/services/epm/packages/remove.ts @@ -17,10 +17,12 @@ import { SavedObjectsUtils, SavedObjectsErrorHelpers } from '@kbn/core/server'; import minVersion from 'semver/ranges/min-version'; import { chunk } from 'lodash'; +import pMap from 'p-map'; import { updateIndexSettings } from '../elasticsearch/index/update_settings'; import { + MAX_CONCURRENT_ES_ASSETS_OPERATIONS, PACKAGE_POLICY_SAVED_OBJECT_TYPE, PACKAGES_SAVED_OBJECT_TYPE, SO_SEARCH_LIMIT, @@ -209,29 +211,36 @@ async function bulkDeleteSavedObjects( } } -export function deleteESAssets( +export const deleteESAsset = async ( + installedObject: EsAssetReference, + esClient: ElasticsearchClient +): Promise => { + const { id, type } = installedObject; + const assetType = type as AssetType; + if (assetType === ElasticsearchAssetType.ingestPipeline) { + return deletePipeline(esClient, id); + } else if (assetType === ElasticsearchAssetType.indexTemplate) { + return deleteIndexTemplate(esClient, id); + } else if (assetType === ElasticsearchAssetType.componentTemplate) { + return deleteComponentTemplate(esClient, id); + } else if (assetType === ElasticsearchAssetType.transform) { + return deleteTransforms(esClient, [id], true); + } else if (assetType === ElasticsearchAssetType.dataStreamIlmPolicy) { + return deleteIlms(esClient, [id]); + } else if (assetType === ElasticsearchAssetType.ilmPolicy) { + return deleteIlms(esClient, [id]); + } else if (assetType === ElasticsearchAssetType.mlModel) { + return deleteMlModel(esClient, [id]); + } +}; + +export const deleteESAssets = ( installedObjects: EsAssetReference[], esClient: ElasticsearchClient -): Array> { - return installedObjects.map(async ({ id, type }) => { - const assetType = type as AssetType; - if (assetType === ElasticsearchAssetType.ingestPipeline) { - return deletePipeline(esClient, id); - } else if (assetType === ElasticsearchAssetType.indexTemplate) { - return deleteIndexTemplate(esClient, id); - } else if (assetType === ElasticsearchAssetType.componentTemplate) { - return deleteComponentTemplate(esClient, id); - } else if (assetType === ElasticsearchAssetType.transform) { - return deleteTransforms(esClient, [id], true); - } else if (assetType === ElasticsearchAssetType.dataStreamIlmPolicy) { - return deleteIlms(esClient, [id]); - } else if (assetType === ElasticsearchAssetType.ilmPolicy) { - return deleteIlms(esClient, [id]); - } else if (assetType === ElasticsearchAssetType.mlModel) { - return deleteMlModel(esClient, [id]); - } - }); -} +): Array> => { + return installedObjects.map((installedObject) => deleteESAsset(installedObject, esClient)); +}; + type Tuple = [EsAssetReference[], EsAssetReference[], EsAssetReference[], EsAssetReference[]]; export const splitESAssets = (installedEs: EsAssetReference[]) => { @@ -291,16 +300,24 @@ export async function deletePrerequisiteAssets( try { // must first unset any default pipeline associated with any existing indices // by setting empty string - await Promise.all( - indexAssets.map((asset) => updateIndexSettings(esClient, asset.id, { default_pipeline: '' })) + await pMap( + indexAssets, + (asset) => updateIndexSettings(esClient, asset.id, { default_pipeline: '' }), + { + concurrency: MAX_CONCURRENT_ES_ASSETS_OPERATIONS, + } ); // in case transform's destination index contains any pipeline, // we should delete the transforms first - await Promise.all(deleteESAssets(transformAssets, esClient)); + await pMap(transformAssets, (transformAsset) => deleteESAsset(transformAsset, esClient), { + concurrency: MAX_CONCURRENT_ES_ASSETS_OPERATIONS, + }); // then delete index templates and pipelines - await Promise.all(deleteESAssets(indexTemplatesAndPipelines, esClient)); + await pMap(indexTemplatesAndPipelines, (asset) => deleteESAsset(asset, esClient), { + concurrency: MAX_CONCURRENT_ES_ASSETS_OPERATIONS, + }); } catch (err) { // in the rollback case, partial installs are likely, so missing assets are not an error if (!SavedObjectsErrorHelpers.isNotFoundError(err)) { diff --git a/x-pack/plugins/fleet/server/services/files/index.ts b/x-pack/plugins/fleet/server/services/files/index.ts index c7a00ee597f62..0598155153ce6 100644 --- a/x-pack/plugins/fleet/server/services/files/index.ts +++ b/x-pack/plugins/fleet/server/services/files/index.ts @@ -8,6 +8,7 @@ import type { ElasticsearchClient } from '@kbn/core/server'; import type { SearchHit, UpdateByQueryResponse } from '@elastic/elasticsearch/lib/api/types'; import type { FileStatus } from '@kbn/files-plugin/common/types'; +import pMap from 'p-map'; import { FILE_STORAGE_DATA_INDEX_PATTERN, @@ -20,6 +21,8 @@ import { getFileMetadataIndexName } from '../../../common/services'; import { ES_SEARCH_LIMIT } from '../../../common/constants'; +import { MAX_CONCURRENT_AGENT_FILES_UPLOADS } from '../../constants'; + import { parseFileStorageIndex } from './utils'; /** @@ -145,14 +148,15 @@ export async function fileIdsWithoutChunksByIndex( * @param fileIdsByIndex * @param status */ -export function updateFilesStatus( +export async function updateFilesStatus( esClient: ElasticsearchClient, abortController: AbortController | undefined, fileIdsByIndex: FileIdsByIndex, status: FileStatus ): Promise { - return Promise.all( - Object.entries(fileIdsByIndex).map(([index, fileIds]) => { + return await pMap( + Object.entries(fileIdsByIndex), + ([index, fileIds]) => { return esClient .updateByQuery( { @@ -174,6 +178,9 @@ export function updateFilesStatus( Error.captureStackTrace(err); throw err; }); - }) + }, + { + concurrency: MAX_CONCURRENT_AGENT_FILES_UPLOADS, + } ); } diff --git a/x-pack/plugins/fleet/server/services/fleet_proxies.ts b/x-pack/plugins/fleet/server/services/fleet_proxies.ts index 4cfc81db50740..e60c15577bdc2 100644 --- a/x-pack/plugins/fleet/server/services/fleet_proxies.ts +++ b/x-pack/plugins/fleet/server/services/fleet_proxies.ts @@ -13,7 +13,11 @@ import type { import { omit } from 'lodash'; import pMap from 'p-map'; -import { FLEET_PROXY_SAVED_OBJECT_TYPE, SO_SEARCH_LIMIT } from '../constants'; +import { + FLEET_PROXY_SAVED_OBJECT_TYPE, + SO_SEARCH_LIMIT, + MAX_CONCURRENT_FLEET_PROXIES_OPERATIONS, +} from '../constants'; import { FleetProxyUnauthorizedError } from '../errors'; import type { DownloadSource, @@ -206,7 +210,7 @@ async function updateRelatedSavedObject( ...omit(fleetServerHost, 'id'), proxy_id: null, }), - { concurrency: 20 } + { concurrency: MAX_CONCURRENT_FLEET_PROXIES_OPERATIONS } ); await pMap( @@ -216,7 +220,7 @@ async function updateRelatedSavedObject( ...omit(output, 'id'), proxy_id: null, } as Partial), - { concurrency: 20 } + { concurrency: MAX_CONCURRENT_FLEET_PROXIES_OPERATIONS } ); await pMap(downloadSources, (downloadSource) => diff --git a/x-pack/plugins/fleet/server/services/output.ts b/x-pack/plugins/fleet/server/services/output.ts index ceecd29562fc9..0b30890ee566d 100644 --- a/x-pack/plugins/fleet/server/services/output.ts +++ b/x-pack/plugins/fleet/server/services/output.ts @@ -44,6 +44,7 @@ import { DEFAULT_OUTPUT_ID, OUTPUT_SAVED_OBJECT_TYPE, OUTPUT_HEALTH_DATA_STREAM, + MAX_CONCURRENT_BACKFILL_OUTPUTS_PRESETS, } from '../constants'; import { SO_SEARCH_LIMIT, @@ -1165,7 +1166,7 @@ class OutputService { await agentPolicyService.bumpAllAgentPoliciesForOutput(esClient, output.id); }, { - concurrency: 5, + concurrency: MAX_CONCURRENT_BACKFILL_OUTPUTS_PRESETS, } ); } diff --git a/x-pack/plugins/fleet/server/services/package_policy.ts b/x-pack/plugins/fleet/server/services/package_policy.ts index eac31bb980256..32ec4c90b4319 100644 --- a/x-pack/plugins/fleet/server/services/package_policy.ts +++ b/x-pack/plugins/fleet/server/services/package_policy.ts @@ -100,6 +100,11 @@ import type { } from '../types'; import type { ExternalCallback } from '..'; +import { + MAX_CONCURRENT_AGENT_POLICIES_OPERATIONS, + MAX_CONCURRENT_PACKAGE_ASSETS, +} from '../constants'; + import { createSoFindIterable } from './utils/create_so_find_iterable'; import type { FleetAuthzRouteConfig } from './security'; @@ -178,7 +183,7 @@ async function getPkgInfoAssetsMap({ pkgInfo, }); }, - { concurrency: 5 } + { concurrency: MAX_CONCURRENT_PACKAGE_ASSETS } ); return packageInfosandAssetsMap; @@ -2211,7 +2216,7 @@ class PackagePolicyClientImpl implements PackagePolicyClient { } }, { - concurrency: 50, + concurrency: MAX_CONCURRENT_AGENT_POLICIES_OPERATIONS, } ); await pMap( @@ -2231,7 +2236,7 @@ class PackagePolicyClientImpl implements PackagePolicyClient { ); }, { - concurrency: 50, + concurrency: MAX_CONCURRENT_AGENT_POLICIES_OPERATIONS, } ); } diff --git a/x-pack/plugins/fleet/server/services/preconfiguration/fleet_proxies.ts b/x-pack/plugins/fleet/server/services/preconfiguration/fleet_proxies.ts index 03787b8e6be65..d09494e52d30b 100644 --- a/x-pack/plugins/fleet/server/services/preconfiguration/fleet_proxies.ts +++ b/x-pack/plugins/fleet/server/services/preconfiguration/fleet_proxies.ts @@ -22,6 +22,8 @@ import { listFleetServerHostsForProxyId } from '../fleet_server_host'; import { agentPolicyService } from '../agent_policy'; import { outputService } from '../output'; +import { MAX_CONCURRENT_AGENT_POLICIES_OPERATIONS_20 } from '../../constants'; + export function getPreconfiguredFleetProxiesFromConfig(config?: FleetConfigType) { const { proxies: fleetProxiesFromConfig } = config; @@ -107,7 +109,7 @@ async function createOrUpdatePreconfiguredFleetProxies( outputs, (output) => agentPolicyService.bumpAllAgentPoliciesForOutput(esClient, output.id), { - concurrency: 20, + concurrency: MAX_CONCURRENT_AGENT_POLICIES_OPERATIONS_20, } ); await pMap( @@ -118,7 +120,7 @@ async function createOrUpdatePreconfiguredFleetProxies( fleetServerHost.id ), { - concurrency: 20, + concurrency: MAX_CONCURRENT_AGENT_POLICIES_OPERATIONS_20, } ); } diff --git a/x-pack/plugins/fleet/server/services/preconfiguration/outputs.ts b/x-pack/plugins/fleet/server/services/preconfiguration/outputs.ts index 714b16af5bcd2..f605df4680b31 100644 --- a/x-pack/plugins/fleet/server/services/preconfiguration/outputs.ts +++ b/x-pack/plugins/fleet/server/services/preconfiguration/outputs.ts @@ -11,6 +11,7 @@ import utils from 'node:util'; import type { ElasticsearchClient, SavedObjectsClientContract } from '@kbn/core/server'; import { isEqual } from 'lodash'; import { dump } from 'js-yaml'; +import pMap from 'p-map'; const pbkdf2Async = utils.promisify(crypto.pbkdf2); @@ -32,6 +33,8 @@ import { appContextService } from '../app_context'; import { isDifferent } from './utils'; +export const MAX_CONCURRENT_OUTPUTS_OPERATIONS = 50; + export function getPreconfiguredOutputFromConfig(config?: FleetConfigType) { const { outputs: outputsOrUndefined } = config; @@ -78,67 +81,69 @@ export async function createOrUpdatePreconfiguredOutputs( { ignoreNotFound: true } ); - await Promise.all( - outputs.map(async (output) => { - const existingOutput = existingOutputs.find((o) => o.id === output.id); + const updateOrConfigureOutput = async (output: PreconfiguredOutput) => { + const existingOutput = existingOutputs.find((o) => o.id === output.id); - const { id, config, ...outputData } = output; + const { id, config, ...outputData } = output; - const configYaml = config ? dump(config) : undefined; + const configYaml = config ? dump(config) : undefined; - const data: NewOutput = { - ...outputData, - is_preconfigured: true, - config_yaml: configYaml ?? null, - // Set value to null to update these fields on update - ca_sha256: outputData.ca_sha256 ?? null, - ca_trusted_fingerprint: outputData.ca_trusted_fingerprint ?? null, - ssl: outputData.ssl ?? null, - } as NewOutput; + const data: NewOutput = { + ...outputData, + is_preconfigured: true, + config_yaml: configYaml ?? null, + // Set value to null to update these fields on update + ca_sha256: outputData.ca_sha256 ?? null, + ca_trusted_fingerprint: outputData.ca_trusted_fingerprint ?? null, + ssl: outputData.ssl ?? null, + } as NewOutput; - if (!data.hosts || data.hosts.length === 0) { - data.hosts = outputService.getDefaultESHosts(); - } + if (!data.hosts || data.hosts.length === 0) { + data.hosts = outputService.getDefaultESHosts(); + } - const isCreate = !existingOutput; + const isCreate = !existingOutput; - // field in allow edit are not updated through preconfiguration - if (!isCreate && output.allow_edit) { - for (const key of output.allow_edit) { - // @ts-expect-error - data[key] = existingOutput[key]; - } + // field in allow edit are not updated through preconfiguration + if (!isCreate && output.allow_edit) { + for (const key of output.allow_edit) { + // @ts-expect-error + data[key] = existingOutput[key]; } + } + + const isUpdateWithNewData = + existingOutput && (await isPreconfiguredOutputDifferentFromCurrent(existingOutput, data)); + + if (isCreate || isUpdateWithNewData) { + const secretHashes = await hashSecrets(output); - const isUpdateWithNewData = - existingOutput && (await isPreconfiguredOutputDifferentFromCurrent(existingOutput, data)); - - if (isCreate || isUpdateWithNewData) { - const secretHashes = await hashSecrets(output); - - if (isCreate) { - logger.debug(`Creating preconfigured output ${output.id}`); - await outputService.create(soClient, esClient, data, { - id, - fromPreconfiguration: true, - secretHashes, - }); - } else if (isUpdateWithNewData) { - logger.debug(`Updating preconfigured output ${output.id}`); - await outputService.update(soClient, esClient, id, data, { - fromPreconfiguration: true, - secretHashes, - }); - // Bump revision of all policies using that output - if (outputData.is_default || outputData.is_default_monitoring) { - await agentPolicyService.bumpAllAgentPolicies(esClient); - } else { - await agentPolicyService.bumpAllAgentPoliciesForOutput(esClient, id); - } + if (isCreate) { + logger.debug(`Creating preconfigured output ${output.id}`); + await outputService.create(soClient, esClient, data, { + id, + fromPreconfiguration: true, + secretHashes, + }); + } else if (isUpdateWithNewData) { + logger.debug(`Updating preconfigured output ${output.id}`); + await outputService.update(soClient, esClient, id, data, { + fromPreconfiguration: true, + secretHashes, + }); + // Bump revision of all policies using that output + if (outputData.is_default || outputData.is_default_monitoring) { + await agentPolicyService.bumpAllAgentPolicies(esClient); + } else { + await agentPolicyService.bumpAllAgentPoliciesForOutput(esClient, id); } } - }) - ); + } + }; + + await pMap(outputs, (output) => updateOrConfigureOutput(output), { + concurrency: MAX_CONCURRENT_OUTPUTS_OPERATIONS, + }); } // Values recommended by NodeJS documentation diff --git a/x-pack/plugins/fleet/server/services/preconfiguration/reset_agent_policies.ts b/x-pack/plugins/fleet/server/services/preconfiguration/reset_agent_policies.ts index 7e65dd665d0bd..84dbbf817d665 100644 --- a/x-pack/plugins/fleet/server/services/preconfiguration/reset_agent_policies.ts +++ b/x-pack/plugins/fleet/server/services/preconfiguration/reset_agent_policies.ts @@ -24,6 +24,8 @@ import { listEnrollmentApiKeys, deleteEnrollmentApiKey } from '../api_keys'; import type { AgentPolicy } from '../../types'; import { AgentPolicyInvalidError } from '../../errors'; +import { MAX_CONCURRENT_AGENT_POLICIES_OPERATIONS_20 } from '../../constants'; + export async function resetPreconfiguredAgentPolicies( soClient: SavedObjectsClientContract, esClient: ElasticsearchClient, @@ -83,7 +85,7 @@ async function _deleteGhostPackagePolicies( } }, { - concurrency: 20, + concurrency: MAX_CONCURRENT_AGENT_POLICIES_OPERATIONS_20, } ); } @@ -116,7 +118,7 @@ async function _deletePreconfigurationDeleteRecord( }), { - concurrency: 20, + concurrency: MAX_CONCURRENT_AGENT_POLICIES_OPERATIONS_20, } ); } @@ -167,7 +169,7 @@ async function _deleteExistingData( if (agents.length > 0) { logger.info(`Force unenrolling ${agents.length} agents`); await pMap(agents, (agent) => forceUnenrollAgent(esClient, soClient, agent.id), { - concurrency: 20, + concurrency: MAX_CONCURRENT_AGENT_POLICIES_OPERATIONS_20, }); } @@ -183,7 +185,7 @@ async function _deleteExistingData( enrollmentApiKeys, (enrollmentKey) => deleteEnrollmentApiKey(esClient, enrollmentKey.id, true), { - concurrency: 20, + concurrency: MAX_CONCURRENT_AGENT_POLICIES_OPERATIONS_20, } ); } @@ -195,7 +197,7 @@ async function _deleteExistingData( force: true, }), { - concurrency: 20, + concurrency: MAX_CONCURRENT_AGENT_POLICIES_OPERATIONS_20, } ); } diff --git a/x-pack/plugins/fleet/server/services/setup.ts b/x-pack/plugins/fleet/server/services/setup.ts index ab882a013ebe3..24d655a4cae16 100644 --- a/x-pack/plugins/fleet/server/services/setup.ts +++ b/x-pack/plugins/fleet/server/services/setup.ts @@ -21,6 +21,8 @@ import { AUTO_UPDATE_PACKAGES, FLEET_SETUP_LOCK_TYPE } from '../../common/consta import type { PreconfigurationError } from '../../common/constants'; import type { DefaultPackagesInstallationError, FleetSetupLock } from '../../common/types'; +import { MAX_CONCURRENT_EPM_PACKAGES_INSTALLATIONS } from '../constants'; + import { appContextService } from './app_context'; import { ensurePreconfiguredPackagesAndPolicies } from './preconfiguration'; import { @@ -359,7 +361,7 @@ export async function ensureFleetGlobalEsAssets( ); }); }, - { concurrency: 10 } + { concurrency: MAX_CONCURRENT_EPM_PACKAGES_INSTALLATIONS } ); } } diff --git a/x-pack/plugins/fleet/server/services/setup/clean_old_fleet_indices.tsx b/x-pack/plugins/fleet/server/services/setup/clean_old_fleet_indices.tsx index cd3317c5eb23b..ab3045ee57a08 100644 --- a/x-pack/plugins/fleet/server/services/setup/clean_old_fleet_indices.tsx +++ b/x-pack/plugins/fleet/server/services/setup/clean_old_fleet_indices.tsx @@ -8,6 +8,8 @@ import type { ElasticsearchClient, Logger } from '@kbn/core/server'; import pMap from 'p-map'; +import { MAX_CONCURRENT_CLEAN_OLD_FILE_INDICES } from '../../constants'; + const INDICES_TO_CLEAN = [ '.fleet-files-*', '.fleet-file-data-*', @@ -49,7 +51,7 @@ export async function cleanUpOldFileIndices(esClient: ElasticsearchClient, logge }); } }, - { concurrency: 2 } + { concurrency: MAX_CONCURRENT_CLEAN_OLD_FILE_INDICES } ); await esClient.indices .deleteIndexTemplate({ diff --git a/x-pack/plugins/fleet/server/services/setup/fleet_server_policies_enrollment_keys.ts b/x-pack/plugins/fleet/server/services/setup/fleet_server_policies_enrollment_keys.ts index cd7e91fb81ac4..07efdde6f7b77 100644 --- a/x-pack/plugins/fleet/server/services/setup/fleet_server_policies_enrollment_keys.ts +++ b/x-pack/plugins/fleet/server/services/setup/fleet_server_policies_enrollment_keys.ts @@ -10,7 +10,7 @@ import pMap from 'p-map'; import { agentPolicyService } from '../agent_policy'; import { ensureDefaultEnrollmentAPIKeyForAgentPolicy } from '../api_keys'; -import { SO_SEARCH_LIMIT } from '../../constants'; +import { SO_SEARCH_LIMIT, MAX_CONCURRENT_AGENT_POLICIES_OPERATIONS_20 } from '../../constants'; import { appContextService } from '../app_context'; import { scheduleDeployAgentPoliciesTask } from '../agent_policies/deploy_agent_policies_task'; import { scheduleBumpAgentPoliciesTask } from '../agent_policies/bump_agent_policies_task'; @@ -51,7 +51,7 @@ export async function ensureAgentPoliciesFleetServerKeysAndPolicies({ } }, { - concurrency: 20, + concurrency: MAX_CONCURRENT_AGENT_POLICIES_OPERATIONS_20, } ); diff --git a/x-pack/plugins/fleet/server/services/setup/upgrade_package_install_version.ts b/x-pack/plugins/fleet/server/services/setup/upgrade_package_install_version.ts index db85e269dc345..bb9def3dc4ae6 100644 --- a/x-pack/plugins/fleet/server/services/setup/upgrade_package_install_version.ts +++ b/x-pack/plugins/fleet/server/services/setup/upgrade_package_install_version.ts @@ -9,7 +9,11 @@ import type { ElasticsearchClient, SavedObjectsClientContract } from '@kbn/core/ import pMap from 'p-map'; import type { Logger } from '@kbn/logging'; -import { PACKAGES_SAVED_OBJECT_TYPE, SO_SEARCH_LIMIT } from '../../constants'; +import { + MAX_CONCURRENT_EPM_PACKAGES_INSTALLATIONS, + PACKAGES_SAVED_OBJECT_TYPE, + SO_SEARCH_LIMIT, +} from '../../constants'; import { FLEET_INSTALL_FORMAT_VERSION } from '../../constants/fleet_es_assets'; import type { Installation } from '../../types'; @@ -59,6 +63,6 @@ export async function upgradePackageInstallVersion({ } }); }, - { concurrency: 10 } + { concurrency: MAX_CONCURRENT_EPM_PACKAGES_INSTALLATIONS } ); } diff --git a/x-pack/plugins/fleet/server/services/spaces/agent_policy.ts b/x-pack/plugins/fleet/server/services/spaces/agent_policy.ts index e123ca4426654..50f20443c3262 100644 --- a/x-pack/plugins/fleet/server/services/spaces/agent_policy.ts +++ b/x-pack/plugins/fleet/server/services/spaces/agent_policy.ts @@ -23,9 +23,10 @@ import { ENROLLMENT_API_KEYS_INDEX } from '../../constants'; import { packagePolicyService } from '../package_policy'; import { FleetError, HostedAgentPolicyRestrictionRelatedError } from '../../errors'; -import { isSpaceAwarenessEnabled } from './helpers'; import type { UninstallTokenSOAttributes } from '../security/uninstall_token_service'; +import { isSpaceAwarenessEnabled } from './helpers'; + export async function updateAgentPolicySpaces({ agentPolicyId, currentSpaceId, diff --git a/x-pack/plugins/index_management/__jest__/client_integration/create_enrich_policy/create_enrich_policy.test.tsx b/x-pack/plugins/index_management/__jest__/client_integration/create_enrich_policy/create_enrich_policy.test.tsx index a9675b592aa39..e9d93e6baf631 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/create_enrich_policy/create_enrich_policy.test.tsx +++ b/x-pack/plugins/index_management/__jest__/client_integration/create_enrich_policy/create_enrich_policy.test.tsx @@ -57,10 +57,6 @@ describe('Create enrich policy', () => { beforeEach(async () => { httpRequestsMockHelpers.setGetMatchingIndices(getMatchingIndices()); - httpRequestsMockHelpers.setGetPrivilegesResponse({ - hasAllPrivileges: true, - missingPrivileges: { cluster: [] }, - }); httpRequestsMockHelpers.setGetMatchingDataStreams(getMatchingDataStreams()); await act(async () => { diff --git a/x-pack/plugins/index_management/__jest__/client_integration/helpers/http_requests.ts b/x-pack/plugins/index_management/__jest__/client_integration/helpers/http_requests.ts index 0504f9bf40b7a..a9f1dac15ed1f 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/helpers/http_requests.ts +++ b/x-pack/plugins/index_management/__jest__/client_integration/helpers/http_requests.ts @@ -188,9 +188,6 @@ const registerHttpRequestMockHelpers = ( error ); - const setGetPrivilegesResponse = (response?: HttpResponse, error?: ResponseError) => - mockResponse('GET', `${INTERNAL_API_BASE_PATH}/enrich_policies/privileges`, response, error); - const setCreateEnrichPolicy = (response?: HttpResponse, error?: ResponseError) => mockResponse('POST', `${INTERNAL_API_BASE_PATH}/enrich_policies`, response, error); @@ -253,7 +250,6 @@ const registerHttpRequestMockHelpers = ( setCreateIndexResponse, setGetMatchingIndices, setGetFieldsFromIndices, - setGetPrivilegesResponse, setCreateEnrichPolicy, setInferenceModels, setGetMatchingDataStreams, diff --git a/x-pack/plugins/index_management/__jest__/client_integration/helpers/setup_environment.tsx b/x-pack/plugins/index_management/__jest__/client_integration/helpers/setup_environment.tsx index 633ed96ec8225..24f641ae2833f 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/helpers/setup_environment.tsx +++ b/x-pack/plugins/index_management/__jest__/client_integration/helpers/setup_environment.tsx @@ -91,6 +91,11 @@ const appDependencies = { overlays: { openConfirm: jest.fn(), }, + privs: { + monitor: true, + manageEnrich: true, + monitorEnrich: true, + }, } as any; export const kibanaVersion = new SemVer(MAJOR_VERSION); diff --git a/x-pack/plugins/index_management/__jest__/client_integration/home/enrich_policies.test.tsx b/x-pack/plugins/index_management/__jest__/client_integration/home/enrich_policies.test.tsx index 77c7757fe9202..040602a058e25 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/home/enrich_policies.test.tsx +++ b/x-pack/plugins/index_management/__jest__/client_integration/home/enrich_policies.test.tsx @@ -38,11 +38,6 @@ describe('Enrich policies tab', () => { describe('empty states', () => { beforeEach(async () => { setDelayResponse(false); - - httpRequestsMockHelpers.setGetPrivilegesResponse({ - hasAllPrivileges: true, - missingPrivileges: { cluster: [] }, - }); }); test('displays a loading prompt', async () => { @@ -82,24 +77,6 @@ describe('Enrich policies tab', () => { }); }); - describe('permissions check', () => { - it('shows a permissions error when the user does not have sufficient privileges', async () => { - httpRequestsMockHelpers.setGetPrivilegesResponse({ - hasAllPrivileges: false, - missingPrivileges: { cluster: ['manage_enrich'] }, - }); - - testBed = await setup(httpSetup); - await act(async () => { - testBed.actions.goToEnrichPoliciesTab(); - }); - - testBed.component.update(); - - expect(testBed.exists('enrichPoliciesInsuficientPrivileges')).toBe(true); - }); - }); - describe('policies list', () => { let testPolicy: ReturnType; beforeEach(async () => { @@ -110,11 +87,6 @@ describe('Enrich policies tab', () => { createTestEnrichPolicy('policy-range', 'range'), ]); - httpRequestsMockHelpers.setGetPrivilegesResponse({ - hasAllPrivileges: true, - missingPrivileges: { cluster: [] }, - }); - testBed = await setup(httpSetup); await act(async () => { testBed.actions.goToEnrichPoliciesTab(); diff --git a/x-pack/plugins/index_management/__jest__/components/index_table.test.js b/x-pack/plugins/index_management/__jest__/components/index_table.test.js index 2ae162b421001..0a59fef7be6e6 100644 --- a/x-pack/plugins/index_management/__jest__/components/index_table.test.js +++ b/x-pack/plugins/index_management/__jest__/components/index_table.test.js @@ -168,6 +168,11 @@ describe('index table', () => { enableIndexActions: true, enableIndexStats: true, }, + privs: { + monitor: true, + manageEnrich: true, + monitorEnrich: true, + }, }; component = ( diff --git a/x-pack/plugins/index_management/public/application/app_context.tsx b/x-pack/plugins/index_management/public/application/app_context.tsx index 6df01a109a036..3573ae33812d9 100644 --- a/x-pack/plugins/index_management/public/application/app_context.tsx +++ b/x-pack/plugins/index_management/public/application/app_context.tsx @@ -80,6 +80,11 @@ export interface AppDependencies { kibanaVersion: SemVer; overlays: OverlayStart; canUseSyntheticSource: boolean; + privs: { + monitor: boolean; + manageEnrich: boolean; + monitorEnrich: boolean; + }; } export const AppContextProvider = ({ diff --git a/x-pack/plugins/index_management/public/application/components/enrich_policies/with_privileges.tsx b/x-pack/plugins/index_management/public/application/components/enrich_policies/with_privileges.tsx deleted file mode 100644 index 09a79343b2210..0000000000000 --- a/x-pack/plugins/index_management/public/application/components/enrich_policies/with_privileges.tsx +++ /dev/null @@ -1,82 +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 { FormattedMessage } from '@kbn/i18n-react'; -import React, { FunctionComponent } from 'react'; - -import { - PageLoading, - PageError, - useAuthorizationContext, - WithPrivileges, - NotAuthorizedSection, -} from '../../../shared_imports'; -import { ENRICH_POLICIES_REQUIRED_PRIVILEGES } from '../../constants'; - -export const EnrichPoliciesWithPrivileges: FunctionComponent<{ - children?: React.ReactNode; -}> = ({ children }) => { - const { apiError } = useAuthorizationContext(); - - if (apiError) { - return ( - - } - error={apiError} - /> - ); - } - - return ( - `cluster.${privilege}`)} - > - {({ isLoading, hasPrivileges, privilegesMissing }) => { - if (isLoading) { - return ( - - - - ); - } - - if (!hasPrivileges) { - return ( - - } - message={ - - } - /> - ); - } - - return <>{children}; - }} - - ); -}; diff --git a/x-pack/plugins/index_management/public/application/mount_management_section.ts b/x-pack/plugins/index_management/public/application/mount_management_section.ts index 48a45579a01fc..83cf620a0e8e0 100644 --- a/x-pack/plugins/index_management/public/application/mount_management_section.ts +++ b/x-pack/plugins/index_management/public/application/mount_management_section.ts @@ -73,6 +73,8 @@ export function getIndexManagementDependencies({ }): AppDependencies { const { docLinks, application, uiSettings, settings } = core; const { url } = startDependencies.share; + const { monitor, manageEnrich, monitorEnrich } = application.capabilities.index_management; + return { core: { getUrlForApp: application.getUrlForApp, @@ -103,6 +105,11 @@ export function getIndexManagementDependencies({ kibanaVersion, overlays: core.overlays, canUseSyntheticSource, + privs: { + monitor: !!monitor, + manageEnrich: !!manageEnrich, + monitorEnrich: !!monitorEnrich, + }, }; } diff --git a/x-pack/plugins/index_management/public/application/sections/enrich_policy_create/enrich_policy_create.tsx b/x-pack/plugins/index_management/public/application/sections/enrich_policy_create/enrich_policy_create.tsx index f7ef260b14651..321dee68ae8aa 100644 --- a/x-pack/plugins/index_management/public/application/sections/enrich_policy_create/enrich_policy_create.tsx +++ b/x-pack/plugins/index_management/public/application/sections/enrich_policy_create/enrich_policy_create.tsx @@ -14,12 +14,8 @@ import { breadcrumbService, IndexManagementBreadcrumb } from '../../services/bre import { CreatePolicyWizard } from './create_policy_wizard'; import { CreatePolicyContextProvider } from './create_policy_context'; -import { - EnrichPoliciesAuthProvider, - EnrichPoliciesWithPrivileges, -} from '../../components/enrich_policies'; -const CreateView: React.FunctionComponent = () => { +export const EnrichPolicyCreate: React.FunctionComponent = () => { useEffect(() => { breadcrumbService.setBreadcrumbs(IndexManagementBreadcrumb.enrichPoliciesCreate); }, []); @@ -64,11 +60,3 @@ const CreateView: React.FunctionComponent = () => { ); }; - -export const EnrichPolicyCreate: React.FunctionComponent = (props) => ( - - - - - -); diff --git a/x-pack/plugins/index_management/public/application/sections/home/enrich_policies_list/enrich_policies_list.tsx b/x-pack/plugins/index_management/public/application/sections/home/enrich_policies_list/enrich_policies_list.tsx index a036273ebdde9..eeba7b9e03fd8 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/enrich_policies_list/enrich_policies_list.tsx +++ b/x-pack/plugins/index_management/public/application/sections/home/enrich_policies_list/enrich_policies_list.tsx @@ -17,10 +17,6 @@ import { APP_WRAPPER_CLASS, useExecutionContext } from '../../../../shared_impor import { useAppContext } from '../../../app_context'; import { useRedirectPath } from '../../../hooks/redirect_path'; -import { - EnrichPoliciesAuthProvider, - EnrichPoliciesWithPrivileges, -} from '../../../components/enrich_policies'; import { breadcrumbService, IndexManagementBreadcrumb } from '../../../services/breadcrumbs'; import { documentationService } from '../../../services/documentation'; import { useLoadEnrichPolicies } from '../../../services/api'; @@ -34,9 +30,13 @@ const getEnrichPolicyNameFromLocation = (location: Location) => { return policy; }; -const ListView: React.FunctionComponent = ({ history, location }) => { +export const EnrichPoliciesList: React.FunctionComponent = ({ + history, + location, +}) => { const { core: { executionContext }, + privs, } = useAppContext(); const redirectTo = useRedirectPath(history); @@ -79,7 +79,7 @@ const ListView: React.FunctionComponent = ({ history, locat return ; } - if (policies?.length === 0) { + if (privs.manageEnrich && policies?.length === 0) { return ; } @@ -151,11 +151,3 @@ const ListView: React.FunctionComponent = ({ history, locat
        ); }; - -export const EnrichPoliciesList: React.FunctionComponent = (props) => ( - - - - - -); diff --git a/x-pack/plugins/index_management/public/application/sections/home/enrich_policies_list/policies_table/policies_table.tsx b/x-pack/plugins/index_management/public/application/sections/home/enrich_policies_list/policies_table/policies_table.tsx index e78e08b829997..61574a70fa545 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/enrich_policies_list/policies_table/policies_table.tsx +++ b/x-pack/plugins/index_management/public/application/sections/home/enrich_policies_list/policies_table/policies_table.tsx @@ -33,43 +33,84 @@ export const PoliciesTable: FunctionComponent = ({ onDeletePolicyClick, onExecutePolicyClick, }) => { - const { history } = useAppContext(); + const { history, privs } = useAppContext(); - const renderToolsRight = () => { - return [ - - - , - - - , - ]; - }; + const createBtn = ( + + + + ); + + const toolsRight = [ + + + , + ]; + + if (privs.manageEnrich) { + toolsRight.push(createBtn); + } const search: EuiSearchBarProps = { - toolsRight: renderToolsRight(), + toolsRight, box: { incremental: true, }, }; + const actions: EuiBasicTableColumn = { + name: i18n.translate('xpack.idxMgmt.enrichPolicies.table.actionsField', { + defaultMessage: 'Actions', + }), + actions: [ + { + isPrimary: true, + name: i18n.translate('xpack.idxMgmt.enrichPolicies.table.executeAction', { + defaultMessage: 'Execute', + }), + description: i18n.translate('xpack.idxMgmt.enrichPolicies.table.executeDescription', { + defaultMessage: 'Execute this enrich policy', + }), + type: 'icon', + icon: 'play', + 'data-test-subj': 'executePolicyButton', + onClick: ({ name }) => onExecutePolicyClick(name), + }, + { + isPrimary: true, + name: i18n.translate('xpack.idxMgmt.enrichPolicies.table.deleteAction', { + defaultMessage: 'Delete', + }), + description: i18n.translate('xpack.idxMgmt.enrichPolicies.table.deleteDescription', { + defaultMessage: 'Delete this enrich policy', + }), + type: 'icon', + icon: 'trash', + color: 'danger', + 'data-test-subj': 'deletePolicyButton', + onClick: ({ name }) => onDeletePolicyClick(name), + }, + ], + }; + const columns: Array> = [ { field: 'name', @@ -120,42 +161,12 @@ export const PoliciesTable: FunctionComponent = ({ truncateText: true, render: (fields: string[]) => {fields.join(', ')}, }, - { - name: i18n.translate('xpack.idxMgmt.enrichPolicies.table.actionsField', { - defaultMessage: 'Actions', - }), - actions: [ - { - isPrimary: true, - name: i18n.translate('xpack.idxMgmt.enrichPolicies.table.executeAction', { - defaultMessage: 'Execute', - }), - description: i18n.translate('xpack.idxMgmt.enrichPolicies.table.executeDescription', { - defaultMessage: 'Execute this enrich policy', - }), - type: 'icon', - icon: 'play', - 'data-test-subj': 'executePolicyButton', - onClick: ({ name }) => onExecutePolicyClick(name), - }, - { - isPrimary: true, - name: i18n.translate('xpack.idxMgmt.enrichPolicies.table.deleteAction', { - defaultMessage: 'Delete', - }), - description: i18n.translate('xpack.idxMgmt.enrichPolicies.table.deleteDescription', { - defaultMessage: 'Delete this enrich policy', - }), - type: 'icon', - icon: 'trash', - color: 'danger', - 'data-test-subj': 'deletePolicyButton', - onClick: ({ name }) => onDeletePolicyClick(name), - }, - ], - }, ]; + if (privs.manageEnrich) { + columns.push(actions); + } + const { pageSize, sorting, onTableChange } = useEuiTablePersist({ tableId: 'enrichPolicies', initialPageSize: 50, diff --git a/x-pack/plugins/index_management/public/application/sections/home/home.tsx b/x-pack/plugins/index_management/public/application/sections/home/home.tsx index e7de896fa4b38..2d0fc7d4ec108 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/home.tsx +++ b/x-pack/plugins/index_management/public/application/sections/home/home.tsx @@ -41,6 +41,7 @@ export const IndexManagementHome: React.FunctionComponent { const { plugins: { console: consolePlugin }, + privs, } = useAppContext(); const tabs = [ { @@ -74,7 +75,10 @@ export const IndexManagementHome: React.FunctionComponent ), }, - { + ]; + + if (privs.monitorEnrich) { + tabs.push({ id: Section.EnrichPolicies, name: ( ), - }, - ]; + }); + } const onSectionChange = (newSection: Section) => { history.push(`/${newSection}`); @@ -143,7 +147,9 @@ export const IndexManagementHome: React.FunctionComponent - + {privs.monitorEnrich && ( + + )} {consolePlugin?.EmbeddableConsole ? : null} diff --git a/x-pack/plugins/index_management/public/plugin.ts b/x-pack/plugins/index_management/public/plugin.ts index 82ba6505696aa..06adcc75d80b3 100644 --- a/x-pack/plugins/index_management/public/plugin.ts +++ b/x-pack/plugins/index_management/public/plugin.ts @@ -6,6 +6,7 @@ */ import { i18n } from '@kbn/i18n'; +import { Subject } from 'rxjs'; import SemVer from 'semver/classes/semver'; import { @@ -14,6 +15,7 @@ import { Plugin, PluginInitializerContext, ScopedHistory, + Capabilities, } from '@kbn/core/public'; import { IndexManagementPluginSetup, @@ -61,6 +63,8 @@ export class IndexMgmtUIPlugin private canUseSyntheticSource: boolean = false; private licensingSubscription?: Subscription; + private capabilities$ = new Subject(); + constructor(ctx: PluginInitializerContext) { // Temporary hack to provide the service instances in module files in order to avoid a big refactor // For the selectors we should expose them through app dependencies and read them from there on each container component. @@ -98,29 +102,34 @@ export class IndexMgmtUIPlugin coreSetup: CoreSetup, plugins: SetupDependencies ): IndexManagementPluginSetup { - if (this.config.isIndexManagementUiEnabled) { - const { fleet, usageCollection, management, cloud } = plugins; + const { fleet, usageCollection, management, cloud } = plugins; - management.sections.section.data.registerApp({ - id: PLUGIN.id, - title: i18n.translate('xpack.idxMgmt.appTitle', { defaultMessage: 'Index Management' }), - order: 0, - mount: async (params) => { - const { mountManagementSection } = await import('./application/mount_management_section'); - return mountManagementSection({ - coreSetup, - usageCollection, - params, - extensionsService: this.extensionsService, - isFleetEnabled: Boolean(fleet), - kibanaVersion: this.kibanaVersion, - config: this.config, - cloud, - canUseSyntheticSource: this.canUseSyntheticSource, - }); - }, - }); - } + this.capabilities$.subscribe((capabilities) => { + const { monitor, manageEnrich, monitorEnrich } = capabilities.index_management; + if (this.config.isIndexManagementUiEnabled && (monitor || manageEnrich || monitorEnrich)) { + management.sections.section.data.registerApp({ + id: PLUGIN.id, + title: i18n.translate('xpack.idxMgmt.appTitle', { defaultMessage: 'Index Management' }), + order: 0, + mount: async (params) => { + const { mountManagementSection } = await import( + './application/mount_management_section' + ); + return mountManagementSection({ + coreSetup, + usageCollection, + params, + extensionsService: this.extensionsService, + isFleetEnabled: Boolean(fleet), + kibanaVersion: this.kibanaVersion, + config: this.config, + cloud, + canUseSyntheticSource: this.canUseSyntheticSource, + }); + }, + }); + } + }); this.locator = plugins.share.url.locators.create( new IndexManagementLocatorDefinition({ @@ -138,6 +147,8 @@ export class IndexMgmtUIPlugin public start(coreStart: CoreStart, plugins: StartDependencies): IndexManagementPluginStart { const { fleet, usageCollection, cloud, share, console, ml, licensing } = plugins; + this.capabilities$.next(coreStart.application.capabilities); + this.licensingSubscription = licensing?.license$.subscribe((next) => { this.canUseSyntheticSource = next.hasAtLeast('enterprise'); }); diff --git a/x-pack/plugins/index_management/server/plugin.ts b/x-pack/plugins/index_management/server/plugin.ts index 0ba15c463d4ec..ab6b058cddc78 100644 --- a/x-pack/plugins/index_management/server/plugin.ts +++ b/x-pack/plugins/index_management/server/plugin.ts @@ -37,15 +37,20 @@ export class IndexMgmtServerPlugin implements Plugin { + const { root, errors } = parse(query); + // don't try modifying anything if the query is not syntactically correct + if (errors) { + return { + output: query, + corrections: [], + }; + } + + const corrections = correctAll(root); + + const multiline = /\r?\n/.test(query); + const formattedQuery = BasicPrettyPrinter.print(root, { multiline, pipeTab: '' }); + + return { + output: formattedQuery, + corrections, + }; +}; diff --git a/x-pack/plugins/inference/common/tasks/nl_to_esql/ast/corrections/index.ts b/x-pack/plugins/inference/common/tasks/nl_to_esql/ast/corrections/index.ts new file mode 100644 index 0000000000000..76ffd993bb9ab --- /dev/null +++ b/x-pack/plugins/inference/common/tasks/nl_to_esql/ast/corrections/index.ts @@ -0,0 +1,20 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { ESQLAstQueryExpression } from '@kbn/esql-ast'; +import type { QueryCorrection } from './types'; +import { correctTimespanLiterals } from './timespan_literals'; +import { correctLikeWildcards } from './like'; + +export type { QueryCorrection } from './types'; + +export const correctAll = (query: ESQLAstQueryExpression): QueryCorrection[] => { + const corrections: QueryCorrection[] = []; + corrections.push(...correctTimespanLiterals(query)); + corrections.push(...correctLikeWildcards(query)); + return corrections; +}; diff --git a/x-pack/plugins/inference/common/tasks/nl_to_esql/ast/corrections/like.test.ts b/x-pack/plugins/inference/common/tasks/nl_to_esql/ast/corrections/like.test.ts new file mode 100644 index 0000000000000..81779188c553b --- /dev/null +++ b/x-pack/plugins/inference/common/tasks/nl_to_esql/ast/corrections/like.test.ts @@ -0,0 +1,59 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { parse, BasicPrettyPrinter } from '@kbn/esql-ast'; +import { correctLikeWildcards } from './like'; + +describe('correctLikeWildcards', () => { + it('replaces badly used "_" wildcard', () => { + const query = 'FROM logs | WHERE message LIKE "ba_"'; + const { root } = parse(query); + correctLikeWildcards(root); + + const output = BasicPrettyPrinter.print(root); + expect(output).toEqual('FROM logs | WHERE message LIKE "ba?"'); + }); + + it('replaces badly used "%" wildcard', () => { + const query = 'FROM logs | WHERE message LIKE "b%"'; + const { root } = parse(query); + correctLikeWildcards(root); + + const output = BasicPrettyPrinter.print(root); + expect(output).toEqual('FROM logs | WHERE message LIKE "b*"'); + }); + + it('replaces multiple bad wildcards', () => { + const query = 'FROM logs | WHERE message LIKE "a__t%"'; + const { root } = parse(query); + correctLikeWildcards(root); + + const output = BasicPrettyPrinter.print(root); + expect(output).toEqual('FROM logs | WHERE message LIKE "a??t*"'); + }); + + it('replaces bad wildcards in multiple commands and functions', () => { + const query = + 'FROM logs | WHERE message LIKE "a%" AND TO_UPPER(level) LIKE "err%" | WHERE foo LIKE "ba_"'; + const { root } = parse(query); + correctLikeWildcards(root); + + const output = BasicPrettyPrinter.print(root); + expect(output).toEqual( + 'FROM logs | WHERE message LIKE "a*" AND TO_UPPER(level) LIKE "err*" | WHERE foo LIKE "ba?"' + ); + }); + + it('does not replace escaped characters', () => { + const query = 'FROM logs | WHERE message LIKE "ba\\\\_"'; + const { root } = parse(query); + correctLikeWildcards(root); + + const output = BasicPrettyPrinter.print(root); + expect(output).toEqual('FROM logs | WHERE message LIKE "ba\\\\_"'); + }); +}); diff --git a/x-pack/plugins/inference/common/tasks/nl_to_esql/ast/corrections/like.ts b/x-pack/plugins/inference/common/tasks/nl_to_esql/ast/corrections/like.ts new file mode 100644 index 0000000000000..be61bd216284b --- /dev/null +++ b/x-pack/plugins/inference/common/tasks/nl_to_esql/ast/corrections/like.ts @@ -0,0 +1,59 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { Walker, type ESQLAstQueryExpression } from '@kbn/esql-ast'; +import { isLikeOperatorNode, isStringLiteralNode } from '../typeguards'; +import type { ESQLLikeOperator, ESQLStringLiteral } from '../types'; +import type { QueryCorrection } from './types'; + +/** + * Correct wrong LIKE wildcard mistakes. + * The LLM can make mistake and use SQL wildcards for LIKE operators. + * + * E.g. + * `column LIKE "ba_"` => `column LIKE "ba?"` + * `column LIKE "ba%"` => `column LIKE "ba*"` + */ +export const correctLikeWildcards = (query: ESQLAstQueryExpression): QueryCorrection[] => { + const corrections: QueryCorrection[] = []; + + Walker.walk(query, { + visitFunction: (node) => { + if (isLikeOperatorNode(node)) { + corrections.push(...checkLikeNode(node)); + } + }, + }); + + return corrections; +}; + +function checkLikeNode(node: ESQLLikeOperator): QueryCorrection[] { + if (node.args.length !== 2 || !isStringLiteralNode(node.args[1])) { + return []; + } + const likeExpression = node.args[1] as ESQLStringLiteral; + + const initialValue = likeExpression.value; + + likeExpression.value = likeExpression.value + .replaceAll(/(? { + describe('with DATE_TRUNC', () => { + it('replaces a timespan with a proper timespan literal', () => { + const query = 'FROM logs | EVAL truncated = DATE_TRUNC("1 year", date)'; + const { root } = parse(query); + + correctTimespanLiterals(root); + + const output = BasicPrettyPrinter.print(root); + + expect(output).toMatchInlineSnapshot( + `"FROM logs | EVAL truncated = DATE_TRUNC(1 year, date)"` + ); + }); + + it('replaces a timespan without quantity', () => { + const query = 'FROM logs | EVAL truncated = DATE_TRUNC("month", date)'; + const { root } = parse(query); + + correctTimespanLiterals(root); + + const output = BasicPrettyPrinter.print(root); + + expect(output).toMatchInlineSnapshot( + `"FROM logs | EVAL truncated = DATE_TRUNC(1 month, date)"` + ); + }); + + it('replaces uppercase literals', () => { + const query = 'FROM logs | EVAL truncated = DATE_TRUNC("1 YEAR", date)'; + const { root } = parse(query); + + correctTimespanLiterals(root); + + const output = BasicPrettyPrinter.print(root); + + expect(output).toMatchInlineSnapshot( + `"FROM logs | EVAL truncated = DATE_TRUNC(1 year, date)"` + ); + }); + + it('returns info about the correction', () => { + const query = 'FROM logs | EVAL truncated = DATE_TRUNC("1 year", date)'; + const { root } = parse(query); + + const corrections = correctTimespanLiterals(root); + + expect(corrections).toHaveLength(1); + expect(corrections[0]).toEqual({ + type: 'string_as_timespan_literal', + description: + 'Replaced string literal with timespan literal in DATE_TRUNC function at position 29', + node: expect.any(Object), + }); + }); + }); + + describe('with BUCKET', () => { + it('replaces a timespan with a proper timespan literal', () => { + const query = 'FROM logs | STATS hires = COUNT(*) BY week = BUCKET(hire_date, "1 week")'; + const { root } = parse(query); + + correctTimespanLiterals(root); + + const output = BasicPrettyPrinter.print(root); + + expect(output).toMatchInlineSnapshot( + `"FROM logs | STATS hires = COUNT(*) BY week = BUCKET(hire_date, 1 week)"` + ); + }); + + it('replaces a timespan without quantity', () => { + const query = 'FROM logs | STATS hires = COUNT(*) BY hour = BUCKET(hire_date, "hour")'; + const { root } = parse(query); + + correctTimespanLiterals(root); + + const output = BasicPrettyPrinter.print(root); + + expect(output).toMatchInlineSnapshot( + `"FROM logs | STATS hires = COUNT(*) BY hour = BUCKET(hire_date, 1 hour)"` + ); + }); + + it('replaces uppercase literals', () => { + const query = 'FROM logs | STATS hires = COUNT(*) BY week = BUCKET(hire_date, "1 WEEK")'; + const { root } = parse(query); + + correctTimespanLiterals(root); + + const output = BasicPrettyPrinter.print(root); + + expect(output).toMatchInlineSnapshot( + `"FROM logs | STATS hires = COUNT(*) BY week = BUCKET(hire_date, 1 week)"` + ); + }); + + it('returns info about the correction', () => { + const query = 'FROM logs | STATS hires = COUNT(*) BY hour = BUCKET(hire_date, "hour")'; + const { root } = parse(query); + + const corrections = correctTimespanLiterals(root); + + expect(corrections).toHaveLength(1); + expect(corrections[0]).toEqual({ + type: 'string_as_timespan_literal', + description: + 'Replaced string literal with timespan literal in BUCKET function at position 45', + node: expect.any(Object), + }); + }); + }); + + describe('with mixed usages', () => { + it('find all occurrences in a complex query', () => { + const query = `FROM logs + | EVAL trunc_year = DATE_TRUNC("1 year", date) + | EVAL trunc_month = DATE_TRUNC("month", date) + | STATS hires = COUNT(*) BY hour = BUCKET(hire_date, "3 hour")`; + const { root } = parse(query); + + correctTimespanLiterals(root); + + const output = BasicPrettyPrinter.print(root, { multiline: true, pipeTab: '' }); + + expect(output).toMatchInlineSnapshot(` + "FROM logs + | EVAL trunc_year = DATE_TRUNC(1 year, date) + | EVAL trunc_month = DATE_TRUNC(1 month, date) + | STATS hires = COUNT(*) BY hour = BUCKET(hire_date, 3 hour)" + `); + }); + }); +}); diff --git a/x-pack/plugins/inference/common/tasks/nl_to_esql/ast/corrections/timespan_literals.ts b/x-pack/plugins/inference/common/tasks/nl_to_esql/ast/corrections/timespan_literals.ts new file mode 100644 index 0000000000000..039632c3d103f --- /dev/null +++ b/x-pack/plugins/inference/common/tasks/nl_to_esql/ast/corrections/timespan_literals.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 { Walker, type ESQLAstQueryExpression } from '@kbn/esql-ast'; +import { isDateTruncFunctionNode, isBucketFunctionNode, isStringLiteralNode } from '../typeguards'; +import type { ESQLDateTruncFunction, ESQLBucketFunction } from '../types'; +import { stringToTimespanLiteral, isTimespanString } from '../ast_tools/timespan'; +import { QueryCorrection } from './types'; + +/** + * Correct timespan literal grammar mistakes, and returns the list of corrections that got applied. + * + * E.g. + * `DATE_TRUNC("YEAR", @timestamp)` => `DATE_TRUNC(1 year, @timestamp)` + * `BUCKET(@timestamp, "1 week")` => `BUCKET(@timestamp, 1 week)` + * + */ +export const correctTimespanLiterals = (query: ESQLAstQueryExpression): QueryCorrection[] => { + const corrections: QueryCorrection[] = []; + + Walker.walk(query, { + visitFunction: (node) => { + if (isDateTruncFunctionNode(node)) { + corrections.push(...checkDateTrunc(node)); + } + if (isBucketFunctionNode(node)) { + corrections.push(...checkBucket(node)); + } + }, + }); + + return corrections; +}; + +function checkDateTrunc(node: ESQLDateTruncFunction): QueryCorrection[] { + if (node.args.length !== 2) { + return []; + } + + const firstArg = node.args[0]; + + if (isStringLiteralNode(firstArg) && isTimespanString(firstArg.value)) { + const replacement = stringToTimespanLiteral(firstArg.value); + node.args[0] = replacement; + + const correction: QueryCorrection = { + type: 'string_as_timespan_literal', + node, + description: `Replaced string literal with timespan literal in DATE_TRUNC function at position ${node.location.min}`, + }; + return [correction]; + } + + return []; +} + +function checkBucket(node: ESQLBucketFunction): QueryCorrection[] { + // only checking the 2 args version - e.g. BUCKET(hire_date, 1 week) + if (node.args.length !== 2) { + return []; + } + + const secondArg = node.args[1]; + + if (isStringLiteralNode(secondArg) && isTimespanString(secondArg.value)) { + const replacement = stringToTimespanLiteral(secondArg.value); + node.args[1] = replacement; + + const correction: QueryCorrection = { + type: 'string_as_timespan_literal', + node, + description: `Replaced string literal with timespan literal in BUCKET function at position ${node.location.min}`, + }; + return [correction]; + } + + return []; +} diff --git a/x-pack/plugins/inference/common/tasks/nl_to_esql/ast/corrections/types.ts b/x-pack/plugins/inference/common/tasks/nl_to_esql/ast/corrections/types.ts new file mode 100644 index 0000000000000..dc1210c84acc2 --- /dev/null +++ b/x-pack/plugins/inference/common/tasks/nl_to_esql/ast/corrections/types.ts @@ -0,0 +1,20 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { ESQLSingleAstItem } from '@kbn/esql-ast'; + +/** + * Represents a correction that was applied to the query + */ +export interface QueryCorrection { + /** The type of correction */ + type: string; + /** A human-friendly-ish description of the correction */ + description: string; + /** The parent node the correction was applied to */ + node: ESQLSingleAstItem; +} diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/error_connecting/index.ts b/x-pack/plugins/inference/common/tasks/nl_to_esql/ast/index.ts similarity index 81% rename from x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/error_connecting/index.ts rename to x-pack/plugins/inference/common/tasks/nl_to_esql/ast/index.ts index 59ac4e0e37efe..d0e1a4808829a 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/error_connecting/index.ts +++ b/x-pack/plugins/inference/common/tasks/nl_to_esql/ast/index.ts @@ -5,4 +5,4 @@ * 2.0. */ -export { ErrorConnecting } from './error_connecting'; +export { correctQueryWithAst } from './correct_with_ast'; diff --git a/x-pack/plugins/inference/common/tasks/nl_to_esql/ast/typeguards.ts b/x-pack/plugins/inference/common/tasks/nl_to_esql/ast/typeguards.ts new file mode 100644 index 0000000000000..54bbe2f7300a9 --- /dev/null +++ b/x-pack/plugins/inference/common/tasks/nl_to_esql/ast/typeguards.ts @@ -0,0 +1,52 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { + ESQLSingleAstItem, + ESQLAstItem, + ESQLFunction, + ESQLLiteral, + ESQLColumn, +} from '@kbn/esql-ast'; +import type { + ESQLStringLiteral, + ESQLDateTruncFunction, + ESQLBucketFunction, + ESQLLikeOperator, +} from './types'; + +export function isSingleItem(item: ESQLAstItem): item is ESQLSingleAstItem { + return Object.hasOwn(item, 'type'); +} + +export function isFunctionNode(node: ESQLAstItem): node is ESQLFunction { + return isSingleItem(node) && node.type === 'function'; +} + +export function isColumnNode(node: ESQLAstItem): node is ESQLColumn { + return isSingleItem(node) && node.type === 'column'; +} + +export function isLiteralNode(node: ESQLAstItem): node is ESQLLiteral { + return isSingleItem(node) && node.type === 'literal'; +} + +export function isStringLiteralNode(node: ESQLAstItem): node is ESQLStringLiteral { + return isLiteralNode(node) && node.literalType === 'keyword'; +} + +export function isDateTruncFunctionNode(node: ESQLAstItem): node is ESQLDateTruncFunction { + return isFunctionNode(node) && node.subtype === 'variadic-call' && node.name === 'date_trunc'; +} + +export function isBucketFunctionNode(node: ESQLAstItem): node is ESQLBucketFunction { + return isFunctionNode(node) && node.subtype === 'variadic-call' && node.name === 'bucket'; +} + +export function isLikeOperatorNode(node: ESQLAstItem): node is ESQLLikeOperator { + return isFunctionNode(node) && node.subtype === 'binary-expression' && node.name === 'like'; +} diff --git a/x-pack/plugins/inference/common/tasks/nl_to_esql/ast/types.ts b/x-pack/plugins/inference/common/tasks/nl_to_esql/ast/types.ts new file mode 100644 index 0000000000000..6444f1490f3d2 --- /dev/null +++ b/x-pack/plugins/inference/common/tasks/nl_to_esql/ast/types.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 { ESQLFunction, ESQLLiteral } from '@kbn/esql-ast'; + +/** + * represents a DATE_TRUNC function node. + */ +export type ESQLDateTruncFunction = ESQLFunction<'variadic-call', 'date_trunc'>; + +/** + * represents a LIKE function node. + */ +export type ESQLLikeOperator = ESQLFunction<'binary-expression', 'like'>; + +/** + * represents a BUCKET function node. + */ +export type ESQLBucketFunction = ESQLFunction<'variadic-call', 'bucket'>; + +/** + * represents an ESQL string literal. + */ +export type ESQLStringLiteral = Extract; diff --git a/x-pack/plugins/inference/common/tasks/nl_to_esql/correct_esql_query.test.ts b/x-pack/plugins/inference/common/tasks/nl_to_esql/correct_esql_query.test.ts new file mode 100644 index 0000000000000..22ae55f772e95 --- /dev/null +++ b/x-pack/plugins/inference/common/tasks/nl_to_esql/correct_esql_query.test.ts @@ -0,0 +1,84 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor 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 { correctCommonEsqlMistakes } from './correct_esql_query'; + +jest.mock('./ast'); +jest.mock('./non_ast'); +import { correctQueryWithAst } from './ast'; +import { correctCommonEsqlMistakes as correctQueryWithoutAst } from './non_ast'; + +const correctQueryWithAstMock = correctQueryWithAst as jest.MockedFn; +const correctQueryWithoutAstMock = correctQueryWithoutAst as jest.MockedFn< + typeof correctQueryWithoutAst +>; + +describe('correctCommonEsqlMistakes', () => { + beforeEach(() => { + correctQueryWithoutAstMock.mockImplementation((query) => { + return { + input: query, + output: query, + isCorrection: false, + }; + }); + correctQueryWithAstMock.mockImplementation((query) => { + return { + output: query, + corrections: [], + }; + }); + }); + + afterEach(() => { + correctQueryWithoutAstMock.mockReset(); + correctQueryWithAstMock.mockReset(); + }); + + it('calls correctQueryWithoutAst with the right parameters', () => { + const inputQuery = 'FROM logs | WHERE foo > bar'; + correctCommonEsqlMistakes(inputQuery); + + expect(correctQueryWithoutAstMock).toHaveBeenCalledTimes(1); + expect(correctQueryWithoutAstMock).toHaveBeenCalledWith(inputQuery); + }); + + it('calls correctQueryWithAst with the right parameters', () => { + const inputQuery = 'FROM logs | WHERE foo > bar'; + const correctQueryWithoutAstResult = 'FROM logs | WHERE foo > dolly'; + + correctQueryWithoutAstMock.mockImplementation((query) => { + return { + input: inputQuery, + output: correctQueryWithoutAstResult, + isCorrection: true, + }; + }); + + correctCommonEsqlMistakes(inputQuery); + + expect(correctQueryWithAstMock).toHaveBeenCalledTimes(1); + expect(correctQueryWithAstMock).toHaveBeenCalledWith(correctQueryWithoutAstResult); + }); + + it('returns the corrected query', () => { + const inputQuery = 'FROM logs | WHERE foo > bar'; + const correctQueryWithAstResult = 'FROM logs | WHERE foo > dolly'; + + correctQueryWithAstMock.mockImplementation((query) => { + return { + output: correctQueryWithAstResult, + corrections: [], + }; + }); + + const { input, output } = correctCommonEsqlMistakes(inputQuery); + + expect(input).toEqual(inputQuery); + expect(output).toEqual(correctQueryWithAstResult); + }); +}); diff --git a/x-pack/plugins/inference/common/tasks/nl_to_esql/correct_esql_query.ts b/x-pack/plugins/inference/common/tasks/nl_to_esql/correct_esql_query.ts new file mode 100644 index 0000000000000..4ad96323cc7ea --- /dev/null +++ b/x-pack/plugins/inference/common/tasks/nl_to_esql/correct_esql_query.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 { correctQueryWithAst } from './ast'; +import { correctCommonEsqlMistakes as correctQueryWithoutAst } from './non_ast'; + +/** + * Correct some common ES|QL syntax and grammar mistakes that LLM can potentially do. + * + * Correcting the query is done in two steps: + * 1. we try to correct the *syntax*, without AST (given it requires a valid syntax) + * 2. we try to correct the *grammar*, using AST this time. + */ +export const correctCommonEsqlMistakes = (query: string) => { + const { output: outputWithoutAst, isCorrection: correctionWithoutAst } = + correctQueryWithoutAst(query); + const { output: corrected, corrections } = correctQueryWithAst(outputWithoutAst); + return { + input: query, + output: corrected, + isCorrection: correctionWithoutAst || corrections.length > 0, + }; +}; diff --git a/x-pack/plugins/inference/common/tasks/nl_to_esql/correct_query_with_actions.test.ts b/x-pack/plugins/inference/common/tasks/nl_to_esql/correct_query_with_actions.test.ts deleted file mode 100644 index 818f4854e038d..0000000000000 --- a/x-pack/plugins/inference/common/tasks/nl_to_esql/correct_query_with_actions.test.ts +++ /dev/null @@ -1,46 +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 { correctQueryWithActions } from './correct_query_with_actions'; - -describe('correctQueryWithActions', () => { - it(`fixes errors correctly for a query with one syntax error for stats`, async () => { - const fixedQuery = await correctQueryWithActions('from logstash-* | stats aveg(bytes)'); - expect(fixedQuery).toBe('from logstash-* | stats avg(bytes)'); - }); - - it(`fixes errors correctly for a query with 2 syntax errors for stats`, async () => { - const fixedQuery = await correctQueryWithActions( - 'from logstash-* | stats aveg(bytes), max2(bytes)' - ); - expect(fixedQuery).toBe('from logstash-* | stats avg(bytes), max(bytes)'); - }); - - it(`fixes errors correctly for a query with one syntax error for eval`, async () => { - const fixedQuery = await correctQueryWithActions( - 'from logstash-* | stats var0 = max(bytes) | eval ab(var0) | limit 1' - ); - expect(fixedQuery).toBe('from logstash-* | stats var0 = max(bytes) | eval abs(var0) | limit 1'); - }); - - it(`fixes errors correctly for a query with two syntax error for eval`, async () => { - const fixedQuery = await correctQueryWithActions( - 'from logstash-* | stats var0 = max2(bytes) | eval ab(var0) | limit 1' - ); - expect(fixedQuery).toBe('from logstash-* | stats var0 = max(bytes) | eval abs(var0) | limit 1'); - }); - - it(`doesnt complain for @timestamp column`, async () => { - const queryWithTimestamp = `FROM logstash-* - | WHERE @timestamp >= NOW() - 15 minutes - | EVAL bucket = DATE_TRUNC(1 minute, @timestamp) - | STATS avg_cpu = AVG(system.cpu.total.norm.pct) BY service.name, bucket - | SORT avg_cpu DESC - | LIMIT 10`; - const fixedQuery = await correctQueryWithActions(queryWithTimestamp); - expect(fixedQuery).toBe(queryWithTimestamp); - }); -}); diff --git a/x-pack/plugins/inference/common/tasks/nl_to_esql/correct_query_with_actions.ts b/x-pack/plugins/inference/common/tasks/nl_to_esql/correct_query_with_actions.ts deleted file mode 100644 index 30e2c11adb6de..0000000000000 --- a/x-pack/plugins/inference/common/tasks/nl_to_esql/correct_query_with_actions.ts +++ /dev/null @@ -1,63 +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 { validateQuery, getActions } from '@kbn/esql-validation-autocomplete'; -import { getAstAndSyntaxErrors } from '@kbn/esql-ast'; - -const fixedQueryByOneAction = async (queryString: string) => { - const { errors } = await validateQuery(queryString, getAstAndSyntaxErrors, { - ignoreOnMissingCallbacks: true, - }); - - const actions = await getActions(queryString, errors, getAstAndSyntaxErrors, { - relaxOnMissingCallbacks: true, - }); - - if (actions.length) { - const [firstAction] = actions; - const range = firstAction.edits[0].range; - const correctText = firstAction.edits[0].text; - const problematicString = queryString.substring(range.startColumn - 1, range.endColumn - 1); - const fixedQuery = queryString.replace(problematicString, correctText); - - return { - query: fixedQuery, - shouldRunAgain: Boolean(actions.length), - }; - } - return { - query: queryString, - shouldRunAgain: false, - }; -}; - -/** - * @param queryString - * @returns corrected queryString - * The cases that are handled are: - * - Query stats / eval functions have typos e.g. aveg instead of avg - * - Unquoted fields e.g. keep field-1 instead of keep `field-1` - * - Unquoted fields in stats or eval e.g. stats avg(field-1) instead of stats avg(`field-1`) - * - Combination of the above - */ - -export const correctQueryWithActions = async (queryString: string) => { - let shouldCorrectQuery = true; - let fixedQuery = queryString; - // this is an escape hatch, the loop will end automatically if the ast doesnt return more actions - // in case it goes wrong, we allow it to loop 10 times - let limit = 10; - - while (shouldCorrectQuery && limit >= 0) { - const { query, shouldRunAgain } = await fixedQueryByOneAction(fixedQuery); - shouldCorrectQuery = shouldRunAgain; - fixedQuery = query; - limit--; - } - - return fixedQuery; -}; diff --git a/x-pack/plugins/inference/common/tasks/nl_to_esql/get_errors_with_commands.test.ts b/x-pack/plugins/inference/common/tasks/nl_to_esql/get_errors_with_commands.test.ts deleted file mode 100644 index 04d99aede62b8..0000000000000 --- a/x-pack/plugins/inference/common/tasks/nl_to_esql/get_errors_with_commands.test.ts +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ -import { getErrorsWithCommands } from './get_errors_with_commands'; - -describe('getErrorsWithCommands', () => { - it('returns the command associated with the error', () => { - expect( - getErrorsWithCommands(`FROM logs-* | WHERE @timestamp <= NOW() | STATS BY host.name`, [ - { - type: 'error', - text: 'Syntax error', - code: '', - location: { - min: 24, - max: 36, - }, - }, - ]) - ).toEqual(['Error in `| WHERE @timestamp <= NOW()`:\n Syntax error']); - }); -}); diff --git a/x-pack/plugins/inference/common/tasks/nl_to_esql/get_errors_with_commands.ts b/x-pack/plugins/inference/common/tasks/nl_to_esql/get_errors_with_commands.ts deleted file mode 100644 index b25c79161f79b..0000000000000 --- a/x-pack/plugins/inference/common/tasks/nl_to_esql/get_errors_with_commands.ts +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import type { EditorError, ESQLMessage } from '@kbn/esql-ast'; -import { splitIntoCommands } from './correct_common_esql_mistakes'; - -export function getErrorsWithCommands(query: string, errors: Array) { - const asCommands = splitIntoCommands(query); - - const errorMessages = errors.map((error) => { - if ('location' in error) { - const commandsUntilEndOfError = splitIntoCommands(query.substring(0, error.location.max)); - const lastCompleteCommand = asCommands[commandsUntilEndOfError.length - 1]; - if (lastCompleteCommand) { - return `Error in \`| ${lastCompleteCommand.command}\`:\n ${error.text}`; - } - } - return 'text' in error ? error.text : error.message; - }); - - return errorMessages; -} diff --git a/x-pack/plugins/inference/common/tasks/nl_to_esql/index.ts b/x-pack/plugins/inference/common/tasks/nl_to_esql/index.ts new file mode 100644 index 0000000000000..2efacc374e8cd --- /dev/null +++ b/x-pack/plugins/inference/common/tasks/nl_to_esql/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 { correctCommonEsqlMistakes } from './correct_esql_query'; +export { splitIntoCommands } from './non_ast'; diff --git a/x-pack/plugins/inference/common/tasks/nl_to_esql/correct_common_esql_mistakes.test.ts b/x-pack/plugins/inference/common/tasks/nl_to_esql/non_ast/correct_common_esql_mistakes.test.ts similarity index 99% rename from x-pack/plugins/inference/common/tasks/nl_to_esql/correct_common_esql_mistakes.test.ts rename to x-pack/plugins/inference/common/tasks/nl_to_esql/non_ast/correct_common_esql_mistakes.test.ts index 8c6b90bca76ab..9d4b064b35f61 100644 --- a/x-pack/plugins/inference/common/tasks/nl_to_esql/correct_common_esql_mistakes.test.ts +++ b/x-pack/plugins/inference/common/tasks/nl_to_esql/non_ast/correct_common_esql_mistakes.test.ts @@ -4,6 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ + import { correctCommonEsqlMistakes } from './correct_common_esql_mistakes'; describe('correctCommonEsqlMistakes', () => { diff --git a/x-pack/plugins/inference/common/tasks/nl_to_esql/correct_common_esql_mistakes.ts b/x-pack/plugins/inference/common/tasks/nl_to_esql/non_ast/correct_common_esql_mistakes.ts similarity index 100% rename from x-pack/plugins/inference/common/tasks/nl_to_esql/correct_common_esql_mistakes.ts rename to x-pack/plugins/inference/common/tasks/nl_to_esql/non_ast/correct_common_esql_mistakes.ts diff --git a/x-pack/plugins/inference/common/tasks/nl_to_esql/non_ast/index.ts b/x-pack/plugins/inference/common/tasks/nl_to_esql/non_ast/index.ts new file mode 100644 index 0000000000000..2752f82ce9c43 --- /dev/null +++ b/x-pack/plugins/inference/common/tasks/nl_to_esql/non_ast/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 { correctCommonEsqlMistakes, splitIntoCommands } from './correct_common_esql_mistakes'; diff --git a/x-pack/plugins/inference/scripts/load_esql_docs/load_esql_docs.ts b/x-pack/plugins/inference/scripts/load_esql_docs/load_esql_docs.ts index a35491a476040..fba1d75956bf0 100644 --- a/x-pack/plugins/inference/scripts/load_esql_docs/load_esql_docs.ts +++ b/x-pack/plugins/inference/scripts/load_esql_docs/load_esql_docs.ts @@ -13,7 +13,7 @@ import Path from 'path'; import yargs, { Argv } from 'yargs'; import { REPO_ROOT } from '@kbn/repo-info'; import { INLINE_ESQL_QUERY_REGEX } from '../../common/tasks/nl_to_esql/constants'; -import { correctCommonEsqlMistakes } from '../../common/tasks/nl_to_esql/correct_common_esql_mistakes'; +import { correctCommonEsqlMistakes } from '../../common/tasks/nl_to_esql'; import { connectorIdOption, elasticsearchOption, kibanaOption } from '../util/cli_options'; import { getServiceUrls } from '../util/get_service_urls'; import { KibanaClient } from '../util/kibana_client'; diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/validate_esql_query.ts b/x-pack/plugins/inference/server/tasks/nl_to_esql/validate_esql_query.ts index 823344f52a891..049e627303d1b 100644 --- a/x-pack/plugins/inference/server/tasks/nl_to_esql/validate_esql_query.ts +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/validate_esql_query.ts @@ -11,7 +11,7 @@ import type { ElasticsearchClient } from '@kbn/core/server'; import { ESQLSearchResponse, ESQLRow } from '@kbn/es-types'; import { esFieldTypeToKibanaFieldType } from '@kbn/field-types'; import { DatatableColumn, DatatableColumnType } from '@kbn/expressions-plugin/common'; -import { splitIntoCommands } from '../../../common/tasks/nl_to_esql/correct_common_esql_mistakes'; +import { splitIntoCommands } from '../../../common'; export async function runAndValidateEsqlQuery({ query, diff --git a/x-pack/plugins/integration_assistant/common/api/generation_error.test.ts b/x-pack/plugins/integration_assistant/common/api/generation_error.test.ts new file mode 100644 index 0000000000000..b18414610664c --- /dev/null +++ b/x-pack/plugins/integration_assistant/common/api/generation_error.test.ts @@ -0,0 +1,63 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor 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 { GenerationErrorCode } from '../constants'; +import { isGenerationErrorBody } from './generation_error'; +import type { GenerationErrorBody } from './generation_error'; + +describe('isGenerationErrorBody', () => { + it('should return true for a valid GenerationErrorBody object', () => { + const validErrorBody: GenerationErrorBody = { + message: 'An error occurred', + attributes: { + errorCode: GenerationErrorCode.CEF_ERROR, + underlyingMessages: ['Error message 1', 'Error message 2'], + }, + }; + + expect(isGenerationErrorBody(validErrorBody)).toBe(true); + }); + + it('should return false for an object without a message', () => { + const invalidErrorBody = { + attributes: { + errorCode: 'ERROR_CODE', + underlyingMessages: ['Error message 1', 'Error message 2'], + }, + }; + + expect(isGenerationErrorBody(invalidErrorBody)).toBe(false); + }); + + it('should return false for an object without attributes', () => { + const invalidErrorBody = { + message: 'An error occurred', + }; + + expect(isGenerationErrorBody(invalidErrorBody)).toBe(false); + }); + + it('should return false for an object with invalid attributes', () => { + const invalidErrorBody = { + message: 'An error occurred', + attributes: { + errorCode: 123, // errorCode should be a string + underlyingMessages: 'Error message', // underlyingMessages should be an array + }, + }; + + expect(isGenerationErrorBody(invalidErrorBody)).toBe(false); + }); + + it('should return false for a non-object value', () => { + expect(isGenerationErrorBody(null)).toBe(false); + expect(isGenerationErrorBody(undefined)).toBe(false); + expect(isGenerationErrorBody('string')).toBe(false); + expect(isGenerationErrorBody(123)).toBe(false); + expect(isGenerationErrorBody(true)).toBe(false); + }); +}); diff --git a/x-pack/plugins/integration_assistant/common/api/generation_error.ts b/x-pack/plugins/integration_assistant/common/api/generation_error.ts index e96ad8bff9b59..03f01e96bee53 100644 --- a/x-pack/plugins/integration_assistant/common/api/generation_error.ts +++ b/x-pack/plugins/integration_assistant/common/api/generation_error.ts @@ -13,6 +13,12 @@ export interface GenerationErrorBody { attributes: GenerationErrorAttributes; } +export interface ErrorMessageWithLink { + link: string; + linkText: string; + errorMessage: string; +} + export function isGenerationErrorBody(obj: unknown | undefined): obj is GenerationErrorBody { return ( typeof obj === 'object' && @@ -27,7 +33,8 @@ export function isGenerationErrorBody(obj: unknown | undefined): obj is Generati export interface GenerationErrorAttributes { errorCode: GenerationErrorCode; - underlyingMessages: string[] | undefined; + underlyingMessages?: string[] | undefined; + errorMessageWithLink?: ErrorMessageWithLink | undefined; } export function isGenerationErrorAttributes(obj: unknown): obj is GenerationErrorAttributes { diff --git a/x-pack/plugins/integration_assistant/common/api/model/common_attributes.gen.ts b/x-pack/plugins/integration_assistant/common/api/model/common_attributes.gen.ts index 803f9b8a6c3af..3b8dac7af22ca 100644 --- a/x-pack/plugins/integration_assistant/common/api/model/common_attributes.gen.ts +++ b/x-pack/plugins/integration_assistant/common/api/model/common_attributes.gen.ts @@ -84,6 +84,7 @@ export const SamplesFormatName = z.enum([ 'structured', 'unstructured', 'unsupported', + 'cef', ]); export type SamplesFormatNameEnum = typeof SamplesFormatName.enum; export const SamplesFormatNameEnum = SamplesFormatName.enum; diff --git a/x-pack/plugins/integration_assistant/common/api/model/common_attributes.schema.yaml b/x-pack/plugins/integration_assistant/common/api/model/common_attributes.schema.yaml index 900b6e362a754..23ad137d8d83a 100644 --- a/x-pack/plugins/integration_assistant/common/api/model/common_attributes.schema.yaml +++ b/x-pack/plugins/integration_assistant/common/api/model/common_attributes.schema.yaml @@ -64,6 +64,7 @@ components: - structured - unstructured - unsupported + - cef SamplesFormat: type: object diff --git a/x-pack/plugins/integration_assistant/common/constants.ts b/x-pack/plugins/integration_assistant/common/constants.ts index 4d791341e34f9..3026101ebf54d 100644 --- a/x-pack/plugins/integration_assistant/common/constants.ts +++ b/x-pack/plugins/integration_assistant/common/constants.ts @@ -35,6 +35,7 @@ export enum GenerationErrorCode { RECURSION_LIMIT_ANALYZE_LOGS = 'recursion-limit-analyze-logs', UNSUPPORTED_LOG_SAMPLES_FORMAT = 'unsupported-log-samples-format', UNPARSEABLE_CSV_DATA = 'unparseable-csv-data', + CEF_ERROR = 'cef-not-supported', } // Size limits diff --git a/x-pack/plugins/integration_assistant/public/components/create_integration/create_integration_assistant/steps/data_stream_step/error_with_link.test.tsx b/x-pack/plugins/integration_assistant/public/components/create_integration/create_integration_assistant/steps/data_stream_step/error_with_link.test.tsx new file mode 100644 index 0000000000000..105bacf45e92c --- /dev/null +++ b/x-pack/plugins/integration_assistant/public/components/create_integration/create_integration_assistant/steps/data_stream_step/error_with_link.test.tsx @@ -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 React from 'react'; +import { render } from '@testing-library/react'; +import { ErrorMessage, isErrorMessageWithLink, MessageLink } from './error_with_link'; + +describe('isErrorMessageWithLink', () => { + it('should return true when error is an ErrorMessageWithLink', () => { + const error = { + link: 'http://example.com', + errorMessage: 'An error occurred', + linkText: 'decode_cef', + }; + expect(isErrorMessageWithLink(error)).toBe(true); + }); + + it('should return false when error is a string', () => { + const error = 'An error occurred'; + expect(isErrorMessageWithLink(error)).toBe(false); + }); + + describe('MessageLink', () => { + it('should render link with correct href and text', () => { + const { getByText } = render(); + const linkElement = getByText('decode_cef'); + expect(linkElement).toBeInTheDocument(); + expect(linkElement).toHaveAttribute('href', 'http://example.com'); + }); + }); + + describe('ErrorMessage', () => { + it('should render error message when error is a string', () => { + const error = 'An error occurred'; + const { getByText } = render(); + expect(getByText('An error occurred')).toBeInTheDocument(); + }); + }); +}); diff --git a/x-pack/plugins/integration_assistant/public/components/create_integration/create_integration_assistant/steps/data_stream_step/error_with_link.tsx b/x-pack/plugins/integration_assistant/public/components/create_integration/create_integration_assistant/steps/data_stream_step/error_with_link.tsx new file mode 100644 index 0000000000000..8791e9f03a0f8 --- /dev/null +++ b/x-pack/plugins/integration_assistant/public/components/create_integration/create_integration_assistant/steps/data_stream_step/error_with_link.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 { FormattedMessage } from '@kbn/i18n-react'; +import { EuiLink } from '@elastic/eui'; +import type { ErrorMessageWithLink } from '../../../../../../common/api/generation_error'; + +interface ErrorMessageProps { + error: string | null | ErrorMessageWithLink; +} + +interface MessageLinkProps { + link: string; + linkText: string; +} + +export const isErrorMessageWithLink = ( + error: string | ErrorMessageWithLink | null +): error is ErrorMessageWithLink => { + return ( + (error as ErrorMessageWithLink).link !== undefined && + (error as ErrorMessageWithLink).linkText !== undefined && + (error as ErrorMessageWithLink).errorMessage !== undefined + ); +}; + +export const MessageLink = React.memo(({ link, linkText }) => { + return ( + + {linkText} + + ); +}); +MessageLink.displayName = 'MessageLink'; + +export const ErrorMessage = React.memo(({ error }) => { + return ( + <> + {isErrorMessageWithLink(error) ? ( + , + }} + /> + ) : typeof error === 'string' ? ( + <>{error} + ) : null} + + ); +}); +ErrorMessage.displayName = 'ErrorMessage'; diff --git a/x-pack/plugins/integration_assistant/public/components/create_integration/create_integration_assistant/steps/data_stream_step/generation_modal.tsx b/x-pack/plugins/integration_assistant/public/components/create_integration/create_integration_assistant/steps/data_stream_step/generation_modal.tsx index ba57d83618c13..9d8d52a5b8783 100644 --- a/x-pack/plugins/integration_assistant/public/components/create_integration/create_integration_assistant/steps/data_stream_step/generation_modal.tsx +++ b/x-pack/plugins/integration_assistant/public/components/create_integration/create_integration_assistant/steps/data_stream_step/generation_modal.tsx @@ -28,6 +28,7 @@ import * as i18n from './translations'; import type { OnComplete, ProgressItem } from './use_generation'; import { ProgressOrder, useGeneration } from './use_generation'; +import { ErrorMessage } from './error_with_link'; const progressText: Record = { analyzeLogs: i18n.PROGRESS_ANALYZE_LOGS, @@ -87,7 +88,7 @@ export const GenerationModal = React.memo( iconType="alert" data-test-subj="generationErrorCallout" > - {error} + ) : ( diff --git a/x-pack/plugins/integration_assistant/public/components/create_integration/create_integration_assistant/steps/data_stream_step/translations.ts b/x-pack/plugins/integration_assistant/public/components/create_integration/create_integration_assistant/steps/data_stream_step/translations.ts index ec90568da0ef9..8f2aab49622f0 100644 --- a/x-pack/plugins/integration_assistant/public/components/create_integration/create_integration_assistant/steps/data_stream_step/translations.ts +++ b/x-pack/plugins/integration_assistant/public/components/create_integration/create_integration_assistant/steps/data_stream_step/translations.ts @@ -188,6 +188,13 @@ export const RETRY = i18n.translate('xpack.integrationAssistant.step.dataStream. defaultMessage: 'Retry', }); +export const DECODE_CEF_LINK = i18n.translate( + 'xpack.integrationAssistant.errors.cefFormat.decodeLink', + { + defaultMessage: 'CEF format not supported yet. Instead please use CEF Integration:', + } +); + export const GENERATION_ERROR_TRANSLATION: Record< GenerationErrorCode, string | ((attributes: GenerationErrorAttributes) => string) @@ -211,6 +218,11 @@ export const GENERATION_ERROR_TRANSLATION: Record< defaultMessage: 'Unsupported log format in the samples.', } ), + [GenerationErrorCode.CEF_ERROR]: i18n.translate('xpack.integrationAssistant.errors.cefError', { + // This is a default error message if the linking does not work. + defaultMessage: + 'CEF format detected. Please decode the CEF logs into JSON format using filebeat decode_cef processor.', + }), [GenerationErrorCode.UNPARSEABLE_CSV_DATA]: (attributes) => { if ( attributes.underlyingMessages !== undefined && diff --git a/x-pack/plugins/integration_assistant/public/components/create_integration/create_integration_assistant/steps/data_stream_step/use_generation.tsx b/x-pack/plugins/integration_assistant/public/components/create_integration/create_integration_assistant/steps/data_stream_step/use_generation.tsx index 566451d624c5e..de6b2eed038ec 100644 --- a/x-pack/plugins/integration_assistant/public/components/create_integration/create_integration_assistant/steps/data_stream_step/use_generation.tsx +++ b/x-pack/plugins/integration_assistant/public/components/create_integration/create_integration_assistant/steps/data_stream_step/use_generation.tsx @@ -28,6 +28,8 @@ import type { State } from '../../state'; import * as i18n from './translations'; import { useTelemetry } from '../../../telemetry'; import type { AIConnector, IntegrationSettings } from '../../types'; +import type { ErrorMessageWithLink } from '../../../../../../common/api/generation_error'; +import { GenerationErrorCode } from '../../../../../../common/constants'; export type OnComplete = (result: State['result']) => void; export const ProgressOrder = ['analyzeLogs', 'ecs', 'categorization', 'related'] as const; @@ -48,12 +50,23 @@ interface RunGenerationProps { // If the result is classified as a generation error, produce an error message // as defined in the i18n file. Otherwise, return undefined. -function generationErrorMessage(body: unknown | undefined): string | undefined { +function generationErrorMessage( + body: unknown | undefined +): string | ErrorMessageWithLink | undefined { if (!isGenerationErrorBody(body)) { return; } const errorCode = body.attributes.errorCode; + if (errorCode === GenerationErrorCode.CEF_ERROR) { + if (body.attributes.errorMessageWithLink !== undefined) { + return { + link: body.attributes.errorMessageWithLink.link, + errorMessage: i18n.DECODE_CEF_LINK, + linkText: body.attributes.errorMessageWithLink.linkText, + }; + } + } const translation = i18n.GENERATION_ERROR_TRANSLATION[errorCode]; return typeof translation === 'function' ? translation(body.attributes) : translation; } @@ -72,7 +85,7 @@ export const useGeneration = ({ const { reportGenerationComplete } = useTelemetry(); const { http, notifications } = useKibana().services; const [progress, setProgress] = useState(); - const [error, setError] = useState(null); + const [error, setError] = useState(null); const [isRequesting, setIsRequesting] = useState(true); useEffect(() => { diff --git a/x-pack/plugins/integration_assistant/server/graphs/log_type_detection/prompts.ts b/x-pack/plugins/integration_assistant/server/graphs/log_type_detection/prompts.ts index b6e777a87888a..09a7249a3786c 100644 --- a/x-pack/plugins/integration_assistant/server/graphs/log_type_detection/prompts.ts +++ b/x-pack/plugins/integration_assistant/server/graphs/log_type_detection/prompts.ts @@ -23,6 +23,7 @@ Follow these steps to do this: b. If there is no csv header then set "header: false" and try to find good names for the columns in the "columns" array by looking into the values of data in those columns. For each column, if you are unable to find good name candidate for it then output an empty string, like in the example. * 'structured': If the log samples have structured message body with key-value pairs then classify it as "name: structured". Look for a flat list of key-value pairs, often separated by some delimiters. Consider variations in formatting, such as quotes around values ("key=value", key="value"), special characters in keys or values, or escape sequences. * 'unstructured': If the log samples have unstructured body like a free-form text then classify it as "name: unstructured". + * 'cef': If the log samples have Common Event Format (CEF) then classify it as "name: cef". * 'unsupported': If you cannot put the format into any of the above categories then classify it with "name: unsupported". 2. Header: for structured and unstructured format: - if the samples have any or all of priority, timestamp, loglevel, hostname, ipAddress, messageId in the beginning information then set "header: true". diff --git a/x-pack/plugins/integration_assistant/server/lib/errors/cef_error.ts b/x-pack/plugins/integration_assistant/server/lib/errors/cef_error.ts new file mode 100644 index 0000000000000..16889b30c1a11 --- /dev/null +++ b/x-pack/plugins/integration_assistant/server/lib/errors/cef_error.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 { KibanaResponseFactory } from '@kbn/core/server'; +import { + GenerationErrorAttributes, + GenerationErrorBody, +} from '../../../common/api/generation_error'; +import { ErrorThatHandlesItsOwnResponse } from './types'; +import { GenerationErrorCode } from '../../../common/constants'; + +export class CefError extends Error implements ErrorThatHandlesItsOwnResponse { + private readonly errorCode: GenerationErrorCode = GenerationErrorCode.CEF_ERROR; + attributes: GenerationErrorAttributes; + + constructor(message: string) { + super(message); + this.attributes = { + errorCode: this.errorCode, + errorMessageWithLink: { + linkText: 'cef-integration', + link: 'https://www.elastic.co/docs/current/integrations/cef', + errorMessage: '', // Will be set using translation in the UI. + }, + }; + } + + public sendResponse(res: KibanaResponseFactory) { + const body: GenerationErrorBody = { + message: this.errorCode, + attributes: this.attributes, + }; + return res.customError({ + statusCode: 501, + body, + }); + } +} diff --git a/x-pack/plugins/integration_assistant/server/routes/analyze_logs_routes.ts b/x-pack/plugins/integration_assistant/server/routes/analyze_logs_routes.ts index 34f05fcc82025..37926dac19156 100644 --- a/x-pack/plugins/integration_assistant/server/routes/analyze_logs_routes.ts +++ b/x-pack/plugins/integration_assistant/server/routes/analyze_logs_routes.ts @@ -19,6 +19,7 @@ import { withAvailability } from './with_availability'; import { isErrorThatHandlesItsOwnResponse, UnsupportedLogFormatError } from '../lib/errors'; import { handleCustomErrors } from './routes_util'; import { GenerationErrorCode } from '../../common/constants'; +import { CefError } from '../lib/errors/cef_error'; export function registerAnalyzeLogsRoutes( router: IRouter @@ -102,9 +103,16 @@ export function registerAnalyzeLogsRoutes( .withConfig({ runName: 'Log Format' }) .invoke(logFormatParameters, options); const graphLogFormat = graphResults.results.samplesFormat.name; - if (graphLogFormat === 'unsupported') { - throw new UnsupportedLogFormatError(GenerationErrorCode.UNSUPPORTED_LOG_SAMPLES_FORMAT); + + switch (graphLogFormat) { + case 'unsupported': + throw new UnsupportedLogFormatError( + GenerationErrorCode.UNSUPPORTED_LOG_SAMPLES_FORMAT + ); + case 'cef': + throw new CefError(GenerationErrorCode.CEF_ERROR); } + return res.ok({ body: AnalyzeLogsResponse.parse(graphResults) }); } catch (err) { try { 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 54532360169fd..a4077b6919823 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 @@ -260,6 +260,7 @@ export function WorkspacePanelWrapper({ flexGrow: 0, height: '100%', width: '100%', + overflow: 'auto', ...visDimensionsCSS, }} > diff --git a/x-pack/plugins/lens/public/react_embeddable/data_loader.ts b/x-pack/plugins/lens/public/react_embeddable/data_loader.ts index 0aed3edf70b89..64b7ca4501b08 100644 --- a/x-pack/plugins/lens/public/react_embeddable/data_loader.ts +++ b/x-pack/plugins/lens/public/react_embeddable/data_loader.ts @@ -226,7 +226,7 @@ export function loadEmbeddableData( handleEvent, disableTriggers, updateBlockingErrors, - renderCount: internalApi.renderCount$.getValue(), + getDisplayOptions: internalApi.getDisplayOptions, }), getUsedDataViews( currentState.attributes.references, diff --git a/x-pack/plugins/lens/public/react_embeddable/expressions/expression_params.ts b/x-pack/plugins/lens/public/react_embeddable/expressions/expression_params.ts index e10dded4ad8f9..ff6206f3f70e4 100644 --- a/x-pack/plugins/lens/public/react_embeddable/expressions/expression_params.ts +++ b/x-pack/plugins/lens/public/react_embeddable/expressions/expression_params.ts @@ -24,6 +24,7 @@ import { IndexPatternMap, IndexPatternRef, UserMessage, + VisualizationDisplayOptions, isLensFilterEvent, isLensMultiFilterEvent, isLensTableRowContextMenuClickEvent, @@ -61,7 +62,7 @@ interface GetExpressionRendererPropsParams { api: LensApi; addUserMessages: (messages: UserMessage[]) => void; updateBlockingErrors: (error: Error) => void; - renderCount: number; + getDisplayOptions: () => VisualizationDisplayOptions; } async function getExpressionFromDocument( @@ -146,7 +147,7 @@ export async function getExpressionRendererParams( addUserMessages, updateBlockingErrors, searchContext, - renderCount, + getDisplayOptions, }: GetExpressionRendererPropsParams ): Promise<{ params: ExpressionWrapperProps | null; @@ -215,7 +216,7 @@ export async function getExpressionRendererParams( variables: getVariables(api, state), style: state.style, className: state.className, - noPadding: state.noPadding, + noPadding: getDisplayOptions().noPadding, }; return { indexPatterns, diff --git a/x-pack/plugins/lens/public/react_embeddable/initializers/initialize_dashboard_services.ts b/x-pack/plugins/lens/public/react_embeddable/initializers/initialize_dashboard_services.ts index d030a92a02b59..67a5d3a89a1c2 100644 --- a/x-pack/plugins/lens/public/react_embeddable/initializers/initialize_dashboard_services.ts +++ b/x-pack/plugins/lens/public/react_embeddable/initializers/initialize_dashboard_services.ts @@ -16,7 +16,7 @@ import { getUnchangingComparator, initializeTitles, } from '@kbn/presentation-publishing'; -import { apiPublishesSettings } from '@kbn/presentation-containers'; +import { apiIsPresentationContainer, apiPublishesSettings } from '@kbn/presentation-containers'; import { buildObservableVariable, isTextBasedLanguage } from '../helper'; import type { LensComponentProps, @@ -27,6 +27,7 @@ import type { LensSharedProps, IntegrationCallbacks, LensInternalApi, + LensApi, } from '../types'; import { apiHasLensComponentProps } from '../type_guards'; import { StateManagementConfig } from './initialize_state_management'; @@ -39,9 +40,12 @@ export interface DashboardServicesConfig { PublishesWritablePanelDescription & HasInPlaceLibraryTransforms & HasLibraryTransforms & + Pick & Pick; serialize: () => SerializedProps; - comparators: StateComparators; + comparators: StateComparators< + SerializedProps & Pick & { isNewPanel?: boolean } + >; cleanup: () => void; } @@ -78,6 +82,7 @@ export function initializeDashboardServices( return { api: { + parentApi: apiIsPresentationContainer(parentApi) ? parentApi : undefined, defaultPanelTitle: defaultPanelTitle$, defaultPanelDescription: defaultPanelDescription$, ...titlesApi, @@ -142,7 +147,7 @@ export function initializeDashboardServices( }, }, serialize: () => { - const { style, noPadding, className } = apiHasLensComponentProps(parentApi) + const { style, className } = apiHasLensComponentProps(parentApi) ? parentApi : ({} as LensComponentProps); const settings = apiPublishesSettings(parentApi) @@ -155,7 +160,6 @@ export function initializeDashboardServices( return { ...serializeTitles(), style, - noPadding, className, ...settings, palette: initialState.palette, @@ -179,6 +183,7 @@ export function initializeDashboardServices( overrides: overridesComparator, disableTriggers: disabledTriggersComparator, isNewPanel: getUnchangingComparator<{ isNewPanel?: boolean }, 'isNewPanel'>(), + parentApi: getUnchangingComparator, 'parentApi'>(), }, cleanup: noop, }; diff --git a/x-pack/plugins/lens/public/react_embeddable/initializers/initialize_internal_api.ts b/x-pack/plugins/lens/public/react_embeddable/initializers/initialize_internal_api.ts index 2bdc00b3124a2..e366c24a6c0e0 100644 --- a/x-pack/plugins/lens/public/react_embeddable/initializers/initialize_internal_api.ts +++ b/x-pack/plugins/lens/public/react_embeddable/initializers/initialize_internal_api.ts @@ -6,21 +6,25 @@ */ import { BehaviorSubject } from 'rxjs'; +import { initializeTitles } from '@kbn/presentation-publishing'; import type { DataView } from '@kbn/data-views-plugin/common'; import { buildObservableVariable, createEmptyLensState } from '../helper'; import type { ExpressionWrapperProps, + LensEmbeddableStartServices, LensInternalApi, LensOverrides, LensRuntimeState, } from '../types'; -import { apiHasAbortController } from '../type_guards'; +import { apiHasAbortController, apiHasLensComponentProps } from '../type_guards'; import type { UserMessage } from '../../types'; export function initializeInternalApi( initialState: LensRuntimeState, - parentApi: unknown + parentApi: unknown, + { visualizationMap }: LensEmbeddableStartServices ): LensInternalApi { + const { titlesApi } = initializeTitles(initialState); const [hasRenderCompleted$] = buildObservableVariable(false); const [expressionParams$] = buildObservableVariable(null); const expressionAbortController$ = new BehaviorSubject(undefined); @@ -87,5 +91,30 @@ export function initializeInternalApi( validationMessages$.next([]); }, setAsCreated: () => isNewlyCreated$.next(false), + getDisplayOptions: () => { + const latestAttributes = attributes$.getValue(); + if (!latestAttributes.visualizationType) { + return {}; + } + + let displayOptions = + visualizationMap[latestAttributes.visualizationType]?.getDisplayOptions?.() ?? {}; + + if (apiHasLensComponentProps(parentApi) && parentApi.noPadding != null) { + displayOptions = { + ...displayOptions, + noPadding: parentApi.noPadding, + }; + } + + if (displayOptions.noPanelTitle == null && titlesApi.hidePanelTitle?.getValue()) { + displayOptions = { + ...displayOptions, + noPanelTitle: true, + }; + } + + return displayOptions; + }, }; } diff --git a/x-pack/plugins/lens/public/react_embeddable/lens_embeddable.tsx b/x-pack/plugins/lens/public/react_embeddable/lens_embeddable.tsx index 8c17063f97a2e..074ae451115b5 100644 --- a/x-pack/plugins/lens/public/react_embeddable/lens_embeddable.tsx +++ b/x-pack/plugins/lens/public/react_embeddable/lens_embeddable.tsx @@ -59,7 +59,7 @@ export const createLensEmbeddableFactory = ( * Observables and functions declared here are used internally to store mutating state values * This is an internal API not exposed outside of the embeddable. */ - const internalApi = initializeInternalApi(initialState, parentApi); + const internalApi = initializeInternalApi(initialState, parentApi, services); const visualizationContextHelper = initializeVisualizationContext(internalApi); diff --git a/x-pack/plugins/lens/public/react_embeddable/mocks/index.tsx b/x-pack/plugins/lens/public/react_embeddable/mocks/index.tsx index 0b64b84f7a740..ddcd5e6089592 100644 --- a/x-pack/plugins/lens/public/react_embeddable/mocks/index.tsx +++ b/x-pack/plugins/lens/public/react_embeddable/mocks/index.tsx @@ -309,6 +309,7 @@ const LensInternalApiMock: LensInternalApi = { dispatchError: jest.fn(), updateValidationMessages: jest.fn(), setAsCreated: jest.fn(), + getDisplayOptions: jest.fn(() => ({})), }; export function getLensInternalApiMock(overrides: Partial = {}): LensInternalApi { diff --git a/x-pack/plugins/lens/public/react_embeddable/renderer/lens_embeddable_component.test.tsx b/x-pack/plugins/lens/public/react_embeddable/renderer/lens_embeddable_component.test.tsx index 04c3511ab3d4f..f444f429250ba 100644 --- a/x-pack/plugins/lens/public/react_embeddable/renderer/lens_embeddable_component.test.tsx +++ b/x-pack/plugins/lens/public/react_embeddable/renderer/lens_embeddable_component.test.tsx @@ -13,6 +13,12 @@ import { PublishingSubject } from '@kbn/presentation-publishing'; import React from 'react'; import { LensEmbeddableComponent } from './lens_embeddable_component'; +jest.mock('../expression_wrapper', () => ({ + ExpressionWrapper: () => ( +
        + ), +})); + type GetValueType = Type extends PublishingSubject ? X : never; function getDefaultProps({ @@ -39,4 +45,17 @@ describe('Lens Embeddable component', () => { render(); expect(screen.queryByTestId('lens-embeddable')).not.toBeInTheDocument(); }); + + it('shoud not render the title if the visualization forces the title to be hidden', () => { + const getDisplayOptions = jest.fn(() => ({ noPanelTitle: true })); + const props = getDefaultProps({ + internalApiOverrides: { + getDisplayOptions, + }, + }); + + render(); + expect(props.internalApi.getDisplayOptions).toHaveBeenCalled(); + expect(screen.getByTestId('lens-embeddable').parentElement).not.toHaveAttribute('data-title'); + }); }); diff --git a/x-pack/plugins/lens/public/react_embeddable/renderer/lens_embeddable_component.tsx b/x-pack/plugins/lens/public/react_embeddable/renderer/lens_embeddable_component.tsx index d4ae4516ee930..122891788a808 100644 --- a/x-pack/plugins/lens/public/react_embeddable/renderer/lens_embeddable_component.tsx +++ b/x-pack/plugins/lens/public/react_embeddable/renderer/lens_embeddable_component.tsx @@ -57,7 +57,7 @@ export function LensEmbeddableComponent({ const rootRef = useDispatcher(hasRendered, api); // Publish the data attributes only if avaialble/visible - const title = api.hidePanelTitle?.getValue() + const title = internalApi.getDisplayOptions()?.noPanelTitle ? undefined : { 'data-title': api.panelTitle?.getValue() ?? api.defaultPanelTitle?.getValue() }; const description = api.panelDescription?.getValue() diff --git a/x-pack/plugins/lens/public/react_embeddable/types.ts b/x-pack/plugins/lens/public/react_embeddable/types.ts index 6f01947d41bf3..c860c543570c1 100644 --- a/x-pack/plugins/lens/public/react_embeddable/types.ts +++ b/x-pack/plugins/lens/public/react_embeddable/types.ts @@ -17,6 +17,7 @@ import type { HasEditCapabilities, HasInPlaceLibraryTransforms, HasLibraryTransforms, + HasParentApi, HasSupportedTriggers, PublishesBlockingError, PublishesDataLoading, @@ -63,6 +64,7 @@ import type { AllowedGaugeOverrides } from '@kbn/expression-gauge-plugin/common' import type { AllowedPartitionOverrides } from '@kbn/expression-partition-vis-plugin/common'; import type { AllowedXYOverrides } from '@kbn/expression-xy-plugin/common'; import type { Action } from '@kbn/ui-actions-plugin/public'; +import { PresentationContainer } from '@kbn/presentation-containers'; import type { LegacyMetricState } from '../../common'; import type { LensDocument } from '../persistence'; import type { LensInspector } from '../lens_inspector_service'; @@ -81,6 +83,7 @@ import type { SharingSavedObjectProps, Simplify, UserMessage, + VisualizationDisplayOptions, VisualizationMap, } from '../types'; import type { LensPluginStartDependencies } from '../plugin'; @@ -276,7 +279,7 @@ export type LensSerializedState = Simplify< LensUnifiedSearchContext & LensPanelProps & SerializedTitles & - LensSharedProps & + Omit & Partial & { isNewPanel?: boolean } >; @@ -378,6 +381,8 @@ export type LensApi = Simplify< HasLibraryTransforms & // Let the container know the view mode PublishesViewMode & + // forward the parentApi, note that will be exposed only if it satisfy the PresentationContainer interface + Partial> & // Let the container know the saved object id PublishesSavedObjectId & // Lens specific API methods: @@ -414,6 +419,7 @@ export type LensInternalApi = Simplify< validationMessages$: PublishingSubject; updateValidationMessages: (newMessages: UserMessage[]) => void; resetAllMessages: () => void; + getDisplayOptions: () => VisualizationDisplayOptions; } >; diff --git a/x-pack/plugins/ml/common/constants/alerts.ts b/x-pack/plugins/ml/common/constants/alerts.ts index 009345d23542d..8ed9d61b418ff 100644 --- a/x-pack/plugins/ml/common/constants/alerts.ts +++ b/x-pack/plugins/ml/common/constants/alerts.ts @@ -12,6 +12,7 @@ import { ALERT_RULE_NAME, ALERT_START, ALERT_STATUS, + AlertConsumers, ML_ANOMALY_DETECTION_RULE_TYPE_ID, } from '@kbn/rule-data-utils'; import type { JobsHealthTests } from '../types/alerts'; @@ -21,6 +22,9 @@ export const ML_ALERT_TYPES = { AD_JOBS_HEALTH: 'xpack.ml.anomaly_detection_jobs_health', } as const; +export const ML_RULE_TYPE_IDS = Object.values(ML_ALERT_TYPES); +export const ML_VALID_CONSUMERS = [AlertConsumers.ML, AlertConsumers.ALERTS]; + export type MlAlertType = (typeof ML_ALERT_TYPES)[keyof typeof ML_ALERT_TYPES]; export const ALERT_PREVIEW_SAMPLE_SIZE = 5; diff --git a/x-pack/plugins/ml/common/index.ts b/x-pack/plugins/ml/common/index.ts index bc53fc4247f2d..dbb6c1a54ca16 100644 --- a/x-pack/plugins/ml/common/index.ts +++ b/x-pack/plugins/ml/common/index.ts @@ -8,5 +8,5 @@ export { getDefaultCapabilities as getDefaultMlCapabilities } from './types/capabilities'; export { DATAFEED_STATE, JOB_STATE } from './constants/states'; export type { MlSummaryJob, SummaryJobState } from './types/anomaly_detection_jobs'; -export { ML_ALERT_TYPES } from './constants/alerts'; +export { ML_ALERT_TYPES, ML_RULE_TYPE_IDS } from './constants/alerts'; export type { Job, Datafeed } from './types/anomaly_detection_jobs'; diff --git a/x-pack/plugins/ml/common/types/capabilities.ts b/x-pack/plugins/ml/common/types/capabilities.ts index e7a097fae7dc4..b598a3bfd4d2d 100644 --- a/x-pack/plugins/ml/common/types/capabilities.ts +++ b/x-pack/plugins/ml/common/types/capabilities.ts @@ -6,6 +6,7 @@ */ import type { KibanaRequest } from '@kbn/core/server'; +import { ALERTING_FEATURE_ID } from '@kbn/alerting-plugin/common'; import { PLUGIN_ID } from '../constants/app'; import { ML_JOB_SAVED_OBJECT_TYPE, @@ -109,6 +110,11 @@ export function getDefaultCapabilities(): MlCapabilities { }; } +const alertingFeatures = Object.values(ML_ALERT_TYPES).map((ruleTypeId) => ({ + ruleTypeId, + consumers: [PLUGIN_ID, ALERTING_FEATURE_ID], +})); + export function getPluginPrivileges() { const apmUserMlCapabilitiesKeys = Object.keys(apmUserMlCapabilities); const userMlCapabilitiesKeys = Object.keys(userMlCapabilities); @@ -150,10 +156,10 @@ export function getPluginPrivileges() { }, alerting: { rule: { - all: Object.values(ML_ALERT_TYPES), + all: alertingFeatures, }, alert: { - all: Object.values(ML_ALERT_TYPES), + all: alertingFeatures, }, }, }, @@ -172,10 +178,10 @@ export function getPluginPrivileges() { }, alerting: { rule: { - read: Object.values(ML_ALERT_TYPES), + read: alertingFeatures, }, alert: { - read: Object.values(ML_ALERT_TYPES), + read: alertingFeatures, }, }, }, diff --git a/x-pack/plugins/ml/kibana.jsonc b/x-pack/plugins/ml/kibana.jsonc index 274a92c57a2c3..5c4961de54e97 100644 --- a/x-pack/plugins/ml/kibana.jsonc +++ b/x-pack/plugins/ml/kibana.jsonc @@ -63,7 +63,8 @@ "lens", "maps", "savedObjectsFinder", - "usageCollection" + "usageCollection", + "alerting" ], "extraPublicDirs": [ "common" 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 d06c46cc6f71e..01f4d2d7be74f 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 @@ -60,6 +60,7 @@ export const LogRateAnalysisPage: FC = () => { 'unifiedSearch', 'observabilityAIAssistant', 'embeddable', + 'cases', ]), }} /> diff --git a/x-pack/plugins/ml/public/application/explorer/alerts/alerts_panel.tsx b/x-pack/plugins/ml/public/application/explorer/alerts/alerts_panel.tsx index b9b680a9fbac5..338c5a2a2b3c5 100644 --- a/x-pack/plugins/ml/public/application/explorer/alerts/alerts_panel.tsx +++ b/x-pack/plugins/ml/public/application/explorer/alerts/alerts_panel.tsx @@ -15,9 +15,12 @@ import { } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; -import { ALERT_STATUS_ACTIVE, AlertConsumers, type AlertStatus } from '@kbn/rule-data-utils'; +import { ALERT_STATUS_ACTIVE, type AlertStatus } from '@kbn/rule-data-utils'; +import type { AlertsTableStateProps } from '@kbn/triggers-actions-ui-plugin/public/application/sections/alerts_table/alerts_table_state'; import React, { type FC, useState } from 'react'; import useObservable from 'react-use/lib/useObservable'; +import { ML_VALID_CONSUMERS } from '../../../../common/constants/alerts'; +import { ML_RULE_TYPE_IDS } from '../../../../common'; import { ML_ALERTS_CONFIG_ID } from '../../../alerting/anomaly_detection_alerts_table/register_alerts_table_configuration'; import { CollapsiblePanel } from '../../components/collapsible_panel'; import { useMlKibana } from '../../contexts/kibana'; @@ -42,13 +45,13 @@ export const AlertsPanel: FC = () => { const alertsQuery = useObservable(anomalyDetectionAlertsStateService.alertsQuery$, {}); const isLoading = useObservable(anomalyDetectionAlertsStateService.isLoading$, true); - const alertStateProps = { + const alertStateProps: AlertsTableStateProps = { alertsTableConfigurationRegistry: triggersActionsUi!.alertsTableConfigurationRegistry, configurationId: ML_ALERTS_CONFIG_ID, id: `ml-details-alerts`, - featureIds: [AlertConsumers.ML], + ruleTypeIds: ML_RULE_TYPE_IDS, + consumers: ML_VALID_CONSUMERS, query: alertsQuery, - showExpandToDetails: true, showAlertStatusWithFlapping: true, cellContext: { fieldFormats, diff --git a/x-pack/plugins/ml/public/application/explorer/alerts/anomaly_detection_alerts_state_service.ts b/x-pack/plugins/ml/public/application/explorer/alerts/anomaly_detection_alerts_state_service.ts index d02e9baf91c95..82bd60a4802ab 100644 --- a/x-pack/plugins/ml/public/application/explorer/alerts/anomaly_detection_alerts_state_service.ts +++ b/x-pack/plugins/ml/public/application/explorer/alerts/anomaly_detection_alerts_state_service.ts @@ -21,7 +21,6 @@ import { ALERT_START, ALERT_STATUS, ALERT_UUID, - AlertConsumers, } from '@kbn/rule-data-utils'; import { isDefined } from '@kbn/ml-is-defined'; import { getSeverityColor } from '@kbn/ml-anomaly-utils'; @@ -30,6 +29,8 @@ import { ALERT_ANOMALY_SCORE, ALERT_ANOMALY_TIMESTAMP, ML_ALERT_TYPES, + ML_RULE_TYPE_IDS, + ML_VALID_CONSUMERS, } from '../../../../common/constants/alerts'; import { StateService } from '../../services/state_service'; import type { AnomalyTimelineStateService } from '../anomaly_timeline_state_service'; @@ -175,7 +176,8 @@ export class AnomalyDetectionAlertsStateService extends StateService { return this.data.search .search( { - featureIds: [AlertConsumers.ML], + ruleTypeIds: ML_RULE_TYPE_IDS, + consumers: ML_VALID_CONSUMERS, query, }, { strategy: 'privateRuleRegistryAlertsSearchStrategy' } diff --git a/x-pack/plugins/ml/server/plugin.ts b/x-pack/plugins/ml/server/plugin.ts index 01f3ec7e5d131..ba6c5387a93cb 100644 --- a/x-pack/plugins/ml/server/plugin.ts +++ b/x-pack/plugins/ml/server/plugin.ts @@ -26,6 +26,7 @@ import type { SpacesPluginSetup } from '@kbn/spaces-plugin/server'; import type { FieldFormatsStart } from '@kbn/field-formats-plugin/server'; import type { HomeServerPluginSetup } from '@kbn/home-plugin/server'; import type { CasesServerSetup } from '@kbn/cases-plugin/server'; +import { ALERTING_FEATURE_ID } from '@kbn/alerting-plugin/common'; import { KibanaFeatureScope } from '@kbn/features-plugin/common'; import type { PluginsSetup, PluginsStart, RouteInitialization } from './types'; import type { MlCapabilities } from '../common/types/capabilities'; @@ -142,7 +143,10 @@ export class MlServerPlugin management: { insightsAndAlerting: ['jobsListLink', 'triggersActions'], }, - alerting: Object.values(ML_ALERT_TYPES), + alerting: Object.values(ML_ALERT_TYPES).map((ruleTypeId) => ({ + ruleTypeId, + consumers: [PLUGIN_ID, ALERTING_FEATURE_ID], + })), privileges: { all: admin, read: user, diff --git a/x-pack/plugins/ml/server/routes/job_service.ts b/x-pack/plugins/ml/server/routes/job_service.ts index 3814d36bc3a6c..8c9f90db38186 100644 --- a/x-pack/plugins/ml/server/routes/job_service.ts +++ b/x-pack/plugins/ml/server/routes/job_service.ts @@ -135,7 +135,7 @@ export function jobServiceRoutes({ router, routeGuard }: RouteInitialization) { routeGuard.fullLicenseAPIGuard(async ({ client, mlClient, request, response, context }) => { try { const alerting = await context.alerting; - const rulesClient = alerting?.getRulesClient(); + const rulesClient = await alerting?.getRulesClient(); const { deleteJobs } = jobServiceProvider(client, mlClient, rulesClient); const { jobIds, deleteUserAnnotations, deleteAlertingRules } = request.body; @@ -283,7 +283,8 @@ export function jobServiceRoutes({ router, routeGuard }: RouteInitialization) { routeGuard.fullLicenseAPIGuard(async ({ client, mlClient, request, response, context }) => { try { const alerting = await context.alerting; - const { jobsSummary } = jobServiceProvider(client, mlClient, alerting?.getRulesClient()); + const rulesClient = await alerting?.getRulesClient(); + const { jobsSummary } = jobServiceProvider(client, mlClient, rulesClient); const { jobIds } = request.body; const resp = await jobsSummary(jobIds); @@ -317,11 +318,8 @@ export function jobServiceRoutes({ router, routeGuard }: RouteInitialization) { routeGuard.fullLicenseAPIGuard(async ({ client, mlClient, response, context }) => { try { const alerting = await context.alerting; - const { getJobIdsWithGeo } = jobServiceProvider( - client, - mlClient, - alerting?.getRulesClient() - ); + const rulesClient = await alerting?.getRulesClient(); + const { getJobIdsWithGeo } = jobServiceProvider(client, mlClient, rulesClient); const resp = await getJobIdsWithGeo(); @@ -425,11 +423,9 @@ export function jobServiceRoutes({ router, routeGuard }: RouteInitialization) { routeGuard.fullLicenseAPIGuard(async ({ client, mlClient, request, response, context }) => { try { const alerting = await context.alerting; - const { createFullJobsList } = jobServiceProvider( - client, - mlClient, - alerting?.getRulesClient() - ); + const rulesClient = await alerting?.getRulesClient(); + + const { createFullJobsList } = jobServiceProvider(client, mlClient, rulesClient); const { jobIds } = request.body; const resp = await createFullJobsList(jobIds); diff --git a/x-pack/plugins/monitoring/public/alerts/alert_form.test.tsx b/x-pack/plugins/monitoring/public/alerts/alert_form.test.tsx index 2cca4638876c9..f1e84753820fe 100644 --- a/x-pack/plugins/monitoring/public/alerts/alert_form.test.tsx +++ b/x-pack/plugins/monitoring/public/alerts/alert_form.test.tsx @@ -270,6 +270,7 @@ describe('alert_form', () => { actionTypeRegistry={actionTypeRegistry} featureId="alerting" producerId="alerting" + ruleTypeId=".es-query" /> diff --git a/x-pack/plugins/monitoring/server/lib/cluster/get_clusters_from_request.ts b/x-pack/plugins/monitoring/server/lib/cluster/get_clusters_from_request.ts index 52c0c2a6b7334..b753388af7d5d 100644 --- a/x-pack/plugins/monitoring/server/lib/cluster/get_clusters_from_request.ts +++ b/x-pack/plugins/monitoring/server/lib/cluster/get_clusters_from_request.ts @@ -123,25 +123,19 @@ export async function getClustersFromRequest( // update clusters with license check results const getSupportedClusters = flagSupportedClusters(req, CCS_REMOTE_PATTERN); clusters = await getSupportedClusters(clusters); + clusters = initializeClusters(clusters); // add alerts data if (isInCodePath(codePaths, [CODE_PATH_ALERTS])) { - const rulesClient = req.getRulesClient(); - const alertStatus = await fetchStatus( - rulesClient, - undefined, - clusters.map((cluster) => get(cluster, 'elasticsearch.cluster.id', cluster.cluster_uuid)) + const rulesClient = await req.getRulesClient(); + const clustersIds = clusters.map((cluster) => + get(cluster, 'elasticsearch.cluster.id', cluster.cluster_uuid) ); - for (const cluster of clusters) { - if (!rulesClient) { - cluster.alerts = { - list: {}, - alertsMeta: { - enabled: false, - }, - }; - } else { + if (rulesClient) { + const alertStatus = await fetchStatus(rulesClient, undefined, clustersIds); + + for (const cluster of clusters) { try { cluster.alerts = { list: Object.keys(alertStatus).reduce((acc, ruleTypeName) => { @@ -163,12 +157,6 @@ export async function getClustersFromRequest( req.logger.warn( `Unable to fetch alert status because '${err.message}'. Alerts may not properly show up in the UI.` ); - cluster.alerts = { - list: {}, - alertsMeta: { - enabled: true, - }, - }; } } } @@ -284,3 +272,13 @@ export async function getClustersFromRequest( return getClustersSummary(req.server, clusters as EnhancedClusters[], kibanaUuid, isCcrEnabled); } + +const initializeClusters = (clusters: Cluster[]): Cluster[] => { + return clusters.map((cluster) => ({ + ...cluster, + list: {}, + alertsMeta: { + enabled: false, + }, + })); +}; diff --git a/x-pack/plugins/monitoring/server/lib/setup/collection/get_collection_status.test.ts b/x-pack/plugins/monitoring/server/lib/setup/collection/get_collection_status.test.ts index b743e0300aef6..ce03cc5aecf3b 100644 --- a/x-pack/plugins/monitoring/server/lib/setup/collection/get_collection_status.test.ts +++ b/x-pack/plugins/monitoring/server/lib/setup/collection/get_collection_status.test.ts @@ -94,7 +94,7 @@ const mockReq = ( headers: {}, getKibanaStatsCollector: () => null, getUiSettingsService: () => null, - getActionTypeRegistry: () => null, + getActionTypeRegistry: () => [], getRulesClient: () => null, getActionsClient: () => null, }; diff --git a/x-pack/plugins/monitoring/server/plugin.ts b/x-pack/plugins/monitoring/server/plugin.ts index 0a7460457854e..dbf375aa2e057 100644 --- a/x-pack/plugins/monitoring/server/plugin.ts +++ b/x-pack/plugins/monitoring/server/plugin.ts @@ -23,7 +23,9 @@ import { import { get } from 'lodash'; import { DEFAULT_APP_CATEGORIES } from '@kbn/core/server'; import { RouteMethod } from '@kbn/core/server'; +import { ALERTING_FEATURE_ID } from '@kbn/alerting-plugin/common'; import { KibanaFeatureScope } from '@kbn/features-plugin/common'; +import { AlertConsumers } from '@kbn/rule-data-utils'; import { KIBANA_MONITORING_LOGGING_TAG, KIBANA_STATS_TYPE_MONITORING, @@ -265,6 +267,11 @@ export class MonitoringPlugin } registerPluginInUI(plugins: PluginsSetup) { + const alertingFeatures = RULES.map((ruleTypeId) => ({ + ruleTypeId, + consumers: ['monitoring', ALERTING_FEATURE_ID, AlertConsumers.OBSERVABILITY], + })); + plugins.features.registerKibanaFeature({ id: 'monitoring', name: i18n.translate('xpack.monitoring.featureRegistry.monitoringFeatureName', { @@ -275,7 +282,7 @@ export class MonitoringPlugin app: ['monitoring', 'kibana'], catalogue: ['monitoring'], privileges: null, - alerting: RULES, + alerting: alertingFeatures, reserved: { description: i18n.translate('xpack.monitoring.feature.reserved.description', { defaultMessage: 'To grant users access, you should also assign the monitoring_user role.', @@ -292,10 +299,10 @@ export class MonitoringPlugin }, alerting: { rule: { - all: RULES, + all: alertingFeatures, }, alert: { - all: RULES, + all: alertingFeatures, }, }, ui: [], @@ -335,7 +342,7 @@ export class MonitoringPlugin payload: req.body, getKibanaStatsCollector: () => this.legacyShimDependencies.kibanaStatsCollector, getUiSettingsService: () => coreContext.uiSettings.client, - getActionTypeRegistry: () => actionContext?.listTypes(), + getActionTypeRegistry: () => actionContext?.listTypes() ?? [], getRulesClient: () => { try { return plugins.alerting.getRulesClientWithRequest(req); diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/alerts/enable.ts b/x-pack/plugins/monitoring/server/routes/api/v1/alerts/enable.ts index 8b919fd1f86ea..593f3c9b2b4ab 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/alerts/enable.ts +++ b/x-pack/plugins/monitoring/server/routes/api/v1/alerts/enable.ts @@ -30,6 +30,7 @@ export function enableAlertsRoute(server: MonitoringCore, npRoute: RouteDependen const actionContext = await context.actions; const alerts = RulesFactory.getAll(); + if (alerts.length) { const { isSufficientlySecure, hasPermanentEncryptionKey } = npRoute.alerting ?.getSecurityHealth @@ -49,9 +50,10 @@ export function enableAlertsRoute(server: MonitoringCore, npRoute: RouteDependen } } - const rulesClient = alertingContext?.getRulesClient(); + const rulesClient = await alertingContext?.getRulesClient(); const actionsClient = actionContext?.getActionsClient(); const types = actionContext?.listTypes(); + if (!rulesClient || !actionsClient || !types) { return response.ok({ body: undefined }); } diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/alerts/status.ts b/x-pack/plugins/monitoring/server/routes/api/v1/alerts/status.ts index 64a0b7b92d85f..a6c7d9b833ee1 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/alerts/status.ts +++ b/x-pack/plugins/monitoring/server/routes/api/v1/alerts/status.ts @@ -36,7 +36,7 @@ export function alertStatusRoute(npRoute: RouteDependencies) { try { const { clusterUuid } = request.params; const { alertTypeIds, filters } = request.body; - const rulesClient = (await context.alerting)?.getRulesClient(); + const rulesClient = await (await context.alerting)?.getRulesClient(); if (!rulesClient) { return response.ok({ body: undefined }); } diff --git a/x-pack/plugins/monitoring/server/types.ts b/x-pack/plugins/monitoring/server/types.ts index 95707caf50199..14ef949b93949 100644 --- a/x-pack/plugins/monitoring/server/types.ts +++ b/x-pack/plugins/monitoring/server/types.ts @@ -24,17 +24,14 @@ import type { } from '@kbn/actions-plugin/server'; import type { AlertingApiRequestHandlerContext } from '@kbn/alerting-plugin/server'; import type { RacApiRequestHandlerContext } from '@kbn/rule-registry-plugin/server'; -import { - PluginStartContract as AlertingPluginStartContract, - PluginSetupContract as AlertingPluginSetupContract, -} from '@kbn/alerting-plugin/server'; +import { AlertingServerSetup, AlertingServerStart } from '@kbn/alerting-plugin/server'; import { InfraPluginSetup, InfraRequestHandlerContext } from '@kbn/infra-plugin/server'; -import { PluginSetupContract as AlertingPluginSetup } from '@kbn/alerting-plugin/server'; import { LicensingPluginStart } from '@kbn/licensing-plugin/server'; import { FeaturesPluginSetup } from '@kbn/features-plugin/server'; import { EncryptedSavedObjectsPluginSetup } from '@kbn/encrypted-saved-objects-plugin/server'; import { CloudSetup } from '@kbn/cloud-plugin/server'; import { RouteConfig, RouteMethod, Headers } from '@kbn/core/server'; +import { ActionTypeRegistry } from '@kbn/actions-plugin/server/action_type_registry'; import { ElasticsearchModifiedSource } from '../common/types/es'; import { RulesByType } from '../common/types/alerts'; import { configSchema, MonitoringConfig } from './config'; @@ -53,7 +50,7 @@ export interface PluginsSetup { encryptedSavedObjects?: EncryptedSavedObjectsPluginSetup; usageCollection?: UsageCollectionSetup; features: FeaturesPluginSetup; - alerting?: AlertingPluginSetupContract; + alerting?: AlertingServerSetup; infra: InfraPluginSetup; cloud?: CloudSetup; } @@ -66,7 +63,7 @@ export type RequestHandlerContextMonitoringPlugin = CustomRequestHandlerContext< }>; export interface PluginsStart { - alerting: AlertingPluginStartContract; + alerting: AlertingServerStart; actions: ActionsPluginsStartContact; licensing: LicensingPluginStart; } @@ -76,7 +73,7 @@ export interface RouteDependencies { router: IRouter; licenseService: MonitoringLicenseService; encryptedSavedObjects?: EncryptedSavedObjectsPluginSetup; - alerting?: AlertingPluginSetup; + alerting?: AlertingServerSetup; logger: Logger; } @@ -127,9 +124,11 @@ export interface LegacyRequest { headers: Headers; getKibanaStatsCollector: () => any; getUiSettingsService: () => any; - getActionTypeRegistry: () => any; - getRulesClient: () => any; - getActionsClient: () => any; + getActionTypeRegistry: () => ReturnType; + getRulesClient: () => ReturnType | null; + getActionsClient: () => ReturnType< + ActionsPluginsStartContact['getActionsClientWithRequest'] + > | null; server: LegacyServer; } diff --git a/x-pack/plugins/observability_solution/apm/common/alerting/config/apm_alerting_feature_ids.ts b/x-pack/plugins/observability_solution/apm/common/alerting/config/apm_alerting_feature_ids.ts new file mode 100644 index 0000000000000..784ab0b534256 --- /dev/null +++ b/x-pack/plugins/observability_solution/apm/common/alerting/config/apm_alerting_feature_ids.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 { + AlertConsumers, + OBSERVABILITY_RULE_TYPE_IDS, + type ValidFeatureId, +} from '@kbn/rule-data-utils'; + +export const apmAlertingConsumers: ValidFeatureId[] = [ + AlertConsumers.LOGS, + AlertConsumers.APM, + AlertConsumers.SLO, + AlertConsumers.OBSERVABILITY, + AlertConsumers.INFRASTRUCTURE, + AlertConsumers.ALERTS, +]; + +export const apmAlertingRuleTypeIds: string[] = [...OBSERVABILITY_RULE_TYPE_IDS]; diff --git a/x-pack/plugins/observability_solution/apm/kibana.jsonc b/x-pack/plugins/observability_solution/apm/kibana.jsonc index 656f898f24064..bcb0801fc6394 100644 --- a/x-pack/plugins/observability_solution/apm/kibana.jsonc +++ b/x-pack/plugins/observability_solution/apm/kibana.jsonc @@ -37,7 +37,8 @@ "lens", "maps", "uiActions", - "logsDataAccess" + "logsDataAccess", + "savedSearch", ], "optionalPlugins": [ "actions", diff --git a/x-pack/plugins/observability_solution/apm/public/components/app/alerts_overview/index.tsx b/x-pack/plugins/observability_solution/apm/public/components/app/alerts_overview/index.tsx index a5d0df3b05538..682634819e623 100644 --- a/x-pack/plugins/observability_solution/apm/public/components/app/alerts_overview/index.tsx +++ b/x-pack/plugins/observability_solution/apm/public/components/app/alerts_overview/index.tsx @@ -13,6 +13,10 @@ import { EuiPanel, EuiFlexItem, EuiFlexGroup } from '@elastic/eui'; import { BoolQuery } from '@kbn/es-query'; import { AlertConsumers } from '@kbn/rule-data-utils'; import { useKibana } from '@kbn/kibana-react-plugin/public'; +import { + apmAlertingConsumers, + apmAlertingRuleTypeIds, +} from '../../../../common/alerting/config/apm_alerting_feature_ids'; import { ApmPluginStartDeps } from '../../../plugin'; import { useAnyOfApmParams } from '../../../hooks/use_apm_params'; import { SERVICE_NAME } from '../../../../common/es_fields/apm'; @@ -107,7 +111,8 @@ export function AlertsOverview() { alertsTableConfigurationRegistry={alertsTableConfigurationRegistry} id={'service-overview-alerts'} configurationId={AlertConsumers.OBSERVABILITY} - featureIds={[AlertConsumers.APM, AlertConsumers.OBSERVABILITY]} + ruleTypeIds={apmAlertingRuleTypeIds} + consumers={apmAlertingConsumers} query={esQuery} showAlertStatusWithFlapping cellContext={{ observabilityRuleTypeRegistry }} diff --git a/x-pack/plugins/observability_solution/apm/public/components/app/service_logs/index.tsx b/x-pack/plugins/observability_solution/apm/public/components/app/service_logs/index.tsx index a1dadbf186b91..35f502642518f 100644 --- a/x-pack/plugins/observability_solution/apm/public/components/app/service_logs/index.tsx +++ b/x-pack/plugins/observability_solution/apm/public/components/app/service_logs/index.tsx @@ -6,9 +6,9 @@ */ import React, { useMemo } from 'react'; -import moment from 'moment'; import { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/types'; -import { LogStream } from '@kbn/logs-shared-plugin/public'; +import { LazySavedSearchComponent } from '@kbn/saved-search-component'; +import useAsync from 'react-use/lib/useAsync'; import { ENVIRONMENT_ALL } from '../../../../common/environment_filter_values'; import { CONTAINER_ID, SERVICE_ENVIRONMENT, SERVICE_NAME } from '../../../../common/es_fields/apm'; import { useApmServiceContext } from '../../../context/apm_service/use_apm_service_context'; @@ -35,6 +35,19 @@ export function ServiceLogs() { } export function ClassicServiceLogsStream() { + const { + services: { + logsDataAccess: { + services: { logSourcesService }, + }, + embeddable, + dataViews, + data: { + search: { searchSource }, + }, + }, + } = useKibana(); + const { serviceName } = useApmServiceContext(); const { @@ -62,17 +75,31 @@ export function ClassicServiceLogsStream() { [environment, kuery, serviceName, start, end] ); - return ( - ({ from: start, to: end }), [start, end]); + + const query = useMemo( + () => ({ + language: 'kuery', + query: getInfrastructureKQLFilter({ data, serviceName, environment }), + }), + [data, serviceName, environment] + ); + + return logSources.value ? ( + - ); + ) : null; } export function ServiceLogsOverview() { diff --git a/x-pack/plugins/observability_solution/apm/public/plugin.ts b/x-pack/plugins/observability_solution/apm/public/plugin.ts index f7246115e1e0e..532c0498f7a56 100644 --- a/x-pack/plugins/observability_solution/apm/public/plugin.ts +++ b/x-pack/plugins/observability_solution/apm/public/plugin.ts @@ -70,6 +70,8 @@ import { map } from 'rxjs'; import type { CloudSetup } from '@kbn/cloud-plugin/public'; import type { ServerlessPluginStart } from '@kbn/serverless/public'; import { LogsSharedClientStartExports } from '@kbn/logs-shared-plugin/public'; +import { LogsDataAccessPluginStart } from '@kbn/logs-data-access-plugin/public'; +import { SavedSearchPublicPluginStart } from '@kbn/saved-search-plugin/public'; import type { ConfigSchema } from '.'; import { registerApmRuleTypes } from './components/alerting/rule_types/register_apm_rule_types'; import { registerEmbeddables } from './embeddable/register_embeddables'; @@ -143,6 +145,8 @@ export interface ApmPluginStartDeps { metricsDataAccess: MetricsDataPluginStart; uiSettings: IUiSettingsClient; logsShared: LogsSharedClientStartExports; + logsDataAccess: LogsDataAccessPluginStart; + savedSearch: SavedSearchPublicPluginStart; } const applicationsTitle = i18n.translate('xpack.apm.navigation.rootTitle', { diff --git a/x-pack/plugins/observability_solution/apm/server/assistant_functions/index.ts b/x-pack/plugins/observability_solution/apm/server/assistant_functions/index.ts index 1dff57cef6602..6a65e6126ff22 100644 --- a/x-pack/plugins/observability_solution/apm/server/assistant_functions/index.ts +++ b/x-pack/plugins/observability_solution/apm/server/assistant_functions/index.ts @@ -72,7 +72,10 @@ export function registerAssistantFunctions({ ruleDataClient, plugins, getApmIndices: async () => { - const apmIndices = await plugins.apmDataAccess.setup.getApmIndices(); + const coreContext = await resources.context.core; + const apmIndices = await plugins.apmDataAccess.setup.getApmIndices( + coreContext.savedObjects.client + ); return apmIndices; }, }; diff --git a/x-pack/plugins/observability_solution/apm/server/feature.ts b/x-pack/plugins/observability_solution/apm/server/feature.ts index f9b047c602cda..6e129d298e0a7 100644 --- a/x-pack/plugins/observability_solution/apm/server/feature.ts +++ b/x-pack/plugins/observability_solution/apm/server/feature.ts @@ -15,10 +15,14 @@ import { import { APM_INDEX_SETTINGS_SAVED_OBJECT_TYPE } from '@kbn/apm-data-access-plugin/server/saved_objects/apm_indices'; import { ApmRuleType } from '@kbn/rule-data-utils'; +import { ALERTING_FEATURE_ID } from '@kbn/alerting-plugin/common'; import { KibanaFeatureConfig, KibanaFeatureScope } from '@kbn/features-plugin/common'; import { APM_SERVER_FEATURE_ID } from '../common/rules/apm_rule_types'; -const ruleTypes = Object.values(ApmRuleType); +const alertingFeatures = Object.values(ApmRuleType).map((ruleTypeId) => ({ + ruleTypeId, + consumers: [APM_SERVER_FEATURE_ID, ALERTING_FEATURE_ID], +})); export const APM_FEATURE: KibanaFeatureConfig = { id: APM_SERVER_FEATURE_ID, @@ -33,7 +37,7 @@ export const APM_FEATURE: KibanaFeatureConfig = { management: { insightsAndAlerting: ['triggersActions'], }, - alerting: ruleTypes, + alerting: alertingFeatures, // see x-pack/plugins/features/common/feature_kibana_privileges.ts privileges: { all: { @@ -46,10 +50,10 @@ export const APM_FEATURE: KibanaFeatureConfig = { }, alerting: { alert: { - all: ruleTypes, + all: alertingFeatures, }, rule: { - all: ruleTypes, + all: alertingFeatures, }, }, management: { @@ -67,10 +71,10 @@ export const APM_FEATURE: KibanaFeatureConfig = { }, alerting: { alert: { - read: ruleTypes, + read: alertingFeatures, }, rule: { - read: ruleTypes, + read: alertingFeatures, }, }, management: { diff --git a/x-pack/plugins/observability_solution/apm/server/lib/helpers/get_apm_alerts_client.ts b/x-pack/plugins/observability_solution/apm/server/lib/helpers/get_apm_alerts_client.ts index b0e601fd4c0db..95c29472dbc79 100644 --- a/x-pack/plugins/observability_solution/apm/server/lib/helpers/get_apm_alerts_client.ts +++ b/x-pack/plugins/observability_solution/apm/server/lib/helpers/get_apm_alerts_client.ts @@ -12,6 +12,7 @@ import { DataTier } from '@kbn/observability-shared-plugin/common'; import { searchExcludedDataTiers } from '@kbn/observability-plugin/common/ui_settings_keys'; import { estypes } from '@elastic/elasticsearch'; import { getDataTierFilterCombined } from '@kbn/apm-data-access-plugin/server/utils'; +import { apmAlertingRuleTypeIds } from '../../../common/alerting/config/apm_alerting_feature_ids'; import type { MinimalAPMRouteHandlerResources } from '../../routes/apm_routes/register_apm_server_routes'; export type ApmAlertsClient = Awaited>; @@ -31,7 +32,7 @@ export async function getApmAlertsClient({ const ruleRegistryPluginStart = await plugins.ruleRegistry.start(); const alertsClient = await ruleRegistryPluginStart.getRacClientWithRequest(request); - const apmAlertsIndices = await alertsClient.getAuthorizedAlertsIndices(['apm']); + const apmAlertsIndices = await alertsClient.getAuthorizedAlertsIndices(apmAlertingRuleTypeIds); if (!apmAlertsIndices || isEmpty(apmAlertsIndices)) { throw Error('No alert indices exist for "apm"'); diff --git a/x-pack/plugins/observability_solution/apm/server/plugin.ts b/x-pack/plugins/observability_solution/apm/server/plugin.ts index de49ebcebf8b0..1142a5c69a51f 100644 --- a/x-pack/plugins/observability_solution/apm/server/plugin.ts +++ b/x-pack/plugins/observability_solution/apm/server/plugin.ts @@ -16,6 +16,7 @@ import { registerAssistantFunctions } from './assistant_functions'; import { registerDeprecations } from './deprecations'; import { APM_FEATURE, registerFeaturesUsage } from './feature'; import { createApmTelemetry } from './lib/apm_telemetry'; +import { getInternalSavedObjectsClient } from './lib/helpers/get_internal_saved_objects_client'; import { APM_RULE_TYPE_ALERT_CONTEXT, apmRuleTypeAlertFieldMap, @@ -114,6 +115,13 @@ export class APMPlugin }; }) as APMRouteHandlerResources['plugins']; + const apmIndicesPromise = (async () => { + const coreStart = await getCoreStart(); + const soClient = await getInternalSavedObjectsClient(coreStart); + const { getApmIndices } = plugins.apmDataAccess; + return getApmIndices(soClient); + })(); + // This if else block will go away in favour of removing Home Tutorial Integration // Ideally we will directly register a custom integration and pass the configs // for cloud, onPrem and Serverless so that the actual component can take @@ -121,8 +129,7 @@ export class APMPlugin if (currentConfig.serverlessOnboarding && plugins.customIntegrations) { plugins.customIntegrations?.registerCustomIntegration(apmTutorialCustomIntegration); } else { - plugins.apmDataAccess - .getApmIndices() + apmIndicesPromise .then((apmIndices) => { plugins.home?.tutorials.registerTutorial( tutorialProvider({ diff --git a/x-pack/plugins/observability_solution/apm/server/routes/alerts/register_apm_rule_types.ts b/x-pack/plugins/observability_solution/apm/server/routes/alerts/register_apm_rule_types.ts index 4c57ef4a10e1d..ea653b47145a2 100644 --- a/x-pack/plugins/observability_solution/apm/server/routes/alerts/register_apm_rule_types.ts +++ b/x-pack/plugins/observability_solution/apm/server/routes/alerts/register_apm_rule_types.ts @@ -8,10 +8,7 @@ import type { AlertsLocatorParams } from '@kbn/observability-plugin/common'; import { LocatorPublic } from '@kbn/share-plugin/common'; import { IBasePath, Logger, SavedObjectsClientContract } from '@kbn/core/server'; -import { - PluginSetupContract as AlertingPluginSetupContract, - type IRuleTypeAlerts, -} from '@kbn/alerting-plugin/server'; +import type { AlertingServerSetup, IRuleTypeAlerts } from '@kbn/alerting-plugin/server'; import { ObservabilityPluginSetup } from '@kbn/observability-plugin/server'; import { IRuleDataClient } from '@kbn/rule-registry-plugin/server'; import { MlPluginSetup } from '@kbn/ml-plugin/server'; @@ -100,7 +97,7 @@ export const ApmRuleTypeAlertDefinition: IRuleTypeAlerts }; export interface RegisterRuleDependencies { - alerting: AlertingPluginSetupContract; + alerting: AlertingServerSetup; basePath: IBasePath; getApmIndices: (soClient: SavedObjectsClientContract) => Promise; apmConfig: APMConfig; diff --git a/x-pack/plugins/observability_solution/apm/server/routes/alerts/test_utils/index.ts b/x-pack/plugins/observability_solution/apm/server/routes/alerts/test_utils/index.ts index ce3e67baea1d6..9230ca4983698 100644 --- a/x-pack/plugins/observability_solution/apm/server/routes/alerts/test_utils/index.ts +++ b/x-pack/plugins/observability_solution/apm/server/routes/alerts/test_utils/index.ts @@ -9,7 +9,7 @@ import { IBasePath, Logger } from '@kbn/core/server'; import { elasticsearchServiceMock } from '@kbn/core/server/mocks'; import { IRuleDataClient } from '@kbn/rule-registry-plugin/server'; import { ruleRegistryMocks } from '@kbn/rule-registry-plugin/server/mocks'; -import { PluginSetupContract as AlertingPluginSetupContract } from '@kbn/alerting-plugin/server'; +import { AlertingServerSetup } from '@kbn/alerting-plugin/server'; import { ObservabilityPluginSetup } from '@kbn/observability-plugin/server'; import { DEFAULT_FLAPPING_SETTINGS } from '@kbn/alerting-plugin/common'; import { APMConfig, APM_SERVER_FEATURE_ID } from '../../..'; @@ -28,7 +28,7 @@ export const createRuleTypeMocks = () => { registerType: ({ executor }) => { alertExecutor = executor; }, - } as AlertingPluginSetupContract; + } as AlertingServerSetup; const scheduleActions = jest.fn(); const getUuid = jest.fn(); diff --git a/x-pack/plugins/observability_solution/apm/server/routes/apm_routes/register_apm_server_routes.ts b/x-pack/plugins/observability_solution/apm/server/routes/apm_routes/register_apm_server_routes.ts index 59c9cdac2df83..197b4259d3f09 100644 --- a/x-pack/plugins/observability_solution/apm/server/routes/apm_routes/register_apm_server_routes.ts +++ b/x-pack/plugins/observability_solution/apm/server/routes/apm_routes/register_apm_server_routes.ts @@ -115,7 +115,10 @@ export function registerRoutes({ ); const getApmIndices = async () => { - const apmIndices = await plugins.apmDataAccess.setup.getApmIndices(); + const coreContext = await context.core; + const apmIndices = await plugins.apmDataAccess.setup.getApmIndices( + coreContext.savedObjects.client + ); return apmIndices; }; diff --git a/x-pack/plugins/observability_solution/apm/server/routes/assistant_functions/get_observability_alert_details_context/index.ts b/x-pack/plugins/observability_solution/apm/server/routes/assistant_functions/get_observability_alert_details_context/index.ts index f28e3f9df8570..84e51675233c9 100644 --- a/x-pack/plugins/observability_solution/apm/server/routes/assistant_functions/get_observability_alert_details_context/index.ts +++ b/x-pack/plugins/observability_solution/apm/server/routes/assistant_functions/get_observability_alert_details_context/index.ts @@ -38,7 +38,8 @@ export const getAlertDetailsContextHandler = ( return async (requestContext, query) => { const resources = { getApmIndices: async () => { - return resourcePlugins.apmDataAccess.setup.getApmIndices(); + const coreContext = await requestContext.core; + return resourcePlugins.apmDataAccess.setup.getApmIndices(coreContext.savedObjects.client); }, request: requestContext.request, params: { query: { _inspect: false } }, diff --git a/x-pack/plugins/observability_solution/apm/server/routes/fleet/register_fleet_policy_callbacks.ts b/x-pack/plugins/observability_solution/apm/server/routes/fleet/register_fleet_policy_callbacks.ts index 9d00c50b4ab48..2237548f2d325 100644 --- a/x-pack/plugins/observability_solution/apm/server/routes/fleet/register_fleet_policy_callbacks.ts +++ b/x-pack/plugins/observability_solution/apm/server/routes/fleet/register_fleet_policy_callbacks.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { Logger, CoreStart } from '@kbn/core/server'; +import { Logger, CoreStart, SavedObjectsClientContract } from '@kbn/core/server'; import { FleetStartContract, PostPackagePolicyCreateCallback, @@ -22,6 +22,7 @@ import { SOURCE_MAP_API_KEY_PATH, } from './get_package_policy_decorators'; import { createInternalESClient } from '../../lib/helpers/create_es_client/create_internal_es_client'; +import { getInternalSavedObjectsClient } from '../../lib/helpers/get_internal_saved_objects_client'; import { APMRouteHandlerResources } from '../apm_routes/register_apm_server_routes'; export async function registerFleetPolicyCallbacks({ @@ -148,7 +149,7 @@ function onPackagePolicyCreateOrUpdate({ coreStart, }: { fleetPluginStart: FleetStartContract; - getApmIndices: () => Promise; + getApmIndices: (soClient: SavedObjectsClientContract) => Promise; coreStart: CoreStart; }): PutPackagePolicyUpdateCallback & PostPackagePolicyCreateCallback { return async (packagePolicy) => { @@ -157,7 +158,8 @@ function onPackagePolicyCreateOrUpdate({ } const { asInternalUser } = coreStart.elasticsearch.client; - const apmIndices = await getApmIndices(); + const savedObjectsClient = await getInternalSavedObjectsClient(coreStart); + const apmIndices = await getApmIndices(savedObjectsClient); const internalESClient = await createInternalESClient({ debug: false, diff --git a/x-pack/plugins/observability_solution/apm/server/routes/typings.ts b/x-pack/plugins/observability_solution/apm/server/routes/typings.ts index 126ae48937648..de5aeb6031d1c 100644 --- a/x-pack/plugins/observability_solution/apm/server/routes/typings.ts +++ b/x-pack/plugins/observability_solution/apm/server/routes/typings.ts @@ -16,14 +16,12 @@ import type { import type { RacApiRequestHandlerContext } from '@kbn/rule-registry-plugin/server'; import type { LicensingApiRequestHandlerContext } from '@kbn/licensing-plugin/server'; import type { UsageCollectionSetup } from '@kbn/usage-collection-plugin/server'; -import type { RulesClientApi } from '@kbn/alerting-plugin/server/types'; +import { RulesClientApi } from '@kbn/alerting-plugin/server/types'; export type ApmPluginRequestHandlerContext = CustomRequestHandlerContext<{ licensing: Pick; alerting: { - // Pick is a superset of this - // and incompatible with the start contract from the alerting plugin - getRulesClient: () => RulesClientApi; + getRulesClient: () => Promise; }; rac: Pick; }>; diff --git a/x-pack/plugins/observability_solution/apm/server/types.ts b/x-pack/plugins/observability_solution/apm/server/types.ts index 84e0d5462c43b..e99860b9d441f 100644 --- a/x-pack/plugins/observability_solution/apm/server/types.ts +++ b/x-pack/plugins/observability_solution/apm/server/types.ts @@ -24,7 +24,7 @@ import { SpacesPluginSetup, SpacesPluginStart } from '@kbn/spaces-plugin/server' import { HomeServerPluginSetup, HomeServerPluginStart } from '@kbn/home-plugin/server'; import { UsageCollectionSetup } from '@kbn/usage-collection-plugin/server'; import { ActionsPlugin } from '@kbn/actions-plugin/server'; -import { AlertingPlugin } from '@kbn/alerting-plugin/server'; +import type { AlertingServerSetup, AlertingServerStart } from '@kbn/alerting-plugin/server'; import { CloudSetup } from '@kbn/cloud-plugin/server'; import { FeaturesPluginSetup, FeaturesPluginStart } from '@kbn/features-plugin/server'; import { LicensingPluginSetup, LicensingPluginStart } from '@kbn/licensing-plugin/server'; @@ -78,7 +78,7 @@ export interface APMPluginSetupDependencies { observabilityAIAssistant?: ObservabilityAIAssistantServerSetup; // optional dependencies actions?: ActionsPlugin['setup']; - alerting?: AlertingPlugin['setup']; + alerting?: AlertingServerSetup; cloud?: CloudSetup; fleet?: FleetPluginSetup; home?: HomeServerPluginSetup; @@ -105,7 +105,7 @@ export interface APMPluginStartDependencies { observabilityAIAssistant?: ObservabilityAIAssistantServerStart; // optional dependencies actions?: ActionsPlugin['start']; - alerting?: AlertingPlugin['start']; + alerting?: AlertingServerStart; cloud?: undefined; fleet?: FleetPluginStart; home?: HomeServerPluginStart; diff --git a/x-pack/plugins/observability_solution/apm/tsconfig.json b/x-pack/plugins/observability_solution/apm/tsconfig.json index d3de1633dcad7..b2fda13c3f76f 100644 --- a/x-pack/plugins/observability_solution/apm/tsconfig.json +++ b/x-pack/plugins/observability_solution/apm/tsconfig.json @@ -127,6 +127,8 @@ "@kbn/router-utils", "@kbn/react-hooks", "@kbn/alerting-comparators", + "@kbn/saved-search-component", + "@kbn/saved-search-plugin", ], "exclude": ["target/**/*"] } diff --git a/x-pack/plugins/observability_solution/apm_data_access/kibana.jsonc b/x-pack/plugins/observability_solution/apm_data_access/kibana.jsonc index 9d80dcd71ce93..4eb0859691ba1 100644 --- a/x-pack/plugins/observability_solution/apm_data_access/kibana.jsonc +++ b/x-pack/plugins/observability_solution/apm_data_access/kibana.jsonc @@ -1,10 +1,7 @@ { "type": "plugin", "id": "@kbn/apm-data-access-plugin", - "owner": [ - "@elastic/obs-knowledge-team", - "@elastic/obs-ux-infra_services-team" - ], + "owner": ["@elastic/obs-ux-infra_services-team"], "group": "observability", "visibility": "private", "plugin": { @@ -18,7 +15,9 @@ "requiredPlugins": [ "data" ], - "optionalPlugins": [], + "optionalPlugins": [ + "security" + ], "requiredBundles": [] } } \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/apm_data_access/server/index.ts b/x-pack/plugins/observability_solution/apm_data_access/server/index.ts index 7afaa656591c4..6b6385ded4ce4 100644 --- a/x-pack/plugins/observability_solution/apm_data_access/server/index.ts +++ b/x-pack/plugins/observability_solution/apm_data_access/server/index.ts @@ -91,6 +91,7 @@ export type { APMEventESSearchRequest, APMLogEventESSearchRequest, DocumentSourcesRequest, + ApmDataAccessPrivilegesCheck, HostNamesRequest, GetDocumentTypeParams, } from './types'; diff --git a/x-pack/plugins/observability_solution/apm_data_access/server/lib/check_privileges.ts b/x-pack/plugins/observability_solution/apm_data_access/server/lib/check_privileges.ts new file mode 100644 index 0000000000000..6b8e734a10b4e --- /dev/null +++ b/x-pack/plugins/observability_solution/apm_data_access/server/lib/check_privileges.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 { KibanaRequest } from '@kbn/core-http-server'; +import { SecurityPluginStart } from '@kbn/security-plugin-types-server'; +import { mapValues } from 'lodash'; +import { APMIndices } from '..'; + +export interface ApmDataAccessPrivilegesCheck { + request: KibanaRequest; + security?: SecurityPluginStart; + getApmIndices: () => Promise; +} + +export async function checkPrivileges({ + request, + getApmIndices, + security, +}: ApmDataAccessPrivilegesCheck) { + const authorization = security?.authz; + if (!authorization) { + return true; + } + + const [apmIndices, checkPrivilegesFn] = await Promise.all([ + getApmIndices(), + authorization.checkPrivilegesDynamicallyWithRequest(request), + ]); + + const { hasAllRequested } = await checkPrivilegesFn({ + elasticsearch: { + cluster: [], + index: mapValues(apmIndices, () => ['read']), + }, + }); + + return hasAllRequested; +} diff --git a/x-pack/plugins/observability_solution/apm_data_access/server/plugin.ts b/x-pack/plugins/observability_solution/apm_data_access/server/plugin.ts index 6bf684985583a..680079d080c82 100644 --- a/x-pack/plugins/observability_solution/apm_data_access/server/plugin.ts +++ b/x-pack/plugins/observability_solution/apm_data_access/server/plugin.ts @@ -5,19 +5,32 @@ * 2.0. */ -import { PluginInitializerContext, CoreSetup, CoreStart, Plugin, Logger } from '@kbn/core/server'; +import { + PluginInitializerContext, + CoreSetup, + CoreStart, + Plugin, + SavedObjectsClientContract, + Logger, +} from '@kbn/core/server'; import { APMDataAccessConfig } from '.'; -import { ApmDataAccessPluginSetup, ApmDataAccessPluginStart } from './types'; +import { + ApmDataAccessPluginSetup, + ApmDataAccessPluginStart, + ApmDataAccessServerDependencies, +} from './types'; import { migrateLegacyAPMIndicesToSpaceAware } from './saved_objects/migrations/migrate_legacy_apm_indices_to_space_aware'; import { apmIndicesSavedObjectDefinition, getApmIndicesSavedObject, } from './saved_objects/apm_indices'; import { getServices } from './services/get_services'; +import { ApmDataAccessPrivilegesCheck, checkPrivileges } from './lib/check_privileges'; export class ApmDataAccessPlugin implements Plugin { + public server?: ApmDataAccessServerDependencies; public config: APMDataAccessConfig; public logger: Logger; @@ -26,34 +39,45 @@ export class ApmDataAccessPlugin this.logger = initContext.logger.get(); } + getApmIndices = async (savedObjectsClient: SavedObjectsClientContract) => { + const apmIndicesFromSavedObject = await getApmIndicesSavedObject(savedObjectsClient); + return { ...this.config.indices, ...apmIndicesFromSavedObject }; + }; + public setup(core: CoreSetup): ApmDataAccessPluginSetup { // register saved object core.savedObjects.registerType(apmIndicesSavedObjectDefinition); - const getApmIndices = async () => { - const [coreStart] = await core.getStartServices(); - const soClient = await coreStart.savedObjects.createInternalRepository(); - - const apmIndicesFromSavedObject = await getApmIndicesSavedObject(soClient); - return { ...this.config.indices, ...apmIndicesFromSavedObject }; - }; - // expose return { apmIndicesFromConfigFile: this.config.indices, - getApmIndices, + getApmIndices: this.getApmIndices, getServices, }; } - public start(core: CoreStart) { + public start(core: CoreStart, plugins: ApmDataAccessServerDependencies) { // TODO: remove in 9.0 migrateLegacyAPMIndicesToSpaceAware({ coreStart: core, logger: this.logger }).catch((e) => { this.logger.error('Failed to run migration making APM indices space aware'); this.logger.error(e); }); - return {}; + const getApmIndicesWithInternalUserFn = async () => { + const soClient = core.savedObjects.createInternalRepository(); + return this.getApmIndices(soClient); + }; + + const startServices = { + hasPrivileges: ({ request }: Pick) => + checkPrivileges({ + request, + getApmIndices: getApmIndicesWithInternalUserFn, + security: plugins.security, + }), + }; + + return { ...startServices }; } public stop() {} diff --git a/x-pack/plugins/observability_solution/apm_data_access/server/types.ts b/x-pack/plugins/observability_solution/apm_data_access/server/types.ts index 968590e780ee8..f10c23c1fd994 100644 --- a/x-pack/plugins/observability_solution/apm_data_access/server/types.ts +++ b/x-pack/plugins/observability_solution/apm_data_access/server/types.ts @@ -5,17 +5,28 @@ * 2.0. */ +import { SavedObjectsClientContract } from '@kbn/core-saved-objects-api-server'; +import type { SecurityPluginStart } from '@kbn/security-plugin-types-server'; import type { APMIndices } from '.'; import { getServices } from './services/get_services'; +import type { ApmDataAccessPrivilegesCheck } from './lib/check_privileges'; export interface ApmDataAccessPluginSetup { apmIndicesFromConfigFile: APMIndices; - getApmIndices: () => Promise; + getApmIndices: (soClient: SavedObjectsClientContract) => Promise; getServices: typeof getServices; } -// eslint-disable-next-line @typescript-eslint/no-empty-interface -export interface ApmDataAccessPluginStart {} +export interface ApmDataAccessServerDependencies { + security?: SecurityPluginStart; +} + +export interface ApmDataAccessPluginStart { + hasPrivileges: (params: Pick) => Promise; +} +export interface ApmDataAccessServerDependencies { + security?: SecurityPluginStart; +} export type ApmDataAccessServices = ReturnType; export type { ApmDataAccessServicesParams } from './services/get_services'; @@ -27,3 +38,4 @@ export type { APMEventESSearchRequest, APMLogEventESSearchRequest, } from './lib/helpers'; +export type { ApmDataAccessPrivilegesCheck }; diff --git a/x-pack/plugins/observability_solution/apm_data_access/tsconfig.json b/x-pack/plugins/observability_solution/apm_data_access/tsconfig.json index f7ac83af0922e..d4c38fddf967e 100644 --- a/x-pack/plugins/observability_solution/apm_data_access/tsconfig.json +++ b/x-pack/plugins/observability_solution/apm_data_access/tsconfig.json @@ -9,6 +9,7 @@ "@kbn/config-schema", "@kbn/core", "@kbn/i18n", + "@kbn/core-saved-objects-api-server", "@kbn/data-plugin", "@kbn/inspector-plugin", "@kbn/observability-plugin", @@ -17,6 +18,8 @@ "@kbn/apm-types", "@kbn/core-http-server-mocks", "@kbn/apm-utils", + "@kbn/core-http-server", + "@kbn/security-plugin-types-server", "@kbn/utility-types", "@kbn/elastic-agent-utils", "@kbn/observability-utils-common" diff --git a/x-pack/plugins/observability_solution/dataset_quality/common/api_types.ts b/x-pack/plugins/observability_solution/dataset_quality/common/api_types.ts index 51a1421aec918..7220f9014b477 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/common/api_types.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/common/api_types.ts @@ -95,13 +95,24 @@ export const integrationRt = rt.intersection([ export type IntegrationType = rt.TypeOf; +export const checkAndLoadIntegrationResponseRt = rt.union([ + rt.type({ isIntegration: rt.literal(false), areAssetsAvailable: rt.boolean }), + rt.type({ + isIntegration: rt.literal(true), + areAssetsAvailable: rt.literal(true), + integration: integrationRt, + }), +]); + +export type CheckAndLoadIntegrationResponse = rt.TypeOf; + export const getIntegrationsResponseRt = rt.exact( rt.type({ integrations: rt.array(integrationRt), }) ); -export type IntegrationResponse = rt.TypeOf; +export type IntegrationsResponse = rt.TypeOf; export const degradedFieldRt = rt.type({ name: rt.string, diff --git a/x-pack/plugins/observability_solution/dataset_quality/common/data_stream_details/types.ts b/x-pack/plugins/observability_solution/dataset_quality/common/data_stream_details/types.ts index ce74552b581b9..f6372e1dc61a2 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/common/data_stream_details/types.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/common/data_stream_details/types.ts @@ -5,9 +5,7 @@ * 2.0. */ -export interface GetDataStreamIntegrationParams { - integrationName: string; -} +import { Integration } from '../data_streams_stats/integration'; export interface AnalyzeDegradedFieldsParams { dataStream: string; @@ -19,3 +17,13 @@ export interface UpdateFieldLimitParams { dataStream: string; newFieldLimit: number; } + +export interface CheckAndLoadIntegrationParams { + dataStream: string; +} + +export interface IntegrationType { + isIntegration: boolean; + areAssetsAvailable: boolean; + integration?: Integration; +} diff --git a/x-pack/plugins/observability_solution/dataset_quality/public/components/dataset_quality_details/degraded_field_flyout/possible_mitigations/field_limit/field_mapping_limit.tsx b/x-pack/plugins/observability_solution/dataset_quality/public/components/dataset_quality_details/degraded_field_flyout/possible_mitigations/field_limit/field_mapping_limit.tsx index 1056713ac2070..5dc8d6d367010 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/public/components/dataset_quality_details/degraded_field_flyout/possible_mitigations/field_limit/field_mapping_limit.tsx +++ b/x-pack/plugins/observability_solution/dataset_quality/public/components/dataset_quality_details/degraded_field_flyout/possible_mitigations/field_limit/field_mapping_limit.tsx @@ -29,7 +29,11 @@ import { IncreaseFieldMappingLimit } from './increase_field_mapping_limit'; import { FieldLimitDocLink } from './field_limit_documentation_link'; import { MessageCallout } from './message_callout'; -export function FieldMappingLimit({ isIntegration }: { isIntegration: boolean }) { +export function FieldMappingLimit({ + areIntegrationAssetsAvailable, +}: { + areIntegrationAssetsAvailable: boolean; +}) { const accordionId = useGeneratedHtmlId({ prefix: increaseFieldMappingLimitTitle, }); @@ -66,7 +70,7 @@ export function FieldMappingLimit({ isIntegration }: { isIntegration: boolean }) - {isIntegration && ( + {areIntegrationAssetsAvailable && ( <> updateNewFieldLimit(newFieldLimit)} isLoading={isMitigationInProgress} diff --git a/x-pack/plugins/observability_solution/dataset_quality/public/components/dataset_quality_details/degraded_field_flyout/possible_mitigations/index.tsx b/x-pack/plugins/observability_solution/dataset_quality/public/components/dataset_quality_details/degraded_field_flyout/possible_mitigations/index.tsx index 34f39f25a67ec..d9ca2128521f2 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/public/components/dataset_quality_details/degraded_field_flyout/possible_mitigations/index.tsx +++ b/x-pack/plugins/observability_solution/dataset_quality/public/components/dataset_quality_details/degraded_field_flyout/possible_mitigations/index.tsx @@ -15,7 +15,7 @@ import { PossibleMitigationTitle } from './title'; export function PossibleMitigations() { const { degradedFieldAnalysis, isAnalysisInProgress } = useDegradedFields(); const { integrationDetails } = useDatasetQualityDetailsState(); - const isIntegration = Boolean(integrationDetails?.integration); + const areIntegrationAssetsAvailable = !!integrationDetails?.integration?.areAssetsAvailable; return ( !isAnalysisInProgress && ( @@ -24,7 +24,7 @@ export function PossibleMitigations() { {degradedFieldAnalysis?.isFieldLimitIssue && ( <> - + )} diff --git a/x-pack/plugins/observability_solution/dataset_quality/public/components/dataset_quality_details/degraded_field_flyout/possible_mitigations/manual/component_template_link.tsx b/x-pack/plugins/observability_solution/dataset_quality/public/components/dataset_quality_details/degraded_field_flyout/possible_mitigations/manual/component_template_link.tsx index 54bbe91f2f2e1..e8768d34cdcca 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/public/components/dataset_quality_details/degraded_field_flyout/possible_mitigations/manual/component_template_link.tsx +++ b/x-pack/plugins/observability_solution/dataset_quality/public/components/dataset_quality_details/degraded_field_flyout/possible_mitigations/manual/component_template_link.tsx @@ -13,7 +13,11 @@ import { useDatasetQualityDetailsState } from '../../../../../hooks'; import { getComponentTemplatePrefixFromIndexTemplate } from '../../../../../../common/utils/component_template_name'; import { otherMitigationsCustomComponentTemplate } from '../../../../../../common/translations'; -export function CreateEditComponentTemplateLink({ isIntegration }: { isIntegration: boolean }) { +export function CreateEditComponentTemplateLink({ + areIntegrationAssetsAvailable, +}: { + areIntegrationAssetsAvailable: boolean; +}) { const { services: { application, @@ -54,7 +58,7 @@ export function CreateEditComponentTemplateLink({ isIntegration }: { isIntegrati name, ]); - const templateUrl = isIntegration ? componentTemplatePath : indexTemplatePath; + const templateUrl = areIntegrationAssetsAvailable ? componentTemplatePath : indexTemplatePath; const onClickHandler = useCallback(async () => { const options = { diff --git a/x-pack/plugins/observability_solution/dataset_quality/public/components/dataset_quality_details/degraded_field_flyout/possible_mitigations/manual/index.tsx b/x-pack/plugins/observability_solution/dataset_quality/public/components/dataset_quality_details/degraded_field_flyout/possible_mitigations/manual/index.tsx index f931f3461fb57..34cdbe4b9b838 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/public/components/dataset_quality_details/degraded_field_flyout/possible_mitigations/manual/index.tsx +++ b/x-pack/plugins/observability_solution/dataset_quality/public/components/dataset_quality_details/degraded_field_flyout/possible_mitigations/manual/index.tsx @@ -13,27 +13,27 @@ import { CreateEditPipelineLink } from './pipeline_link'; import { otherMitigationsLoadingAriaText } from '../../../../../../common/translations'; export function ManualMitigations() { - const { integrationDetails, loadingState, dataStreamSettings } = useDatasetQualityDetailsState(); - const isIntegrationPresentInSettings = dataStreamSettings?.integration; - const isIntegration = !!integrationDetails?.integration; - const { dataStreamSettingsLoading, integrationDetailsLoadings } = loadingState; - - const hasIntegrationCheckCompleted = - !dataStreamSettingsLoading && - ((isIntegrationPresentInSettings && !integrationDetailsLoadings) || - !isIntegrationPresentInSettings); + const { + integrationDetails, + loadingState: { integrationDetailsLoaded }, + } = useDatasetQualityDetailsState(); + const areIntegrationAssetsAvailable = !!integrationDetails?.integration?.areAssetsAvailable; return ( - + - + ); } diff --git a/x-pack/plugins/observability_solution/dataset_quality/public/components/dataset_quality_details/degraded_field_flyout/possible_mitigations/manual/pipeline_link.tsx b/x-pack/plugins/observability_solution/dataset_quality/public/components/dataset_quality_details/degraded_field_flyout/possible_mitigations/manual/pipeline_link.tsx index 6179a3ed0736c..f4084c52e2efd 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/public/components/dataset_quality_details/degraded_field_flyout/possible_mitigations/manual/pipeline_link.tsx +++ b/x-pack/plugins/observability_solution/dataset_quality/public/components/dataset_quality_details/degraded_field_flyout/possible_mitigations/manual/pipeline_link.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { useCallback, useMemo } from 'react'; +import React, { useCallback } from 'react'; import { FormattedMessage } from '@kbn/i18n-react'; import { i18n } from '@kbn/i18n'; import { @@ -34,7 +34,11 @@ const AccordionTitle = () => ( ); -export function CreateEditPipelineLink({ isIntegration }: { isIntegration: boolean }) { +export function CreateEditPipelineLink({ + areIntegrationAssetsAvailable, +}: { + areIntegrationAssetsAvailable: boolean; +}) { const { services: { share: { @@ -50,10 +54,7 @@ export function CreateEditPipelineLink({ isIntegration }: { isIntegration: boole const { datasetDetails } = useDatasetQualityDetailsState(); const { type, name } = datasetDetails; - const pipelineName = useMemo( - () => (isIntegration ? `${type}-${name}@custom` : `${type}@custom`), - [isIntegration, type, name] - ); + const pipelineName = areIntegrationAssetsAvailable ? `${type}-${name}@custom` : `${type}@custom`; const ingestPipelineLocator = locators.get('INGEST_PIPELINES_APP_LOCATOR'); diff --git a/x-pack/plugins/observability_solution/dataset_quality/public/components/dataset_quality_details/details/dataset_summary.tsx b/x-pack/plugins/observability_solution/dataset_quality/public/components/dataset_quality_details/details/dataset_summary.tsx index 17032d7866d05..8bbc9aa085420 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/public/components/dataset_quality_details/details/dataset_summary.tsx +++ b/x-pack/plugins/observability_solution/dataset_quality/public/components/dataset_quality_details/details/dataset_summary.tsx @@ -7,7 +7,7 @@ import React, { Fragment } from 'react'; import { ES_FIELD_TYPES, KBN_FIELD_TYPES } from '@kbn/field-types'; -import { EuiBadge, EuiFlexGroup, EuiPanel, EuiText } from '@elastic/eui'; +import { EuiBadge, EuiFlexGroup, EuiPanel, EuiSkeletonRectangle, EuiText } from '@elastic/eui'; import { css } from '@emotion/react'; import { IntegrationActionsMenu } from './integration_actions_menu'; import { @@ -29,7 +29,8 @@ export function DatasetSummary() { const { dataStreamDetailsLoading, dataStreamSettingsLoading, - integrationDetailsLoadings, + integrationDetailsLoading, + integrationDetailsLoaded, integrationDashboardsLoading, } = loadingState; const formattedLastActivity = dataStreamDetails?.lastActivity @@ -39,12 +40,19 @@ export function DatasetSummary() { ? dataFormatter.convert(dataStreamSettings.createdOn) : '-'; - return ( + return !integrationDetailsLoaded ? ( + + ) : ( - - {integrationDetails.integration?.name} + + + {integrationDetails.integration.integration?.name} + ), actionsMenu: ( ), - isLoading: integrationDetailsLoadings, + isLoading: integrationDetailsLoading, }, { fieldTitle: integrationVersionText, - fieldValue: integrationDetails.integration?.version, - isLoading: integrationDetailsLoadings, + fieldValue: integrationDetails.integration.integration?.version, + isLoading: integrationDetailsLoading, }, ] : []), diff --git a/x-pack/plugins/observability_solution/dataset_quality/public/components/dataset_quality_details/header.tsx b/x-pack/plugins/observability_solution/dataset_quality/public/components/dataset_quality_details/header.tsx index e45253b6405c8..60a26d4285732 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/public/components/dataset_quality_details/header.tsx +++ b/x-pack/plugins/observability_solution/dataset_quality/public/components/dataset_quality_details/header.tsx @@ -44,7 +44,8 @@ export function Header() { sendTelemetry, }); - const pageTitle = integrationDetails?.integration?.datasets?.[datasetDetails.name] ?? title; + const pageTitle = + integrationDetails?.integration?.integration?.datasets?.[datasetDetails.name] ?? title; return !loadingState.integrationDetailsLoaded ? ( - +

        diff --git a/x-pack/plugins/observability_solution/dataset_quality/public/hooks/use_dataset_details_telemetry.ts b/x-pack/plugins/observability_solution/dataset_quality/public/hooks/use_dataset_details_telemetry.ts index f613d3af7fdc4..4d2d838419271 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/public/hooks/use_dataset_details_telemetry.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/public/hooks/use_dataset_details_telemetry.ts @@ -42,7 +42,7 @@ export function useDatasetDetailsTelemetry() { breakdownField, isNonAggregatable, isBreakdownFieldEcs, - integration: integrationDetails.integration, + integration: integrationDetails.integration?.integration, }); } @@ -57,7 +57,7 @@ export function useDatasetDetailsTelemetry() { breakdownField, isNonAggregatable, isBreakdownFieldEcs, - integrationDetails.integration, + integrationDetails.integration?.integration, ]); const startTracking = useCallback(() => { diff --git a/x-pack/plugins/observability_solution/dataset_quality/public/hooks/use_dataset_quality_details_state.ts b/x-pack/plugins/observability_solution/dataset_quality/public/hooks/use_dataset_quality_details_state.ts index edd16652374a1..cfea77ff4fa39 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/public/hooks/use_dataset_quality_details_state.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/public/hooks/use_dataset_quality_details_state.ts @@ -51,7 +51,9 @@ export const useDatasetQualityDetailsState = () => { ); const dataStreamSettings = useSelector(service, (state) => - state.matches('initializing.dataStreamSettings.loadingIntegrationsAndDegradedFields') + state.matches('initializing.dataStreamSettings.fetchingDataStreamDegradedFields') || + state.matches('initializing.dataStreamSettings.doneFetchingDegradedFields') || + state.matches('initializing.dataStreamSettings.errorFetchingDegradedFields') ? state.context.dataStreamSettings : undefined ); @@ -59,15 +61,17 @@ export const useDatasetQualityDetailsState = () => { const integrationDetails = { integration: useSelector(service, (state) => state.matches( - 'initializing.dataStreamSettings.loadingIntegrationsAndDegradedFields.integrationDetails.done' - ) + 'initializing.checkAndLoadIntegrationAndDashboards.loadingIntegrationDashboards' + ) || + state.matches( + 'initializing.checkAndLoadIntegrationAndDashboards.unauthorizedToLoadDashboards' + ) || + state.matches('initializing.checkAndLoadIntegrationAndDashboards.done') ? state.context.integration : undefined ), dashboard: useSelector(service, (state) => - state.matches( - 'initializing.dataStreamSettings.loadingIntegrationsAndDegradedFields.integrationDashboards.done' - ) + state.matches('initializing.checkAndLoadIntegrationAndDashboards.done') ? state.context.integrationDashboards : undefined ), @@ -77,7 +81,7 @@ export const useDatasetQualityDetailsState = () => { service, (state) => !state.matches( - 'initializing.dataStreamSettings.loadingIntegrationsAndDegradedFields.integrationDashboards.unauthorized' + 'initializing.checkAndLoadIntegrationAndDashboards.unauthorizedToLoadDashboards' ) ); @@ -106,14 +110,19 @@ export const useDatasetQualityDetailsState = () => { dataStreamSettingsLoading: state.matches( 'initializing.dataStreamSettings.fetchingDataStreamSettings' ), - integrationDetailsLoadings: state.matches( - 'initializing.dataStreamSettings.loadingIntegrationsAndDegradedFields.integrationDetails.fetching' - ), - integrationDetailsLoaded: state.matches( - 'initializing.dataStreamSettings.loadingIntegrationsAndDegradedFields.integrationDetails.done' + integrationDetailsLoading: state.matches( + 'initializing.checkAndLoadIntegrationAndDashboards.checkingAndLoadingIntegration' ), + integrationDetailsLoaded: + state.matches( + 'initializing.checkAndLoadIntegrationAndDashboards.loadingIntegrationDashboards' + ) || + state.matches( + 'initializing.checkAndLoadIntegrationAndDashboards.unauthorizedToLoadDashboards' + ) || + state.matches('initializing.checkAndLoadIntegrationAndDashboards.done'), integrationDashboardsLoading: state.matches( - 'initializing.dataStreamSettings.loadingIntegrationsAndDegradedFields.integrationDashboards.fetching' + 'initializing.checkAndLoadIntegrationAndDashboards.loadingIntegrationDashboards' ), })); diff --git a/x-pack/plugins/observability_solution/dataset_quality/public/hooks/use_degraded_docs_chart.ts b/x-pack/plugins/observability_solution/dataset_quality/public/hooks/use_degraded_docs_chart.ts index fb57e6e87a74f..d499535df1662 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/public/hooks/use_degraded_docs_chart.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/public/hooks/use_degraded_docs_chart.ts @@ -81,7 +81,8 @@ export const useDegradedDocsChart = () => { useEffect(() => { const dataStreamName = dataStream ?? DEFAULT_LOGS_DATA_VIEW; const datasetTitle = - integrationDetails?.integration?.datasets?.[datasetDetails.name] ?? datasetDetails.name; + integrationDetails?.integration?.integration?.datasets?.[datasetDetails.name] ?? + datasetDetails.name; const lensAttributes = getLensAttributes({ color: euiTheme.colors.danger, @@ -95,7 +96,7 @@ export const useDegradedDocsChart = () => { euiTheme.colors.danger, setAttributes, dataStream, - integrationDetails?.integration?.datasets, + integrationDetails?.integration?.integration?.datasets, datasetDetails.name, ]); diff --git a/x-pack/plugins/observability_solution/dataset_quality/public/hooks/use_degraded_fields.ts b/x-pack/plugins/observability_solution/dataset_quality/public/hooks/use_degraded_fields.ts index 49ceb50abc3cd..47b03074fe17e 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/public/hooks/use_degraded_fields.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/public/hooks/use_degraded_fields.ts @@ -77,10 +77,11 @@ export function useDegradedFields() { return renderedItems.find((item) => item.name === expandedDegradedField); }, [expandedDegradedField, renderedItems]); - const isDegradedFieldsLoading = useSelector(service, (state) => - state.matches( - 'initializing.dataStreamSettings.loadingIntegrationsAndDegradedFields.dataStreamDegradedFields.fetching' - ) + const isDegradedFieldsLoading = useSelector( + service, + (state) => + state.matches('initializing.dataStreamSettings.fetchingDataStreamSettings') || + state.matches('initializing.dataStreamSettings.fetchingDataStreamDegradedFields') ); const closeDegradedFieldFlyout = useCallback( diff --git a/x-pack/plugins/observability_solution/dataset_quality/public/services/data_stream_details/data_stream_details_client.ts b/x-pack/plugins/observability_solution/dataset_quality/public/services/data_stream_details/data_stream_details_client.ts index 827cd4b0a1e49..7279bed2e1859 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/public/services/data_stream_details/data_stream_details_client.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/public/services/data_stream_details/data_stream_details_client.ts @@ -8,6 +8,8 @@ import { HttpStart } from '@kbn/core/public'; import { decodeOrThrow } from '@kbn/io-ts-utils'; import { + CheckAndLoadIntegrationResponse, + checkAndLoadIntegrationResponseRt, DataStreamRolloverResponse, dataStreamRolloverResponseRt, DegradedFieldAnalysis, @@ -17,10 +19,8 @@ import { getDataStreamDegradedFieldsResponseRt, getDataStreamsDetailsResponseRt, getDataStreamsSettingsResponseRt, - getIntegrationsResponseRt, IntegrationDashboardsResponse, integrationDashboardsRT, - IntegrationResponse, UpdateFieldLimitResponse, updateFieldLimitResponseRt, } from '../../../common/api_types'; @@ -40,7 +40,7 @@ import { IDataStreamDetailsClient } from './types'; import { Integration } from '../../../common/data_streams_stats/integration'; import { AnalyzeDegradedFieldsParams, - GetDataStreamIntegrationParams, + CheckAndLoadIntegrationParams, UpdateFieldLimitParams, } from '../../../common/data_stream_details/types'; import { DatasetQualityError } from '../../../common/errors'; @@ -139,43 +139,48 @@ export class DataStreamDetailsClient implements IDataStreamDetailsClient { )(response); } - public async getIntegrationDashboards({ integration }: GetIntegrationDashboardsParams) { + public async checkAndLoadIntegration({ dataStream }: CheckAndLoadIntegrationParams) { const response = await this.http - .get( - `/internal/dataset_quality/integrations/${integration}/dashboards` + .get( + `/internal/dataset_quality/data_streams/${dataStream}/integration/check` ) .catch((error) => { - throw new DatasetQualityError(`Failed to fetch integration dashboards": ${error}`, error); + throw new DatasetQualityError( + `Failed to check if data stream belongs to an integration": ${error}`, + error + ); }); - const { dashboards } = decodeOrThrow( - integrationDashboardsRT, + const decodedResponse = decodeOrThrow( + checkAndLoadIntegrationResponseRt, (message: string) => - new DatasetQualityError(`Failed to decode integration dashboards response: ${message}"`) + new DatasetQualityError(`Failed to decode integration check response: ${message}"`) )(response); - return dashboards; + return { + ...decodedResponse, + integration: decodedResponse.isIntegration + ? Integration.create(decodedResponse.integration) + : undefined, + }; } - public async getDataStreamIntegration( - params: GetDataStreamIntegrationParams - ): Promise { - const { integrationName } = params; + public async getIntegrationDashboards({ integration }: GetIntegrationDashboardsParams) { const response = await this.http - .get('/internal/dataset_quality/integrations') + .get( + `/internal/dataset_quality/integrations/${integration}/dashboards` + ) .catch((error) => { - throw new DatasetQualityError(`Failed to fetch integrations: ${error}`, error); + throw new DatasetQualityError(`Failed to fetch integration dashboards": ${error}`, error); }); - const { integrations } = decodeOrThrow( - getIntegrationsResponseRt, + const { dashboards } = decodeOrThrow( + integrationDashboardsRT, (message: string) => - new DatasetQualityError(`Failed to decode integrations response: ${message}`) + new DatasetQualityError(`Failed to decode integration dashboards response: ${message}"`) )(response); - const integration = integrations.find((i) => i.name === integrationName); - - if (integration) return Integration.create(integration); + return dashboards; } public async analyzeDegradedField({ diff --git a/x-pack/plugins/observability_solution/dataset_quality/public/services/data_stream_details/types.ts b/x-pack/plugins/observability_solution/dataset_quality/public/services/data_stream_details/types.ts index 6eac8bd732840..f38c68a68bff5 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/public/services/data_stream_details/types.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/public/services/data_stream_details/types.ts @@ -6,7 +6,6 @@ */ import { HttpStart } from '@kbn/core/public'; -import { Integration } from '../../../common/data_streams_stats/integration'; import { GetDataStreamSettingsParams, DataStreamSettings, @@ -19,7 +18,8 @@ import { } from '../../../common/data_streams_stats'; import { AnalyzeDegradedFieldsParams, - GetDataStreamIntegrationParams, + IntegrationType, + CheckAndLoadIntegrationParams, UpdateFieldLimitParams, } from '../../../common/data_stream_details/types'; import { @@ -49,10 +49,8 @@ export interface IDataStreamDetailsClient { getDataStreamDegradedFieldValues( params: GetDataStreamDegradedFieldValuesPathParams ): Promise; + checkAndLoadIntegration(params: CheckAndLoadIntegrationParams): Promise; getIntegrationDashboards(params: GetIntegrationDashboardsParams): Promise; - getDataStreamIntegration( - params: GetDataStreamIntegrationParams - ): Promise; analyzeDegradedField(params: AnalyzeDegradedFieldsParams): Promise; setNewFieldLimit(params: UpdateFieldLimitParams): Promise; rolloverDataStream(params: { dataStream: string }): Promise; diff --git a/x-pack/plugins/observability_solution/dataset_quality/public/services/data_streams_stats/data_streams_stats_client.ts b/x-pack/plugins/observability_solution/dataset_quality/public/services/data_streams_stats/data_streams_stats_client.ts index 8e218819315b2..5e4790309a07f 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/public/services/data_streams_stats/data_streams_stats_client.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/public/services/data_streams_stats/data_streams_stats_client.ts @@ -17,7 +17,7 @@ import { getDataStreamTotalDocsResponseRt, getIntegrationsResponseRt, getNonAggregatableDatasetsRt, - IntegrationResponse, + IntegrationsResponse, NonAggregatableDatasets, } from '../../../common/api_types'; import { @@ -132,7 +132,7 @@ export class DataStreamsStatsClient implements IDataStreamsStatsClient { public async getIntegrations(): Promise { const response = await this.http - .get('/internal/dataset_quality/integrations') + .get('/internal/dataset_quality/integrations') .catch((error) => { throw new DatasetQualityError(`Failed to fetch integrations: ${error}`, error); }); diff --git a/x-pack/plugins/observability_solution/dataset_quality/public/state_machines/dataset_quality_details_controller/notifications.ts b/x-pack/plugins/observability_solution/dataset_quality/public/state_machines/dataset_quality_details_controller/notifications.ts index f5fdd063492a3..fbd2dd1dc1913 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/public/state_machines/dataset_quality_details_controller/notifications.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/public/state_machines/dataset_quality_details_controller/notifications.ts @@ -44,17 +44,10 @@ export const fetchIntegrationDashboardsFailedNotifier = (toasts: IToasts, error: }); }; -export const fetchDataStreamIntegrationFailedNotifier = ( - toasts: IToasts, - error: Error, - integrationName?: string -) => { +export const fetchDataStreamIntegrationFailedNotifier = (toasts: IToasts, error: Error) => { toasts.addDanger({ title: i18n.translate('xpack.datasetQuality.details.fetchIntegrationsFailed', { - defaultMessage: "We couldn't get {integrationName} integration info.", - values: { - integrationName, - }, + defaultMessage: "We couldn't get integration info.", }), text: error.message, }); diff --git a/x-pack/plugins/observability_solution/dataset_quality/public/state_machines/dataset_quality_details_controller/state_machine.ts b/x-pack/plugins/observability_solution/dataset_quality/public/state_machines/dataset_quality_details_controller/state_machine.ts index 8ac65a7dca4a7..363919b35f65e 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/public/state_machines/dataset_quality_details_controller/state_machine.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/public/state_machines/dataset_quality_details_controller/state_machine.ts @@ -28,6 +28,8 @@ import { UpdateFieldLimitResponse, } from '../../../common/api_types'; import { fetchNonAggregatableDatasetsFailedNotifier } from '../common/notifications'; + +import { IntegrationType } from '../../../common/data_stream_details'; import { fetchDataStreamDetailsFailedNotifier, assertBreakdownFieldEcsFailedNotifier, @@ -37,7 +39,6 @@ import { updateFieldLimitFailedNotifier, rolloverDataStreamFailedNotifier, } from './notifications'; -import { Integration } from '../../../common/data_streams_stats/integration'; export const createPureDatasetQualityDetailsControllerStateMachine = ( initialContext: DatasetQualityDetailsControllerContext @@ -151,7 +152,7 @@ export const createPureDatasetQualityDetailsControllerStateMachine = ( invoke: { src: 'loadDataStreamSettings', onDone: { - target: 'loadingIntegrationsAndDegradedFields', + target: 'fetchingDataStreamDegradedFields', actions: ['storeDataStreamSettings'], }, onError: [ @@ -160,111 +161,49 @@ export const createPureDatasetQualityDetailsControllerStateMachine = ( cond: 'isIndexNotFoundError', }, { - target: 'done', + target: 'errorFetchingDataStreamSettings', actions: ['notifyFetchDataStreamSettingsFailed'], }, ], }, }, - loadingIntegrationsAndDegradedFields: { - type: 'parallel', - states: { - dataStreamDegradedFields: { - initial: 'fetching', - states: { - fetching: { - invoke: { - src: 'loadDegradedFields', - onDone: { - target: 'done', - actions: ['storeDegradedFields', 'raiseDegradedFieldsLoaded'], - }, - onError: [ - { - target: '#DatasetQualityDetailsController.indexNotFound', - cond: 'isIndexNotFoundError', - }, - { - target: 'done', - }, - ], - }, - }, - done: { - on: { - UPDATE_DEGRADED_FIELDS_TABLE_CRITERIA: { - target: 'done', - actions: ['storeDegradedFieldTableOptions'], - }, - OPEN_DEGRADED_FIELD_FLYOUT: { - target: - '#DatasetQualityDetailsController.initializing.degradedFieldFlyout.open', - actions: [ - 'storeExpandedDegradedField', - 'resetFieldLimitServerResponse', - ], - }, - TOGGLE_CURRENT_QUALITY_ISSUES: { - target: 'fetching', - actions: ['toggleCurrentQualityIssues'], - }, - }, - }, - }, + errorFetchingDataStreamSettings: {}, + fetchingDataStreamDegradedFields: { + invoke: { + src: 'loadDegradedFields', + onDone: { + target: 'doneFetchingDegradedFields', + actions: ['storeDegradedFields', 'raiseDegradedFieldsLoaded'], }, - integrationDetails: { - initial: 'fetching', - states: { - fetching: { - invoke: { - src: 'loadDataStreamIntegration', - onDone: { - target: 'done', - actions: ['storeDataStreamIntegration'], - }, - onError: { - target: 'done', - actions: ['notifyFetchDatasetIntegrationsFailed'], - }, - }, - }, - done: {}, + onError: [ + { + target: '#DatasetQualityDetailsController.indexNotFound', + cond: 'isIndexNotFoundError', }, - }, - integrationDashboards: { - initial: 'fetching', - states: { - fetching: { - invoke: { - src: 'loadIntegrationDashboards', - onDone: { - target: 'done', - actions: ['storeIntegrationDashboards'], - }, - onError: [ - { - target: 'unauthorized', - cond: 'checkIfActionForbidden', - }, - { - target: 'done', - actions: ['notifyFetchIntegrationDashboardsFailed'], - }, - ], - }, - }, - done: {}, - unauthorized: { - type: 'final', - }, + { + target: 'errorFetchingDegradedFields', }, - }, + ], }, - onDone: { - target: 'done', + }, + doneFetchingDegradedFields: { + on: { + UPDATE_DEGRADED_FIELDS_TABLE_CRITERIA: { + target: 'doneFetchingDegradedFields', + actions: ['storeDegradedFieldTableOptions'], + }, + OPEN_DEGRADED_FIELD_FLYOUT: { + target: + '#DatasetQualityDetailsController.initializing.degradedFieldFlyout.open', + actions: ['storeExpandedDegradedField', 'resetFieldLimitServerResponse'], + }, + TOGGLE_CURRENT_QUALITY_ISSUES: { + target: 'fetchingDataStreamDegradedFields', + actions: ['toggleCurrentQualityIssues'], + }, }, }, - done: {}, + errorFetchingDegradedFields: {}, }, on: { UPDATE_TIME_RANGE: { @@ -272,6 +211,54 @@ export const createPureDatasetQualityDetailsControllerStateMachine = ( }, }, }, + checkAndLoadIntegrationAndDashboards: { + initial: 'checkingAndLoadingIntegration', + states: { + checkingAndLoadingIntegration: { + invoke: { + src: 'checkAndLoadIntegration', + onDone: [ + { + target: 'loadingIntegrationDashboards', + actions: 'storeDataStreamIntegration', + cond: 'isDataStreamIsPartOfIntegration', + }, + { + actions: 'storeDataStreamIntegration', + target: 'done', + }, + ], + onError: { + target: 'done', + actions: ['notifyFetchDatasetIntegrationsFailed'], + }, + }, + }, + loadingIntegrationDashboards: { + invoke: { + src: 'loadIntegrationDashboards', + onDone: { + target: 'done', + actions: ['storeIntegrationDashboards'], + }, + onError: [ + { + target: 'unauthorizedToLoadDashboards', + cond: 'checkIfActionForbidden', + }, + { + target: 'done', + actions: ['notifyFetchIntegrationDashboardsFailed'], + }, + ], + }, + }, + unauthorizedToLoadDashboards: { + type: 'final', + }, + done: {}, + }, + }, degradedFieldFlyout: { initial: 'pending', states: { @@ -522,7 +509,7 @@ export const createPureDatasetQualityDetailsControllerStateMachine = ( } : {}; }), - storeDataStreamIntegration: assign((context, event: DoneInvokeEvent) => { + storeDataStreamIntegration: assign((context, event: DoneInvokeEvent) => { return 'data' in event ? { integration: event.data, @@ -602,6 +589,14 @@ export const createPureDatasetQualityDetailsControllerStateMachine = ( !event.data.isLatestBackingIndexUpdated ); }, + isDataStreamIsPartOfIntegration: (_, event) => { + return ( + 'data' in event && + typeof event.data === 'object' && + 'isIntegration' in event.data && + event.data.isIntegration + ); + }, }, } ); @@ -634,9 +629,7 @@ export const createDatasetQualityDetailsControllerStateMachine = ({ notifyFetchIntegrationDashboardsFailed: (_context, event: DoneInvokeEvent) => fetchIntegrationDashboardsFailedNotifier(toasts, event.data), notifyFetchDatasetIntegrationsFailed: (context, event: DoneInvokeEvent) => { - const integrationName = - 'dataStreamSettings' in context ? context.dataStreamSettings?.integration : undefined; - return fetchDataStreamIntegrationFailedNotifier(toasts, event.data, integrationName); + return fetchDataStreamIntegrationFailedNotifier(toasts, event.data); }, notifySaveNewFieldLimitError: (_context, event: DoneInvokeEvent) => updateFieldLimitFailedNotifier(toasts, event.data), @@ -735,18 +728,15 @@ export const createDatasetQualityDetailsControllerStateMachine = ({ dataStream: context.dataStream, }); }, - loadDataStreamIntegration: (context) => { - if ('dataStreamSettings' in context && context.dataStreamSettings?.integration) { - return dataStreamDetailsClient.getDataStreamIntegration({ - integrationName: context.dataStreamSettings.integration, - }); - } - return Promise.resolve(); + checkAndLoadIntegration: (context) => { + return dataStreamDetailsClient.checkAndLoadIntegration({ + dataStream: context.dataStream, + }); }, loadIntegrationDashboards: (context) => { - if ('dataStreamSettings' in context && context.dataStreamSettings?.integration) { + if ('integration' in context && context.integration && context.integration.integration) { return dataStreamDetailsClient.getIntegrationDashboards({ - integration: context.dataStreamSettings.integration, + integration: context.integration.integration.name, }); } diff --git a/x-pack/plugins/observability_solution/dataset_quality/public/state_machines/dataset_quality_details_controller/types.ts b/x-pack/plugins/observability_solution/dataset_quality/public/state_machines/dataset_quality_details_controller/types.ts index cdebcfbe53d86..d33e5c4f0415e 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/public/state_machines/dataset_quality_details_controller/types.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/public/state_machines/dataset_quality_details_controller/types.ts @@ -20,7 +20,7 @@ import { UpdateFieldLimitResponse, } from '../../../common/api_types'; import { TableCriteria, TimeRangeConfig } from '../../../common/types'; -import { Integration } from '../../../common/data_streams_stats/integration'; +import { IntegrationType } from '../../../common/data_stream_details'; export interface DataStream { name: string; @@ -53,7 +53,7 @@ export interface WithDefaultControllerState { breakdownField?: string; isBreakdownFieldEcs?: boolean; isIndexNotFoundError?: boolean; - integration?: Integration; + integration?: IntegrationType; expandedDegradedField?: string; isNonAggregatable?: boolean; fieldLimit?: FieldLimit; @@ -84,8 +84,11 @@ export interface WithDataStreamSettings { } export interface WithIntegration { - integration: Integration; - integrationDashboards?: Dashboard[]; + integration: IntegrationType; +} + +export interface WithIntegrationDashboards { + integrationDashboards: Dashboard[]; } export interface WithDegradedFieldValues { @@ -116,15 +119,14 @@ export type DatasetQualityDetailsControllerTypeState = value: | 'initializing' | 'initializing.nonAggregatableDataset.fetching' - | 'initializing.dataStreamSettings.loadingIntegrationsAndDegradedFields.dataStreamDegradedFields.fetching' + | 'initializing.dataStreamDetails.fetching' | 'initializing.dataStreamSettings.fetchingDataStreamSettings' - | 'initializing.dataStreamDetails.fetching'; + | 'initializing.dataStreamSettings.errorFetchingDataStreamSettings' + | 'initializing.checkAndLoadIntegrationAndDashboards.checkingAndLoadingIntegration'; context: WithDefaultControllerState; } | { - value: - | 'initializing.nonAggregatableDataset.done' - | 'initializing.dataStreamSettings.loadingIntegrationsAndDegradedFields.dataStreamDegradedFields.fetching'; + value: 'initializing.nonAggregatableDataset.done'; context: WithDefaultControllerState & WithNonAggregatableDatasetStatus; } | { @@ -139,25 +141,25 @@ export type DatasetQualityDetailsControllerTypeState = value: 'initializing.checkBreakdownFieldIsEcs.done'; context: WithDefaultControllerState & WithBreakdownInEcsCheck; } - | { - value: 'initializing.dataStreamSettings.loadingIntegrationsAndDegradedFields.dataStreamDegradedFields.done'; - context: WithDefaultControllerState & - WithNonAggregatableDatasetStatus & - WithDegradedFieldsData; - } | { value: - | 'initializing.dataStreamSettings.loadingIntegrationsAndDegradedFields' - | 'initializing.dataStreamSettings.loadingIntegrationsAndDegradedFields.integrationDetails.fetching' - | 'initializing.dataStreamSettings.loadingIntegrationsAndDegradedFields.integrationDashboards.fetching' - | 'initializing.dataStreamSettings.loadingIntegrationsAndDegradedFields.integrationDashboards.unauthorized'; + | 'initializing.dataStreamSettings.fetchingDataStreamDegradedFields' + | 'initializing.dataStreamSettings.errorFetchingDegradedFields'; context: WithDefaultControllerState & WithDataStreamSettings; } + | { + value: 'initializing.dataStreamSettings.doneFetchingDegradedFields'; + context: WithDefaultControllerState & WithDataStreamSettings & WithDegradedFieldsData; + } | { value: - | 'initializing.dataStreamSettings.loadingIntegrationsAndDegradedFields.integrationDetails.done' - | 'initializing.dataStreamSettings.loadingIntegrationsAndDegradedFields.integrationDashboards.done'; - context: WithDefaultControllerState & WithDataStreamSettings & WithIntegration; + | 'initializing.checkAndLoadIntegrationAndDashboards.loadingIntegrationDashboards' + | 'initializing.checkAndLoadIntegrationAndDashboards.unauthorizedToLoadDashboards'; + context: WithDefaultControllerState & WithIntegration; + } + | { + value: 'initializing.checkAndLoadIntegrationAndDashboards.done'; + context: WithDefaultControllerState & WithIntegration & WithIntegrationDashboards; } | { value: 'initializing.degradedFieldFlyout.open'; @@ -233,8 +235,8 @@ export type DatasetQualityDetailsControllerEvent = | DoneInvokeEvent | DoneInvokeEvent | DoneInvokeEvent - | DoneInvokeEvent | DoneInvokeEvent | DoneInvokeEvent | DoneInvokeEvent - | DoneInvokeEvent; + | DoneInvokeEvent + | DoneInvokeEvent; diff --git a/x-pack/plugins/observability_solution/dataset_quality/server/routes/data_streams/check_and_load_integration/index.ts b/x-pack/plugins/observability_solution/dataset_quality/server/routes/data_streams/check_and_load_integration/index.ts new file mode 100644 index 0000000000000..a6606028b6cfc --- /dev/null +++ b/x-pack/plugins/observability_solution/dataset_quality/server/routes/data_streams/check_and_load_integration/index.ts @@ -0,0 +1,105 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { ElasticsearchClient } from '@kbn/core-elasticsearch-server'; +import { PackageClient } from '@kbn/fleet-plugin/server'; +import { Logger } from '@kbn/logging'; +import { validateCustomComponentTemplate } from './validate_custom_component_template'; +import { getIntegration, getIntegrations } from '../../integrations/get_integrations'; +import { getComponentTemplatePrefixFromIndexTemplate } from '../../../../common/utils/component_template_name'; +import { CheckAndLoadIntegrationResponse } from '../../../../common/api_types'; +import { dataStreamService } from '../../../services'; + +// The function works on 2 conditions: +// 1. It checks if integration name is present in meta field response of the datastream. +// If yes, it considers it to be an integration. No further checks +// 2. If not, then it does the various checks +export async function checkAndLoadIntegration({ + esClient, + packageClient, + logger, + dataStream, +}: { + esClient: ElasticsearchClient; + packageClient: PackageClient; + logger: Logger; + dataStream: string; +}): Promise { + const [dataStreamInfo] = await dataStreamService.getMatchingDataStreams(esClient, dataStream); + + const indexTemplate = dataStreamInfo?.template; + const isManaged = dataStreamInfo?._meta?.managed; + + const integrationNameFromDataStream = dataStreamInfo?._meta?.package?.name; + + // Index template must be present and isManaged should be true or + // integration name should be present + // Else it's not an integration + if ((!indexTemplate || !isManaged) && !integrationNameFromDataStream) { + return { isIntegration: false, areAssetsAvailable: false }; + } + + // If integration name is present, then we find and return the integration + if (integrationNameFromDataStream) { + try { + const integrationDetailsMatchingDataStream = await getIntegration({ + packageClient, + logger, + packageName: integrationNameFromDataStream, + }); + + if (integrationDetailsMatchingDataStream) { + return { + isIntegration: true, + integration: integrationDetailsMatchingDataStream, + areAssetsAvailable: true, + }; + } + } catch (e) { + // This should ideally not happen. As integration name is present in Data stream + // meta response but the integration itself is not found + // Worst case i could think of is, may be the integration is deleted from the + // system at a later point of time + return { isIntegration: false, areAssetsAvailable: false }; + } + } + + // cleaning the index template name as some have @template suffix + const indexTemplateNameWithoutSuffix = getComponentTemplatePrefixFromIndexTemplate(indexTemplate); + + // Check if index template name has both type and dataset part + const isDedicatedComponentTemplate = indexTemplateNameWithoutSuffix.split('-').length === 2; + + // If only 1 part exists, then it's not a dedicated index template + // Data stream name must starts with this index template, then it's a dedicated index template else not + if (!isDedicatedComponentTemplate || !dataStream.startsWith(indexTemplateNameWithoutSuffix)) { + return { isIntegration: false, areAssetsAvailable: false }; + } + + const isValidCustomComponentTemplate = await validateCustomComponentTemplate({ + esClient, + indexTemplateName: indexTemplate, + }); + + if (!isValidCustomComponentTemplate) { + return { isIntegration: false, areAssetsAvailable: false }; + } + + const datasetName = indexTemplateNameWithoutSuffix.split('-')[1]; + + const allIntegrations = await getIntegrations({ packageClient, logger }); + const integrationFromDataset = allIntegrations.find( + (integration) => datasetName in (integration?.datasets ?? {}) + ); + + if (integrationFromDataset) { + return { isIntegration: true, integration: integrationFromDataset, areAssetsAvailable: true }; + } + + // Since the logic reached the last statement, it means it passed all checks for assets being available + return { isIntegration: false, areAssetsAvailable: true }; +} diff --git a/x-pack/plugins/observability_solution/dataset_quality/server/routes/data_streams/check_and_load_integration/validate_custom_component_template.ts b/x-pack/plugins/observability_solution/dataset_quality/server/routes/data_streams/check_and_load_integration/validate_custom_component_template.ts new file mode 100644 index 0000000000000..13213814935f1 --- /dev/null +++ b/x-pack/plugins/observability_solution/dataset_quality/server/routes/data_streams/check_and_load_integration/validate_custom_component_template.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 { ElasticsearchClient } from '@kbn/core-elasticsearch-server'; +import { createDatasetQualityESClient } from '../../../utils'; +import { getComponentTemplatePrefixFromIndexTemplate } from '../../../../common/utils/component_template_name'; + +export async function validateCustomComponentTemplate({ + esClient, + indexTemplateName, +}: { + esClient: ElasticsearchClient; + indexTemplateName: string; +}): Promise { + const datasetQualityESClient = createDatasetQualityESClient(esClient); + // cleaning the index template name as some have @template suffix + const componentTemplateName = getComponentTemplatePrefixFromIndexTemplate(indexTemplateName); + + try { + const { index_templates: indexTemplates } = await datasetQualityESClient.indexTemplates({ + name: indexTemplateName, + }); + + return indexTemplates.some((template) => + template.index_template.composed_of.includes(componentTemplateName + '@custom') + ); + } catch (error) { + return false; + } +} diff --git a/x-pack/plugins/observability_solution/dataset_quality/server/routes/data_streams/get_data_stream_details/index.ts b/x-pack/plugins/observability_solution/dataset_quality/server/routes/data_streams/get_data_stream_details/index.ts index 288eff11b92a8..0ca2ae94214e8 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/server/routes/data_streams/get_data_stream_details/index.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/server/routes/data_streams/get_data_stream_details/index.ts @@ -16,38 +16,12 @@ import { rangeQuery } from '@kbn/observability-plugin/server'; import { MAX_HOSTS_METRIC_VALUE } from '../../../../common/constants'; import { _IGNORED } from '../../../../common/es_fields'; -import { DataStreamDetails, DataStreamSettings } from '../../../../common/api_types'; +import { DataStreamDetails } from '../../../../common/api_types'; import { createDatasetQualityESClient } from '../../../utils'; -import { dataStreamService, datasetQualityPrivileges } from '../../../services'; +import { datasetQualityPrivileges } from '../../../services'; import { getDataStreams } from '../get_data_streams'; import { getDataStreamsMeteringStats } from '../get_data_streams_metering_stats'; -export async function getDataStreamSettings({ - esClient, - dataStream, -}: { - esClient: ElasticsearchClient; - dataStream: string; -}): Promise { - const [createdOn, [dataStreamInfo], datasetUserPrivileges] = await Promise.all([ - getDataStreamCreatedOn(esClient, dataStream), - dataStreamService.getMatchingDataStreams(esClient, dataStream), - datasetQualityPrivileges.getDatasetPrivileges(esClient, dataStream), - ]); - - const integration = dataStreamInfo?._meta?.package?.name; - const lastBackingIndex = dataStreamInfo?.indices?.slice(-1)[0]; - const indexTemplate = dataStreamInfo?.template; - - return { - createdOn, - integration, - datasetUserPrivileges, - lastBackingIndexName: lastBackingIndex?.index_name, - indexTemplate, - }; -} - export async function getDataStreamDetails({ esClient, dataStream, @@ -118,16 +92,6 @@ export async function getDataStreamDetails({ } } -async function getDataStreamCreatedOn(esClient: ElasticsearchClient, dataStream: string) { - const indexSettings = await dataStreamService.getDataStreamIndexSettings(esClient, dataStream); - - const indexesList = Object.values(indexSettings); - - return indexesList - .map((index) => Number(index.settings?.index?.creation_date)) - .sort((a, b) => a - b)[0]; -} - type TermAggregation = Record; const MAX_HOSTS = MAX_HOSTS_METRIC_VALUE + 1; // Adding 1 so that we can show e.g. '50+' diff --git a/x-pack/plugins/observability_solution/dataset_quality/server/routes/data_streams/get_datastream_settings/get_datastream_created_on.ts b/x-pack/plugins/observability_solution/dataset_quality/server/routes/data_streams/get_datastream_settings/get_datastream_created_on.ts new file mode 100644 index 0000000000000..d9d22d326bffb --- /dev/null +++ b/x-pack/plugins/observability_solution/dataset_quality/server/routes/data_streams/get_datastream_settings/get_datastream_created_on.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 { ElasticsearchClient } from '@kbn/core-elasticsearch-server'; +import { dataStreamService } from '../../../services'; + +export async function getDataStreamCreatedOn(esClient: ElasticsearchClient, dataStream: string) { + const indexSettings = await dataStreamService.getDataStreamIndexSettings(esClient, dataStream); + + const indexesList = Object.values(indexSettings); + + return indexesList + .map((index) => Number(index.settings?.index?.creation_date)) + .sort((a, b) => a - b)[0]; +} diff --git a/x-pack/plugins/observability_solution/dataset_quality/server/routes/data_streams/get_datastream_settings/index.ts b/x-pack/plugins/observability_solution/dataset_quality/server/routes/data_streams/get_datastream_settings/index.ts new file mode 100644 index 0000000000000..8044c8a5abf6a --- /dev/null +++ b/x-pack/plugins/observability_solution/dataset_quality/server/routes/data_streams/get_datastream_settings/index.ts @@ -0,0 +1,37 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { ElasticsearchClient } from '@kbn/core-elasticsearch-server'; +import { datasetQualityPrivileges, dataStreamService } from '../../../services'; +import { DataStreamSettings } from '../../../../common/api_types'; +import { getDataStreamCreatedOn } from './get_datastream_created_on'; + +export async function getDataStreamSettings({ + esClient, + dataStream, +}: { + esClient: ElasticsearchClient; + dataStream: string; +}): Promise { + const [createdOn, [dataStreamInfo], datasetUserPrivileges] = await Promise.all([ + getDataStreamCreatedOn(esClient, dataStream), + dataStreamService.getMatchingDataStreams(esClient, dataStream), + datasetQualityPrivileges.getDatasetPrivileges(esClient, dataStream), + ]); + + const integration = dataStreamInfo?._meta?.package?.name; + const lastBackingIndex = dataStreamInfo?.indices?.at(-1); + const indexTemplate = dataStreamInfo?.template; + + return { + createdOn, + integration, + datasetUserPrivileges, + lastBackingIndexName: lastBackingIndex?.index_name, + indexTemplate, + }; +} diff --git a/x-pack/plugins/observability_solution/dataset_quality/server/routes/data_streams/routes.ts b/x-pack/plugins/observability_solution/dataset_quality/server/routes/data_streams/routes.ts index 3a60f0b9a8ef3..c8ed3296908e3 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/server/routes/data_streams/routes.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/server/routes/data_streams/routes.ts @@ -18,11 +18,12 @@ import { DataStreamDocsStat, UpdateFieldLimitResponse, DataStreamRolloverResponse, + CheckAndLoadIntegrationResponse, } from '../../../common/api_types'; import { rangeRt, typeRt, typesRt } from '../../types/default_api_types'; import { createDatasetQualityServerRoute } from '../create_datasets_quality_server_route'; import { datasetQualityPrivileges } from '../../services'; -import { getDataStreamDetails, getDataStreamSettings } from './get_data_stream_details'; +import { getDataStreamDetails } from './get_data_stream_details'; import { getDataStreams } from './get_data_streams'; import { getDataStreamsStats } from './get_data_streams_stats'; import { getDegradedDocsPaginated } from './get_degraded_docs'; @@ -34,6 +35,8 @@ import { getDataStreamsMeteringStats } from './get_data_streams_metering_stats'; import { getAggregatedDatasetPaginatedResults } from './get_dataset_aggregated_paginated_results'; import { updateFieldLimit } from './update_field_limit'; import { createDatasetQualityESClient } from '../../utils'; +import { getDataStreamSettings } from './get_datastream_settings'; +import { checkAndLoadIntegration } from './check_and_load_integration'; const statsRoute = createDatasetQualityServerRoute({ endpoint: 'GET /internal/dataset_quality/data_streams/stats', @@ -293,6 +296,38 @@ const dataStreamSettingsRoute = createDatasetQualityServerRoute({ }, }); +const checkAndLoadIntegrationRoute = createDatasetQualityServerRoute({ + endpoint: 'GET /internal/dataset_quality/data_streams/{dataStream}/integration/check', + params: t.type({ + path: t.type({ + dataStream: t.string, + }), + }), + options: { + tags: [], + }, + async handler(resources): Promise { + const { context, params, plugins, logger } = resources; + const { dataStream } = params.path; + 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 integration = await checkAndLoadIntegration({ + esClient, + packageClient, + logger, + dataStream, + }); + + return integration; + }, +}); + const dataStreamDetailsRoute = createDatasetQualityServerRoute({ endpoint: 'GET /internal/dataset_quality/data_streams/{dataStream}/details', params: t.type({ @@ -418,6 +453,7 @@ export const dataStreamsRouteRepository = { ...degradedFieldValuesRoute, ...dataStreamDetailsRoute, ...dataStreamSettingsRoute, + ...checkAndLoadIntegrationRoute, ...analyzeDegradedFieldRoute, ...updateFieldLimitRoute, ...rolloverDataStream, diff --git a/x-pack/plugins/observability_solution/dataset_quality/server/routes/data_streams/update_field_limit/index.ts b/x-pack/plugins/observability_solution/dataset_quality/server/routes/data_streams/update_field_limit/index.ts index f377ea1e2642c..d00831a58aa7f 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/server/routes/data_streams/update_field_limit/index.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/server/routes/data_streams/update_field_limit/index.ts @@ -11,7 +11,7 @@ import { createDatasetQualityESClient } from '../../../utils'; import { updateComponentTemplate } from './update_component_template'; import { updateLastBackingIndexSettings } from './update_settings_last_backing_index'; import { UpdateFieldLimitResponse } from '../../../../common/api_types'; -import { getDataStreamSettings } from '../get_data_stream_details'; +import { getDataStreamSettings } from '../get_datastream_settings'; export async function updateFieldLimit({ esClient, diff --git a/x-pack/plugins/observability_solution/dataset_quality/server/routes/integrations/get_integrations.ts b/x-pack/plugins/observability_solution/dataset_quality/server/routes/integrations/get_integrations.ts index 10e89db800a20..b8bf8719783ce 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/server/routes/integrations/get_integrations.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/server/routes/integrations/get_integrations.ts @@ -8,9 +8,29 @@ import { Logger } from '@kbn/core/server'; import { PackageClient } from '@kbn/fleet-plugin/server'; import { PackageNotFoundError } from '@kbn/fleet-plugin/server/errors'; -import { PackageListItem, RegistryDataStream } from '@kbn/fleet-plugin/common'; +import { PackageInfo, RegistryDataStream } from '@kbn/fleet-plugin/common'; import { IntegrationType } from '../../../common/api_types'; +export async function getIntegration({ + packageClient, + logger, + packageName, +}: { + packageClient: PackageClient; + logger: Logger; + packageName: string; +}): Promise { + const latestPackage = await packageClient.getLatestPackageInfo(packageName); + + return { + name: latestPackage.name, + title: latestPackage.title, + version: latestPackage.version, + icons: latestPackage.icons, + datasets: await getDatasets({ packageClient, logger, pkg: latestPackage }), + }; +} + export async function getIntegrations(options: { packageClient: PackageClient; logger: Logger; @@ -36,7 +56,7 @@ export async function getIntegrations(options: { const getDatasets = async (options: { packageClient: PackageClient; logger: Logger; - pkg: PackageListItem; + pkg: Pick; }) => { const { packageClient, logger, pkg } = options; diff --git a/x-pack/plugins/observability_solution/dataset_quality/server/utils/create_dataset_quality_es_client.ts b/x-pack/plugins/observability_solution/dataset_quality/server/utils/create_dataset_quality_es_client.ts index 8a78b4163da95..cb6c963435f1e 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/server/utils/create_dataset_quality_es_client.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/server/utils/create_dataset_quality_es_client.ts @@ -13,6 +13,8 @@ import { FieldCapsRequest, FieldCapsResponse, Indices, + IndicesGetIndexTemplateRequest, + IndicesGetIndexTemplateResponse, IndicesGetMappingResponse, IndicesGetSettingsResponse, IndicesPutSettingsRequest, @@ -63,5 +65,10 @@ export function createDatasetQualityESClient(esClient: ElasticsearchClient) { rollover(params: { alias: string }): Promise { return esClient.indices.rollover(params); }, + indexTemplates( + params: IndicesGetIndexTemplateRequest + ): Promise { + return esClient.indices.getIndexTemplate(params); + }, }; } diff --git a/x-pack/plugins/observability_solution/dataset_quality/tsconfig.json b/x-pack/plugins/observability_solution/dataset_quality/tsconfig.json index 8576b08bd9479..57b159cdbd295 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/tsconfig.json +++ b/x-pack/plugins/observability_solution/dataset_quality/tsconfig.json @@ -61,7 +61,8 @@ "@kbn/rison", "@kbn/task-manager-plugin", "@kbn/core-application-browser", - "@kbn/field-utils" + "@kbn/field-utils", + "@kbn/logging" ], "exclude": [ "target/**/*" diff --git a/x-pack/plugins/observability_solution/entity_manager_app/public/pages/overview/index.tsx b/x-pack/plugins/observability_solution/entity_manager_app/public/pages/overview/index.tsx index 8c978db6f6751..59740fb8f8135 100644 --- a/x-pack/plugins/observability_solution/entity_manager_app/public/pages/overview/index.tsx +++ b/x-pack/plugins/observability_solution/entity_manager_app/public/pages/overview/index.tsx @@ -101,17 +101,29 @@ function EntitySourceForm({ /> + + + + onFieldChange(index, 'display_name', e.target.value)} + /> + + ); } interface EntitySource { id: string; - index_patterns?: string[]; - identity_fields?: string[]; - metadata_fields?: string[]; - filters?: string[]; + index_patterns: string[]; + identity_fields: string[]; + metadata_fields: string[]; + filters: string[]; timestamp_field?: string; + display_name?: string; } const newEntitySource = ({ @@ -126,7 +138,7 @@ const newEntitySource = ({ metadataFields?: string[]; filters?: string[]; timestampField?: string; -}) => ({ +}): EntitySource => ({ id: uuid(), index_patterns: indexPatterns, identity_fields: identityFields, @@ -320,6 +332,10 @@ export function EntityManagerOverviewPage() { field: 'entity.id', name: 'entity.id', }, + { + field: 'entity.display_name', + name: 'entity.display_name', + }, { field: 'entity.type', name: 'entity.type', @@ -329,16 +345,10 @@ export function EntityManagerOverviewPage() { name: 'entity.last_seen_timestamp', }, ...Array.from(new Set(entitySources.flatMap((source) => source.identity_fields))).map( - (field) => ({ - field, - name: field, - }) + (field) => ({ field, name: field }) ), ...Array.from(new Set(entitySources.flatMap((source) => source.metadata_fields))).map( - (field) => ({ - field: `metadata.${field}`, - name: `metadata.${field}`, - }) + (field) => ({ field, name: field }) ), ]} /> diff --git a/x-pack/plugins/observability_solution/infra/common/alerting/logs/log_threshold/types.ts b/x-pack/plugins/observability_solution/infra/common/alerting/logs/log_threshold/types.ts index b8410a478b6f8..2ae0e0b00a2dd 100644 --- a/x-pack/plugins/observability_solution/infra/common/alerting/logs/log_threshold/types.ts +++ b/x-pack/plugins/observability_solution/infra/common/alerting/logs/log_threshold/types.ts @@ -10,7 +10,7 @@ import * as rt from 'io-ts'; import { persistedLogViewReferenceRT } from '@kbn/logs-shared-plugin/common'; import { commonSearchSuccessResponseFieldsRT } from '../../../utils/elasticsearch_runtime_types'; -export const LOG_DOCUMENT_COUNT_RULE_TYPE_ID = 'logs.alert.document.count'; +export { LOG_THRESHOLD_ALERT_TYPE_ID as LOG_DOCUMENT_COUNT_RULE_TYPE_ID } from '@kbn/rule-data-utils'; const ThresholdTypeRT = rt.keyof({ count: null, diff --git a/x-pack/plugins/observability_solution/infra/common/alerting/metrics/types.ts b/x-pack/plugins/observability_solution/infra/common/alerting/metrics/types.ts index b5a3c084c47cb..d1adb75d51134 100644 --- a/x-pack/plugins/observability_solution/infra/common/alerting/metrics/types.ts +++ b/x-pack/plugins/observability_solution/infra/common/alerting/metrics/types.ts @@ -8,16 +8,12 @@ import { TimeUnitChar } from '@kbn/observability-plugin/common/utils/formatters/ import { InventoryItemType, SnapshotMetricType } from '@kbn/metrics-data-access-plugin/common'; import { COMPARATORS } from '@kbn/alerting-comparators'; import { LEGACY_COMPARATORS } from '@kbn/observability-plugin/common/utils/convert_legacy_outside_comparator'; +export { INFRA_RULE_TYPE_IDS } from '@kbn/rule-data-utils'; import { SnapshotCustomMetricInput } from '../../http_api'; export const METRIC_THRESHOLD_ALERT_TYPE_ID = 'metrics.alert.threshold'; export const METRIC_INVENTORY_THRESHOLD_ALERT_TYPE_ID = 'metrics.alert.inventory.threshold'; -export enum InfraRuleType { - MetricThreshold = 'metrics.alert.threshold', - InventoryThreshold = 'metrics.alert.inventory.threshold', -} - export enum Aggregators { COUNT = 'count', AVERAGE = 'avg', diff --git a/x-pack/plugins/observability_solution/infra/common/constants.ts b/x-pack/plugins/observability_solution/infra/common/constants.ts index 482406171a673..c86d39cddb3fb 100644 --- a/x-pack/plugins/observability_solution/infra/common/constants.ts +++ b/x-pack/plugins/observability_solution/infra/common/constants.ts @@ -5,14 +5,25 @@ * 2.0. */ +import { AlertConsumers, ValidFeatureId } from '@kbn/rule-data-utils'; + export const METRICS_INDEX_PATTERN = 'metrics-*,metricbeat-*'; export const LOGS_INDEX_PATTERN = 'logs-*,filebeat-*,kibana_sample_data_logs*'; export const METRICS_APP = 'metrics'; export const LOGS_APP = 'logs'; -export const METRICS_FEATURE_ID = 'infrastructure'; -export const INFRA_ALERT_FEATURE_ID = 'infrastructure'; -export const LOGS_FEATURE_ID = 'logs'; +export const METRICS_FEATURE_ID = AlertConsumers.INFRASTRUCTURE; +export const INFRA_ALERT_FEATURE_ID = AlertConsumers.INFRASTRUCTURE; +export const LOGS_FEATURE_ID = AlertConsumers.LOGS; + +export const INFRA_ALERT_CONSUMERS: ValidFeatureId[] = [ + AlertConsumers.INFRASTRUCTURE, + AlertConsumers.OBSERVABILITY, + AlertConsumers.LOGS, + AlertConsumers.SLO, + AlertConsumers.APM, + AlertConsumers.ALERTS, +]; export type InfraFeatureId = typeof METRICS_FEATURE_ID | typeof LOGS_FEATURE_ID; diff --git a/x-pack/plugins/observability_solution/infra/public/components/asset_details/add_metrics_callout/constants.ts b/x-pack/plugins/observability_solution/infra/public/components/asset_details/add_metrics_callout/constants.ts index ca56a58875220..01da12c5f59ad 100644 --- a/x-pack/plugins/observability_solution/infra/public/components/asset_details/add_metrics_callout/constants.ts +++ b/x-pack/plugins/observability_solution/infra/public/components/asset_details/add_metrics_callout/constants.ts @@ -62,7 +62,7 @@ const containerDefaultActions = ( return { actions: { primary: { - href: locator?.getRedirectUrl({ category: OnboardingFlow.Infra }), + href: locator?.getRedirectUrl({ category: OnboardingFlow.Hosts }), label: defaultPrimaryActionLabel, }, link: { diff --git a/x-pack/plugins/observability_solution/infra/public/components/asset_details/tabs/metrics/container_metrics.tsx b/x-pack/plugins/observability_solution/infra/public/components/asset_details/tabs/metrics/container_metrics.tsx index f49fa026892b1..65d19f7693740 100644 --- a/x-pack/plugins/observability_solution/infra/public/components/asset_details/tabs/metrics/container_metrics.tsx +++ b/x-pack/plugins/observability_solution/infra/public/components/asset_details/tabs/metrics/container_metrics.tsx @@ -14,6 +14,7 @@ import { MetricsTemplate } from './metrics_template'; import { DockerCharts, KubernetesContainerCharts } from '../../charts'; import { DOCKER_METRIC_TYPES, INTEGRATIONS, KUBERNETES_METRIC_TYPES } from '../../constants'; import { useIntegrationCheck } from '../../hooks/use_integration_check'; +import { AddMetricsCallout } from '../../add_metrics_callout'; export const ContainerMetrics = () => { const ref = useRef(null); @@ -29,7 +30,7 @@ export const ContainerMetrics = () => { }); if (!isDockerContainer && !isKubernetesContainer) { - return null; + return ; } return ( diff --git a/x-pack/plugins/observability_solution/infra/public/components/asset_details/tabs/overview/alerts/alerts.tsx b/x-pack/plugins/observability_solution/infra/public/components/asset_details/tabs/overview/alerts/alerts.tsx index 304e67a0debde..dc4d78baeb5a1 100644 --- a/x-pack/plugins/observability_solution/infra/public/components/asset_details/tabs/overview/alerts/alerts.tsx +++ b/x-pack/plugins/observability_solution/infra/public/components/asset_details/tabs/overview/alerts/alerts.tsx @@ -75,7 +75,7 @@ export const AlertsSummaryContent = ({ )} diff --git a/x-pack/plugins/observability_solution/infra/public/components/asset_details/tabs/overview/overview.tsx b/x-pack/plugins/observability_solution/infra/public/components/asset_details/tabs/overview/overview.tsx index e4f0eee51dbc0..9ace5606599d7 100644 --- a/x-pack/plugins/observability_solution/infra/public/components/asset_details/tabs/overview/overview.tsx +++ b/x-pack/plugins/observability_solution/infra/public/components/asset_details/tabs/overview/overview.tsx @@ -27,8 +27,6 @@ import { AddMetricsCallout } from '../../add_metrics_callout'; import { AddMetricsCalloutKey } from '../../add_metrics_callout/constants'; import { useEntitySummary } from '../../hooks/use_entity_summary'; import { isMetricsSignal } from '../../utils/get_data_stream_types'; -import { INTEGRATIONS } from '../../constants'; -import { useIntegrationCheck } from '../../hooks/use_integration_check'; export const Overview = () => { const { dateRange } = useDatePickerContext(); @@ -50,10 +48,6 @@ export const Overview = () => { `infra.dismissedAddMetricsCallout.${addMetricsCalloutId}`, false ); - const isDockerContainer = useIntegrationCheck({ dependsOn: INTEGRATIONS.docker }); - const isKubernetesContainer = useIntegrationCheck({ - dependsOn: INTEGRATIONS.kubernetesContainer, - }); const metadataSummarySection = isFullPageView ? ( @@ -74,13 +68,7 @@ export const Overview = () => { return false; } - const { type } = asset; - const baseCondition = !isMetricsSignal(dataStreams); - - const isRelevantContainer = - type === 'container' && (isDockerContainer || isKubernetesContainer); - - return baseCondition && (type === 'host' || isRelevantContainer); + return !isMetricsSignal(dataStreams); }; const showAddMetricsCallout = shouldShowCallout(); diff --git a/x-pack/plugins/observability_solution/infra/public/components/lens/lens_chart.tsx b/x-pack/plugins/observability_solution/infra/public/components/lens/lens_chart.tsx index b244ff12222d6..56d69fa9b6c7c 100644 --- a/x-pack/plugins/observability_solution/infra/public/components/lens/lens_chart.tsx +++ b/x-pack/plugins/observability_solution/infra/public/components/lens/lens_chart.tsx @@ -25,6 +25,12 @@ import { ChartLoadError } from './chart_load_error'; import { HOST_MISSING_FIELDS } from '../../common/visualizations/constants'; const MIN_HEIGHT = 300; +const DEFAULT_DISABLED_ACTIONS = [ + 'ACTION_CUSTOMIZE_PANEL', + 'ACTION_EXPORT_CSV', + 'embeddable_addToExistingCase', + 'create-ml-ad-job-action', +]; export type LensChartProps = BaseChartProps & Pick & { @@ -33,6 +39,8 @@ export type LensChartProps = BaseChartProps & description?: string; } & { lensAttributes: UseLensAttributesParams; + withDefaultActions?: boolean; + disabledActions?: string[]; }; export const LensChart = React.memo( @@ -52,6 +60,8 @@ export const LensChart = React.memo( height = MIN_HEIGHT, loading = false, lensAttributes, + withDefaultActions = true, + disabledActions = DEFAULT_DISABLED_ACTIONS, }: LensChartProps) => { const { formula, attributes, getExtraActions, error } = useLensAttributes(lensAttributes); @@ -122,6 +132,8 @@ export const LensChart = React.memo( dateRange={dateRange} disableTriggers={disableTriggers} extraActions={extraActions} + withDefaultActions={withDefaultActions} + disabledActions={disabledActions} filters={filters} hidePanelTitles={hidePanelTitles} loading={isLoading} diff --git a/x-pack/plugins/observability_solution/infra/public/components/lens/lens_wrapper.tsx b/x-pack/plugins/observability_solution/infra/public/components/lens/lens_wrapper.tsx index 01d409fc9a1ac..01ce60b593462 100644 --- a/x-pack/plugins/observability_solution/infra/public/components/lens/lens_wrapper.tsx +++ b/x-pack/plugins/observability_solution/infra/public/components/lens/lens_wrapper.tsx @@ -93,7 +93,6 @@ export const LensWrapper = ({

        { }; describe('useAlertsCount', () => { - const featureIds: ValidFeatureId[] = ['infrastructure']; + const ruleTypeIds = ['metrics.alert.inventory.threshold']; + const consumers = ['foo']; beforeAll(() => { mockUseKibana(); @@ -66,7 +67,7 @@ describe('useAlertsCount', () => { it('should return the mocked data from API', async () => { mockedPostAPI.mockResolvedValue(mockedAlertsCountResponse); - const { result } = renderHook(() => useAlertsCount({ featureIds })); + const { result } = renderHook(() => useAlertsCount({ ruleTypeIds })); expect(result.current.loading).toBe(true); expect(result.current.alertsCount).toEqual(undefined); @@ -90,7 +91,8 @@ describe('useAlertsCount', () => { renderHook(() => useAlertsCount({ - featureIds, + ruleTypeIds, + consumers, query, }) ); @@ -101,7 +103,8 @@ describe('useAlertsCount', () => { terms: { field: ALERT_STATUS }, }, }, - feature_ids: featureIds, + rule_type_ids: ruleTypeIds, + consumers, query, size: 0, }); @@ -118,7 +121,7 @@ describe('useAlertsCount', () => { const error = new Error('Fetch Alerts Count Failed'); mockedPostAPI.mockRejectedValueOnce(error); - const { result } = renderHook(() => useAlertsCount({ featureIds })); + const { result } = renderHook(() => useAlertsCount({ ruleTypeIds })); await waitFor(() => expect(result.current.error?.message).toMatch(error.message)); }); diff --git a/x-pack/plugins/observability_solution/infra/public/hooks/use_alerts_count.ts b/x-pack/plugins/observability_solution/infra/public/hooks/use_alerts_count.ts index 5c602d09b7d23..aab542d597f92 100644 --- a/x-pack/plugins/observability_solution/infra/public/hooks/use_alerts_count.ts +++ b/x-pack/plugins/observability_solution/infra/public/hooks/use_alerts_count.ts @@ -12,17 +12,19 @@ import { BASE_RAC_ALERTS_API_PATH } from '@kbn/rule-registry-plugin/common/const import { estypes } from '@elastic/elasticsearch'; import { useKibana } from '@kbn/kibana-react-plugin/public'; import type { HttpSetup } from '@kbn/core/public'; -import { ALERT_STATUS_ACTIVE, ALERT_STATUS_RECOVERED, ValidFeatureId } from '@kbn/rule-data-utils'; +import { ALERT_STATUS_ACTIVE, ALERT_STATUS_RECOVERED } from '@kbn/rule-data-utils'; import { InfraClientCoreStart } from '../types'; interface UseAlertsCountProps { - featureIds: ValidFeatureId[]; + ruleTypeIds: string[]; + consumers?: string[]; query?: estypes.QueryDslQueryContainer; } interface FetchAlertsCountParams { - featureIds: ValidFeatureId[]; + ruleTypeIds: string[]; + consumers?: string[]; query?: estypes.QueryDslQueryContainer; http: HttpSetup; signal: AbortSignal; @@ -35,7 +37,7 @@ export interface AlertsCount { const ALERT_STATUS = 'kibana.alert.status'; -export function useAlertsCount({ featureIds, query }: UseAlertsCountProps) { +export function useAlertsCount({ ruleTypeIds, consumers, query }: UseAlertsCountProps) { const { http } = useKibana().services; const abortCtrlRef = useRef(new AbortController()); @@ -45,13 +47,14 @@ export function useAlertsCount({ featureIds, query }: UseAlertsCountProps) { abortCtrlRef.current.abort(); abortCtrlRef.current = new AbortController(); return fetchAlertsCount({ - featureIds, + ruleTypeIds, + consumers, query, http, signal: abortCtrlRef.current.signal, }); }, - [featureIds, query, http], + [ruleTypeIds, query, http], { loading: true } ); @@ -70,7 +73,8 @@ export function useAlertsCount({ featureIds, query }: UseAlertsCountProps) { } async function fetchAlertsCount({ - featureIds, + ruleTypeIds, + consumers, http, query, signal, @@ -84,7 +88,8 @@ async function fetchAlertsCount({ terms: { field: ALERT_STATUS }, }, }, - feature_ids: featureIds, + rule_type_ids: ruleTypeIds, + consumers, query, size: 0, }), diff --git a/x-pack/plugins/observability_solution/infra/public/pages/logs/settings/indices_configuration_panel.tsx b/x-pack/plugins/observability_solution/infra/public/pages/logs/settings/indices_configuration_panel.tsx index 8f42b4cf1bc6a..0e16a404cbd54 100644 --- a/x-pack/plugins/observability_solution/infra/public/pages/logs/settings/indices_configuration_panel.tsx +++ b/x-pack/plugins/observability_solution/infra/public/pages/logs/settings/indices_configuration_panel.tsx @@ -19,7 +19,7 @@ import { import { EuiCallOut } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { loadRuleAggregations } from '@kbn/triggers-actions-ui-plugin/public'; -import { LOG_THRESHOLD_ALERT_TYPE_ID } from '@kbn/rule-data-utils'; +import { AlertConsumers, LOG_THRESHOLD_ALERT_TYPE_ID } from '@kbn/rule-data-utils'; import { rulesLocatorID, RulesParams } from '@kbn/observability-plugin/public'; import { EuiLink } from '@elastic/eui'; @@ -93,7 +93,8 @@ export const IndicesConfigurationPanel = React.memo<{ if (http) { const { ruleExecutionStatus } = await loadRuleAggregations({ http, - typesFilter: [LOG_THRESHOLD_ALERT_TYPE_ID], + ruleTypeIds: [LOG_THRESHOLD_ALERT_TYPE_ID], + consumers: [AlertConsumers.LOGS, AlertConsumers.ALERTS, AlertConsumers.OBSERVABILITY], }); const numberOfRules = Object.values(ruleExecutionStatus).reduce( (acc, value) => acc + value, diff --git a/x-pack/plugins/observability_solution/infra/public/pages/metrics/hosts/components/tabs/alerts/alerts_tab_content.tsx b/x-pack/plugins/observability_solution/infra/public/pages/metrics/hosts/components/tabs/alerts/alerts_tab_content.tsx index a3926b95383d9..7b0ec7ed2d2f1 100644 --- a/x-pack/plugins/observability_solution/infra/public/pages/metrics/hosts/components/tabs/alerts/alerts_tab_content.tsx +++ b/x-pack/plugins/observability_solution/infra/public/pages/metrics/hosts/components/tabs/alerts/alerts_tab_content.tsx @@ -6,11 +6,16 @@ */ import React from 'react'; import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; -import { AlertConsumers, ALERT_RULE_PRODUCER } from '@kbn/rule-data-utils'; +import { + AlertConsumers, + INFRA_RULE_TYPE_IDS, + OBSERVABILITY_RULE_TYPE_IDS, +} from '@kbn/rule-data-utils'; import { BrushEndListener, type XYBrushEvent } from '@elastic/charts'; import { useSummaryTimeRange } from '@kbn/observability-plugin/public'; import { useBoolean } from '@kbn/react-hooks'; import type { TimeRange } from '@kbn/es-query'; +import { INFRA_ALERT_CONSUMERS } from '../../../../../../../common/constants'; import { useKibanaContextForPlugin } from '../../../../../../hooks/use_kibana'; import { HeightRetainer } from '../../../../../../components/height_retainer'; import { useUnifiedSearchContext } from '../../../hooks/use_unified_search'; @@ -20,18 +25,18 @@ import { AlertsEsQuery } from '../../../../../../utils/filters/create_alerts_es_ import { ALERTS_PER_PAGE, ALERTS_TABLE_ID, - infraAlertFeatureIds, } from '../../../../../../components/shared/alerts/constants'; import AlertsStatusFilter from '../../../../../../components/shared/alerts/alerts_status_filter'; import { CreateAlertRuleButton } from '../../../../../../components/shared/alerts/links/create_alert_rule_button'; import { LinkToAlertsPage } from '../../../../../../components/shared/alerts/links/link_to_alerts_page'; -import { INFRA_ALERT_FEATURE_ID } from '../../../../../../../common/constants'; import { AlertFlyout } from '../../../../../../alerting/inventory/components/alert_flyout'; import { usePluginConfig } from '../../../../../../containers/plugin_config_context'; +import { useHostsViewContext } from '../../../hooks/use_hosts_view'; export const AlertsTabContent = () => { const { services } = useKibanaContextForPlugin(); const { featureFlags } = usePluginConfig(); + const { hostNodes } = useHostsViewContext(); const { alertStatus, setAlertStatus, alertsEsQueryByStatus } = useAlertsQuery(); const [isAlertFlyoutVisible, { toggle: toggleAlertFlyout }] = useBoolean(false); @@ -43,6 +48,11 @@ export const AlertsTabContent = () => { const { alertsTableConfigurationRegistry, getAlertsStateTable: AlertsStateTable } = triggersActionsUi; + const hostsWithAlertsKuery = hostNodes + .filter((host) => host.alertsCount) + .map((host) => `"${host.name}"`) + .join(' OR '); + return ( @@ -63,7 +73,7 @@ export const AlertsTabContent = () => { @@ -80,7 +90,8 @@ export const AlertsTabContent = () => { { const { alertsEsQuery } = useAlertsQuery(); const { alertsCount, loading, error } = useAlertsCount({ - featureIds: infraAlertFeatureIds, + ruleTypeIds: INFRA_RULE_TYPE_IDS, + consumers: INFRA_ALERT_CONSUMERS, query: alertsEsQuery, }); diff --git a/x-pack/plugins/observability_solution/infra/public/pages/metrics/settings/source_configuration_settings.tsx b/x-pack/plugins/observability_solution/infra/public/pages/metrics/settings/source_configuration_settings.tsx index 8deaa805ba9b4..328ef4680680e 100644 --- a/x-pack/plugins/observability_solution/infra/public/pages/metrics/settings/source_configuration_settings.tsx +++ b/x-pack/plugins/observability_solution/infra/public/pages/metrics/settings/source_configuration_settings.tsx @@ -20,6 +20,7 @@ import { import { loadRuleAggregations } from '@kbn/triggers-actions-ui-plugin/public'; import { HttpSetup } from '@kbn/core-http-browser'; import { + AlertConsumers, METRIC_INVENTORY_THRESHOLD_ALERT_TYPE_ID, METRIC_THRESHOLD_ALERT_TYPE_ID, } from '@kbn/rule-data-utils'; @@ -56,7 +57,12 @@ export const SourceConfigurationSettings = ({ if (http) { const { ruleExecutionStatus } = await loadRuleAggregations({ http, - typesFilter: [METRIC_INVENTORY_THRESHOLD_ALERT_TYPE_ID, METRIC_THRESHOLD_ALERT_TYPE_ID], + ruleTypeIds: [METRIC_INVENTORY_THRESHOLD_ALERT_TYPE_ID, METRIC_THRESHOLD_ALERT_TYPE_ID], + consumers: [ + AlertConsumers.INFRASTRUCTURE, + AlertConsumers.ALERTS, + AlertConsumers.OBSERVABILITY, + ], }); const numberOfRules = Object.values(ruleExecutionStatus).reduce( (acc, value) => acc + value, diff --git a/x-pack/plugins/observability_solution/infra/server/features.ts b/x-pack/plugins/observability_solution/infra/server/features.ts index b2f83967920e1..77fb8d317fefd 100644 --- a/x-pack/plugins/observability_solution/infra/server/features.ts +++ b/x-pack/plugins/observability_solution/infra/server/features.ts @@ -14,6 +14,7 @@ import { } from '@kbn/rule-data-utils'; import { ES_QUERY_ID } from '@kbn/rule-data-utils'; import { metricsDataSourceSavedObjectName } from '@kbn/metrics-data-access-plugin/server'; +import { ALERTING_FEATURE_ID } from '@kbn/alerting-plugin/common'; import { KibanaFeatureScope } from '@kbn/features-plugin/common'; import { LOG_DOCUMENT_COUNT_RULE_TYPE_ID } from '../common/alerting/logs/log_threshold/types'; import { @@ -31,6 +32,11 @@ const metricRuleTypes = [ ML_ANOMALY_DETECTION_RULE_TYPE_ID, ]; +const metricAlertingFeatures = metricRuleTypes.map((ruleTypeId) => ({ + ruleTypeId, + consumers: [METRICS_FEATURE_ID, ALERTING_FEATURE_ID], +})); + export const METRICS_FEATURE = { id: METRICS_FEATURE_ID, name: i18n.translate('xpack.infra.featureRegistry.linkInfrastructureTitle', { @@ -44,7 +50,7 @@ export const METRICS_FEATURE = { management: { insightsAndAlerting: ['triggersActions'], }, - alerting: metricRuleTypes, + alerting: metricAlertingFeatures, privileges: { all: { app: ['infra', 'metrics', 'kibana'], @@ -56,10 +62,10 @@ export const METRICS_FEATURE = { }, alerting: { rule: { - all: metricRuleTypes, + all: metricAlertingFeatures, }, alert: { - all: metricRuleTypes, + all: metricAlertingFeatures, }, }, management: { @@ -77,10 +83,10 @@ export const METRICS_FEATURE = { }, alerting: { rule: { - read: metricRuleTypes, + read: metricAlertingFeatures, }, alert: { - read: metricRuleTypes, + read: metricAlertingFeatures, }, }, management: { @@ -98,6 +104,11 @@ const logsRuleTypes = [ ML_ANOMALY_DETECTION_RULE_TYPE_ID, ]; +const logsAlertingFeatures = logsRuleTypes.map((ruleTypeId) => ({ + ruleTypeId, + consumers: [LOGS_FEATURE_ID, ALERTING_FEATURE_ID], +})); + export const LOGS_FEATURE = { id: LOGS_FEATURE_ID, name: i18n.translate('xpack.infra.featureRegistry.linkLogsTitle', { @@ -111,7 +122,7 @@ export const LOGS_FEATURE = { management: { insightsAndAlerting: ['triggersActions'], }, - alerting: logsRuleTypes, + alerting: logsAlertingFeatures, privileges: { all: { app: ['infra', 'logs', 'kibana', 'observability-logs-explorer'], @@ -123,10 +134,10 @@ export const LOGS_FEATURE = { }, alerting: { rule: { - all: logsRuleTypes, + all: logsAlertingFeatures, }, alert: { - all: logsRuleTypes, + all: logsAlertingFeatures, }, }, management: { @@ -140,10 +151,10 @@ export const LOGS_FEATURE = { api: ['infra', 'rac'], alerting: { rule: { - read: logsRuleTypes, + read: logsAlertingFeatures, }, alert: { - read: logsRuleTypes, + read: logsAlertingFeatures, }, }, management: { diff --git a/x-pack/plugins/observability_solution/infra/server/lib/adapters/framework/adapter_types.ts b/x-pack/plugins/observability_solution/infra/server/lib/adapters/framework/adapter_types.ts index b8dd11a17fb0b..3ee4f9632b359 100644 --- a/x-pack/plugins/observability_solution/infra/server/lib/adapters/framework/adapter_types.ts +++ b/x-pack/plugins/observability_solution/infra/server/lib/adapters/framework/adapter_types.ts @@ -20,7 +20,7 @@ import { HomeServerPluginSetup } from '@kbn/home-plugin/server'; import { VisTypeTimeseriesSetup } from '@kbn/vis-type-timeseries-plugin/server'; import { FeaturesPluginSetup } from '@kbn/features-plugin/server'; import { SpacesPluginSetup } from '@kbn/spaces-plugin/server'; -import { PluginSetupContract as AlertingPluginContract } from '@kbn/alerting-plugin/server'; +import type { AlertingServerSetup } from '@kbn/alerting-plugin/server'; import { MlPluginSetup } from '@kbn/ml-plugin/server'; import { RuleRegistryPluginSetupContract, @@ -46,7 +46,7 @@ import type { } from '@kbn/entityManager-plugin/server'; export interface InfraServerPluginSetupDeps { - alerting: AlertingPluginContract; + alerting: AlertingServerSetup; data: DataPluginSetup; home: HomeServerPluginSetup; features: FeaturesPluginSetup; diff --git a/x-pack/plugins/observability_solution/infra/server/lib/alerting/inventory_metric_threshold/register_inventory_metric_threshold_rule_type.ts b/x-pack/plugins/observability_solution/infra/server/lib/alerting/inventory_metric_threshold/register_inventory_metric_threshold_rule_type.ts index 7b69d76ba0ce9..f85738248a9c0 100644 --- a/x-pack/plugins/observability_solution/infra/server/lib/alerting/inventory_metric_threshold/register_inventory_metric_threshold_rule_type.ts +++ b/x-pack/plugins/observability_solution/infra/server/lib/alerting/inventory_metric_threshold/register_inventory_metric_threshold_rule_type.ts @@ -8,7 +8,7 @@ import { schema, Type } from '@kbn/config-schema'; import { i18n } from '@kbn/i18n'; import { DEFAULT_APP_CATEGORIES } from '@kbn/core/server'; -import { GetViewInAppRelativeUrlFnOpts, PluginSetupContract } from '@kbn/alerting-plugin/server'; +import { GetViewInAppRelativeUrlFnOpts, AlertingServerSetup } from '@kbn/alerting-plugin/server'; import { observabilityPaths } from '@kbn/observability-plugin/common'; import { TimeUnitChar } from '@kbn/observability-plugin/common/utils/formatters/duration'; import { @@ -81,7 +81,7 @@ const groupActionVariableDescription = i18n.translate( ); export function registerInventoryThresholdRuleType( - alertingPlugin: PluginSetupContract, + alertingPlugin: AlertingServerSetup, libs: InfraBackendLibs, { featureFlags }: InfraConfig, locators: InfraLocators diff --git a/x-pack/plugins/observability_solution/infra/server/lib/alerting/log_threshold/register_log_threshold_rule_type.ts b/x-pack/plugins/observability_solution/infra/server/lib/alerting/log_threshold/register_log_threshold_rule_type.ts index decac47dbb5f9..d4eb9050499cf 100644 --- a/x-pack/plugins/observability_solution/infra/server/lib/alerting/log_threshold/register_log_threshold_rule_type.ts +++ b/x-pack/plugins/observability_solution/infra/server/lib/alerting/log_threshold/register_log_threshold_rule_type.ts @@ -7,7 +7,10 @@ import { i18n } from '@kbn/i18n'; import { DEFAULT_APP_CATEGORIES } from '@kbn/core/server'; -import { GetViewInAppRelativeUrlFnOpts, PluginSetupContract } from '@kbn/alerting-plugin/server'; +import type { + GetViewInAppRelativeUrlFnOpts, + AlertingServerSetup, +} from '@kbn/alerting-plugin/server'; import { observabilityPaths } from '@kbn/observability-plugin/common'; import { decodeOrThrow } from '@kbn/io-ts-utils'; import type { InfraConfig } from '../../../../common/plugin_config_types'; @@ -103,7 +106,7 @@ const viewInAppUrlActionVariableDescription = i18n.translate( ); export function registerLogThresholdRuleType( - alertingPlugin: PluginSetupContract, + alertingPlugin: AlertingServerSetup, libs: InfraBackendLibs, { featureFlags }: InfraConfig ) { diff --git a/x-pack/plugins/observability_solution/infra/server/lib/alerting/metric_threshold/register_metric_threshold_rule_type.ts b/x-pack/plugins/observability_solution/infra/server/lib/alerting/metric_threshold/register_metric_threshold_rule_type.ts index 6369465773cf7..3cc272a02c7fe 100644 --- a/x-pack/plugins/observability_solution/infra/server/lib/alerting/metric_threshold/register_metric_threshold_rule_type.ts +++ b/x-pack/plugins/observability_solution/infra/server/lib/alerting/metric_threshold/register_metric_threshold_rule_type.ts @@ -8,7 +8,10 @@ import { DEFAULT_APP_CATEGORIES } from '@kbn/core/server'; import { schema } from '@kbn/config-schema'; import { i18n } from '@kbn/i18n'; -import { GetViewInAppRelativeUrlFnOpts, PluginSetupContract } from '@kbn/alerting-plugin/server'; +import type { + GetViewInAppRelativeUrlFnOpts, + AlertingServerSetup, +} from '@kbn/alerting-plugin/server'; import { observabilityPaths } from '@kbn/observability-plugin/common'; import { COMPARATORS } from '@kbn/alerting-comparators'; import { LEGACY_COMPARATORS } from '@kbn/observability-plugin/common/utils/convert_legacy_outside_comparator'; @@ -46,7 +49,7 @@ import { MetricsRulesTypeAlertDefinition } from '../register_rule_types'; import { O11Y_AAD_FIELDS } from '../../../../common/constants'; export function registerMetricThresholdRuleType( - alertingPlugin: PluginSetupContract, + alertingPlugin: AlertingServerSetup, libs: InfraBackendLibs, { featureFlags }: InfraConfig, locators: InfraLocators diff --git a/x-pack/plugins/observability_solution/infra/server/lib/alerting/register_rule_types.ts b/x-pack/plugins/observability_solution/infra/server/lib/alerting/register_rule_types.ts index 125c3135a235d..6d06c2c98607e 100644 --- a/x-pack/plugins/observability_solution/infra/server/lib/alerting/register_rule_types.ts +++ b/x-pack/plugins/observability_solution/infra/server/lib/alerting/register_rule_types.ts @@ -6,7 +6,7 @@ */ import { legacyExperimentalFieldMap } from '@kbn/alerts-as-data-utils'; -import { type IRuleTypeAlerts, PluginSetupContract } from '@kbn/alerting-plugin/server'; +import { type IRuleTypeAlerts, AlertingServerSetup } from '@kbn/alerting-plugin/server'; import { registerMetricThresholdRuleType } from './metric_threshold/register_metric_threshold_rule_type'; import { registerInventoryThresholdRuleType } from './inventory_metric_threshold/register_inventory_metric_threshold_rule_type'; import { registerLogThresholdRuleType } from './log_threshold/register_log_threshold_rule_type'; @@ -36,7 +36,7 @@ export const MetricsRulesTypeAlertDefinition: IRuleTypeAlerts { + const hasPrivileges = async () => { + const apmDataAccessStart = await libs.plugins.apmDataAccess.start(); + return apmDataAccessStart.hasPrivileges({ request }); + }; + const getServices = async () => { const apmDataAccess = libs.plugins.apmDataAccess.setup; const coreContext = await context.core; - const { uiSettings, elasticsearch } = coreContext; + const { savedObjects, uiSettings, elasticsearch } = coreContext; + const savedObjectsClient = savedObjects.client; const esClient = elasticsearch.client.asCurrentUser; const uiSettingsClient = uiSettings.client; const [apmIndices, includeFrozen] = await Promise.all([ - apmDataAccess.getApmIndices(), + apmDataAccess.getApmIndices(savedObjectsClient), uiSettingsClient.get(UI_SETTINGS.SEARCH_INCLUDE_FROZEN), ]); @@ -80,5 +86,5 @@ export const getApmDataAccessClient = ({ }; }; - return { getServices }; + return { hasPrivileges, getServices }; }; diff --git a/x-pack/plugins/observability_solution/infra/server/lib/helpers/get_infra_alerts_client.ts b/x-pack/plugins/observability_solution/infra/server/lib/helpers/get_infra_alerts_client.ts index 58dfdde223ebd..99464efd02567 100644 --- a/x-pack/plugins/observability_solution/infra/server/lib/helpers/get_infra_alerts_client.ts +++ b/x-pack/plugins/observability_solution/infra/server/lib/helpers/get_infra_alerts_client.ts @@ -8,6 +8,7 @@ import { isEmpty } from 'lodash'; import type { ESSearchRequest, InferSearchResponseOf } from '@kbn/es-types'; import { ParsedTechnicalFields } from '@kbn/rule-registry-plugin/common'; import type { KibanaRequest } from '@kbn/core/server'; +import { OBSERVABILITY_RULE_TYPE_IDS } from '@kbn/rule-data-utils'; import type { InfraBackendLibs } from '../infra_types'; type RequiredParams = ESSearchRequest & { @@ -26,7 +27,9 @@ export async function getInfraAlertsClient({ }) { const [, { ruleRegistry }] = await libs.getStartServices(); const alertsClient = await ruleRegistry.getRacClientWithRequest(request); - const infraAlertsIndices = await alertsClient.getAuthorizedAlertsIndices(['infrastructure']); + const infraAlertsIndices = await alertsClient.getAuthorizedAlertsIndices( + OBSERVABILITY_RULE_TYPE_IDS + ); if (!infraAlertsIndices || isEmpty(infraAlertsIndices)) { throw Error('No alert indices exist for "infrastructure"'); diff --git a/x-pack/plugins/observability_solution/infra/server/routes/infra/index.ts b/x-pack/plugins/observability_solution/infra/server/routes/infra/index.ts index 3f91a034c8103..1b720eeb31869 100644 --- a/x-pack/plugins/observability_solution/infra/server/routes/infra/index.ts +++ b/x-pack/plugins/observability_solution/infra/server/routes/infra/index.ts @@ -41,11 +41,12 @@ export const initInfraAssetRoutes = (libs: InfraBackendLibs) => { try { const apmDataAccessClient = getApmDataAccessClient({ request, libs, context }); + const hasApmPrivileges = await apmDataAccessClient.hasPrivileges(); const [infraMetricsClient, alertsClient, apmDataAccessServices] = await Promise.all([ getInfraMetricsClient({ request, libs, context }), getInfraAlertsClient({ libs, request }), - apmDataAccessClient.getServices(), + hasApmPrivileges ? apmDataAccessClient.getServices() : undefined, ]); const hosts = await getHosts({ @@ -96,10 +97,11 @@ export const initInfraAssetRoutes = (libs: InfraBackendLibs) => { try { const apmDataAccessClient = getApmDataAccessClient({ request, libs, context }); + const hasApmPrivileges = await apmDataAccessClient.hasPrivileges(); const [infraMetricsClient, apmDataAccessServices] = await Promise.all([ getInfraMetricsClient({ request, libs, context }), - apmDataAccessClient.getServices(), + hasApmPrivileges ? apmDataAccessClient.getServices() : undefined, ]); const count = await getHostsCount({ diff --git a/x-pack/plugins/observability_solution/infra/server/routes/infra/lib/helpers/query.ts b/x-pack/plugins/observability_solution/infra/server/routes/infra/lib/helpers/query.ts index 52da69cd7c008..570c1499f3b74 100644 --- a/x-pack/plugins/observability_solution/infra/server/routes/infra/lib/helpers/query.ts +++ b/x-pack/plugins/observability_solution/infra/server/routes/infra/lib/helpers/query.ts @@ -9,7 +9,6 @@ import { findInventoryModel } from '@kbn/metrics-data-access-plugin/common'; import { termQuery } from '@kbn/observability-plugin/server'; import { ApmDocumentType, type TimeRangeMetadata } from '@kbn/apm-data-access-plugin/common'; import { estypes } from '@elastic/elasticsearch'; -import { castArray } from 'lodash'; import type { ApmDataAccessServicesWrapper } from '../../../../lib/helpers/get_apm_data_access_client'; import { EVENT_MODULE, @@ -18,16 +17,12 @@ import { } from '../../../../../common/constants'; import type { InfraAssetMetricType } from '../../../../../common/http_api/infra'; -export const getFilterByIntegration = ( - integration: typeof SYSTEM_INTEGRATION, - extraFilter: estypes.QueryDslQueryContainer[] = [] -) => { +export const getFilterByIntegration = (integration: typeof SYSTEM_INTEGRATION) => { return { bool: { should: [ ...termQuery(EVENT_MODULE, integration), ...termQuery(METRICSET_MODULE, integration), - ...extraFilter, ], minimum_should_match: 1, }, @@ -68,6 +63,7 @@ export const getDocumentsFilter = async ({ from: number; to: number; }) => { + const filters: estypes.QueryDslQueryContainer[] = [getFilterByIntegration('system')]; const apmDocumentsFilter = apmDataAccessServices && apmDocumentSources ? await getApmDocumentsFilter({ @@ -78,9 +74,9 @@ export const getDocumentsFilter = async ({ }) : undefined; - const filters: estypes.QueryDslQueryContainer[] = [ - getFilterByIntegration('system', apmDocumentsFilter && castArray(apmDocumentsFilter)), - ]; + if (apmDocumentsFilter) { + filters.push(apmDocumentsFilter); + } return filters; }; diff --git a/x-pack/plugins/observability_solution/infra/server/routes/infra/lib/host/get_hosts.ts b/x-pack/plugins/observability_solution/infra/server/routes/infra/lib/host/get_hosts.ts index 63fef5d438b00..bb5bd51cfe1f9 100644 --- a/x-pack/plugins/observability_solution/infra/server/routes/infra/lib/host/get_hosts.ts +++ b/x-pack/plugins/observability_solution/infra/server/routes/infra/lib/host/get_hosts.ts @@ -49,7 +49,6 @@ export const getHosts = async ({ const [hostMetricsResponse, alertsCountResponse] = await Promise.all([ getAllHosts({ infraMetricsClient, - apmDataAccessServices, apmDocumentSources, from, to, diff --git a/x-pack/plugins/observability_solution/infra/server/routes/infra/lib/host/get_hosts_alerts_count.ts b/x-pack/plugins/observability_solution/infra/server/routes/infra/lib/host/get_hosts_alerts_count.ts index c3d8f0f674d55..dbb1a3c2ceb69 100644 --- a/x-pack/plugins/observability_solution/infra/server/routes/infra/lib/host/get_hosts_alerts_count.ts +++ b/x-pack/plugins/observability_solution/infra/server/routes/infra/lib/host/get_hosts_alerts_count.ts @@ -6,14 +6,13 @@ */ import { termQuery, termsQuery } from '@kbn/observability-plugin/server'; -import { observabilityFeatureId } from '@kbn/observability-shared-plugin/common'; import { ALERT_RULE_PRODUCER, ALERT_STATUS, ALERT_STATUS_ACTIVE, ALERT_UUID, } from '@kbn/rule-data-utils'; -import { HOST_NAME_FIELD, INFRA_ALERT_FEATURE_ID } from '../../../../../common/constants'; +import { HOST_NAME_FIELD, INFRA_ALERT_CONSUMERS } from '../../../../../common/constants'; import { GetHostParameters } from '../types'; export async function getHostsAlertsCount({ @@ -41,7 +40,7 @@ export async function getHostsAlertsCount({ query: { bool: { filter: [ - ...termsQuery(ALERT_RULE_PRODUCER, INFRA_ALERT_FEATURE_ID, observabilityFeatureId), + ...termsQuery(ALERT_RULE_PRODUCER, ...INFRA_ALERT_CONSUMERS), ...termQuery(ALERT_STATUS, ALERT_STATUS_ACTIVE), ...termsQuery(HOST_NAME_FIELD, ...hostNames), ...rangeQuery, diff --git a/x-pack/plugins/observability_solution/infra/server/routes/infra/lib/host/get_hosts_count.ts b/x-pack/plugins/observability_solution/infra/server/routes/infra/lib/host/get_hosts_count.ts index e36811ea5b87a..154fd8796520d 100644 --- a/x-pack/plugins/observability_solution/infra/server/routes/infra/lib/host/get_hosts_count.ts +++ b/x-pack/plugins/observability_solution/infra/server/routes/infra/lib/host/get_hosts_count.ts @@ -25,14 +25,8 @@ export async function getHostsCount({ }) { assertQueryStructure(query); - const apmDocumentSources = await apmDataAccessServices?.getDocumentSources({ - start: from, - end: to, - }); - const documentsFilter = await getDocumentsFilter({ apmDataAccessServices, - apmDocumentSources, from, to, }); @@ -45,7 +39,7 @@ export async function getHostsCount({ query: { bool: { filter: [query, ...rangeQuery(from, to)], - must: [...documentsFilter], + should: [...documentsFilter], }, }, aggs: { diff --git a/x-pack/plugins/observability_solution/infra/server/routes/infra/lib/types.ts b/x-pack/plugins/observability_solution/infra/server/routes/infra/lib/types.ts index 8f50d9eb89f13..87679f24271d6 100644 --- a/x-pack/plugins/observability_solution/infra/server/routes/infra/lib/types.ts +++ b/x-pack/plugins/observability_solution/infra/server/routes/infra/lib/types.ts @@ -13,5 +13,5 @@ import { InfraMetricsClient } from '../../../lib/helpers/get_infra_metrics_clien export interface GetHostParameters extends GetInfraMetricsRequestBodyPayload { infraMetricsClient: InfraMetricsClient; alertsClient: InfraAlertsClient; - apmDataAccessServices: ApmDataAccessServicesWrapper; + apmDataAccessServices?: ApmDataAccessServicesWrapper; } diff --git a/x-pack/plugins/observability_solution/infra/server/routes/services/index.ts b/x-pack/plugins/observability_solution/infra/server/routes/services/index.ts index bc6ce91e830ad..9673b31788487 100644 --- a/x-pack/plugins/observability_solution/infra/server/routes/services/index.ts +++ b/x-pack/plugins/observability_solution/infra/server/routes/services/index.ts @@ -36,6 +36,16 @@ export const initServicesRoute = (libs: InfraBackendLibs) => { const { from, to, size = 10, validatedFilters } = request.query; const apmDataAccessClient = getApmDataAccessClient({ request, libs, context }); + const hasApmPrivileges = await apmDataAccessClient.hasPrivileges(); + + if (!hasApmPrivileges) { + return response.customError({ + statusCode: 403, + body: { + message: 'APM data access service is not available', + }, + }); + } const apmDataAccessServices = await apmDataAccessClient.getServices(); diff --git a/x-pack/plugins/observability_solution/infra/server/services/rules/types.ts b/x-pack/plugins/observability_solution/infra/server/services/rules/types.ts index 68ae0bd95b410..ee2d5967b081b 100644 --- a/x-pack/plugins/observability_solution/infra/server/services/rules/types.ts +++ b/x-pack/plugins/observability_solution/infra/server/services/rules/types.ts @@ -5,10 +5,10 @@ * 2.0. */ -import { PluginSetupContract as AlertingPluginSetup } from '@kbn/alerting-plugin/server'; +import type { AlertingServerSetup } from '@kbn/alerting-plugin/server'; import { IRuleDataClient, RuleRegistryPluginSetupContract } from '@kbn/rule-registry-plugin/server'; export interface RulesServiceSetupDeps { - alerting: AlertingPluginSetup; + alerting: AlertingServerSetup; ruleRegistry: RuleRegistryPluginSetupContract; } diff --git a/x-pack/plugins/observability_solution/inventory/common/entities.ts b/x-pack/plugins/observability_solution/inventory/common/entities.ts index 65fd8a4ffbd7a..b006fa0c7f6d8 100644 --- a/x-pack/plugins/observability_solution/inventory/common/entities.ts +++ b/x-pack/plugins/observability_solution/inventory/common/entities.ts @@ -5,8 +5,6 @@ * 2.0. */ import { ENTITY_LATEST, entitiesAliasPattern, type EntityMetadata } from '@kbn/entities-schema'; -import { decode, encode } from '@kbn/rison'; -import { isRight } from 'fp-ts/lib/Either'; import * as t from 'io-ts'; export const entityColumnIdsRt = t.union([ @@ -19,49 +17,6 @@ export const entityColumnIdsRt = t.union([ export type EntityColumnIds = t.TypeOf; -export const entityViewRt = t.union([t.literal('unified'), t.literal('grouped')]); - -const paginationRt = t.record(t.string, t.number); -export const entityPaginationRt = new t.Type | undefined, string, unknown>( - 'entityPaginationRt', - paginationRt.is, - (input, context) => { - switch (typeof input) { - case 'string': { - try { - const decoded = decode(input); - const validation = paginationRt.decode(decoded); - if (isRight(validation)) { - return t.success(validation.right); - } - - return t.failure(input, context); - } catch (e) { - return t.failure(input, context); - } - } - - case 'undefined': - return t.success(input); - - default: { - const validation = paginationRt.decode(input); - - if (isRight(validation)) { - return t.success(validation.right); - } - - return t.failure(input, context); - } - } - }, - (o) => encode(o) -); - -export type EntityView = t.TypeOf; - -export type EntityPagination = t.TypeOf; - export const defaultEntitySortField: EntityColumnIds = 'alertsCount'; export const MAX_NUMBER_OF_ENTITIES = 500; diff --git a/x-pack/plugins/observability_solution/inventory/common/rt_types.ts b/x-pack/plugins/observability_solution/inventory/common/rt_types.ts new file mode 100644 index 0000000000000..17496d672e610 --- /dev/null +++ b/x-pack/plugins/observability_solution/inventory/common/rt_types.ts @@ -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 { decode, encode } from '@kbn/rison'; +import { isRight } from 'fp-ts/lib/Either'; +import * as t from 'io-ts'; + +const validate = (validationRt: t.Any) => (input: unknown, context: t.Context) => { + switch (typeof input) { + case 'string': { + try { + const decoded = decode(input); + const validation = validationRt.decode(decoded); + if (isRight(validation)) { + return t.success(validation.right); + } + + return t.failure(input, context); + } catch (e) { + return t.failure(input, context); + } + } + + case 'undefined': + return t.success(input); + + default: { + const validation = validationRt.decode(input); + + if (isRight(validation)) { + return t.success(validation.right); + } + + return t.failure(input, context); + } + } +}; + +const entityTypeCheckOptions = t.union([t.literal('on'), t.literal('off'), t.literal('mixed')]); +export type EntityTypeCheckOptions = t.TypeOf; + +const entityTypeRt = t.record(t.string, entityTypeCheckOptions); +export type EntityType = t.TypeOf; +export const entityTypesRt = new t.Type< + Record | undefined, + string, + unknown +>('entityTypesRt', entityTypeRt.is, validate(entityTypeRt), (o) => encode(o)); + +const paginationRt = t.record(t.string, t.number); +export type EntityPagination = t.TypeOf; +export const entityPaginationRt = new t.Type | undefined, string, unknown>( + 'entityPaginationRt', + paginationRt.is, + validate(paginationRt), + (o) => encode(o) +); diff --git a/x-pack/plugins/observability_solution/inventory/e2e/cypress/e2e/home.cy.ts b/x-pack/plugins/observability_solution/inventory/e2e/cypress/e2e/home.cy.ts index 61a55bab3258f..c2e7f1232e6aa 100644 --- a/x-pack/plugins/observability_solution/inventory/e2e/cypress/e2e/home.cy.ts +++ b/x-pack/plugins/observability_solution/inventory/e2e/cypress/e2e/home.cy.ts @@ -80,25 +80,6 @@ describe('Home page', () => { cy.contains('foo'); }); - it('Shows inventory page with unified view of entities', () => { - cy.intercept('GET', '/internal/entities/managed/enablement', { - fixture: 'eem_enabled.json', - }).as('getEEMStatus'); - cy.intercept('GET', '/internal/inventory/entities?**').as('getEntities'); - cy.visitKibana('/app/inventory'); - cy.wait('@getEEMStatus'); - cy.contains('Group entities by: Type'); - cy.getByTestSubj('groupSelectorDropdown').click(); - cy.getByTestSubj('panelUnified').click(); - cy.wait('@getEntities'); - cy.contains('server1'); - cy.contains('host'); - cy.contains('synth-node-trace-logs'); - cy.contains('service'); - cy.contains('foo'); - cy.contains('container'); - }); - it('Navigates to apm when clicking on a service type entity', () => { cy.intercept('GET', '/internal/entities/managed/enablement', { fixture: 'eem_enabled.json', @@ -148,69 +129,69 @@ describe('Home page', () => { cy.intercept('GET', '/internal/entities/managed/enablement', { fixture: 'eem_enabled.json', }).as('getEEMStatus'); - cy.intercept('POST', 'internal/controls/optionsList/entities-*-latest').as( - 'entityTypeControlGroupOptions' - ); cy.intercept('GET', '/internal/inventory/entities?**').as('getEntities'); cy.intercept('GET', '/internal/inventory/entities/types').as('getEntitiesTypes'); cy.intercept('GET', '/internal/inventory/entities/group_by/**').as('getGroups'); cy.visitKibana('/app/inventory'); + cy.wait('@getEntitiesTypes'); cy.wait('@getEEMStatus'); - cy.getByTestSubj('optionsList-control-entity.type').click(); - cy.wait('@entityTypeControlGroupOptions'); - cy.getByTestSubj('optionsList-control-selection-service').click(); + cy.getByTestSubj('entityTypes_multiSelect_filter').click(); + cy.getByTestSubj('entityTypes_multiSelect_filter_selection_service').click(); cy.wait('@getGroups'); cy.getByTestSubj('inventoryGroupTitle_entity.type_service').click(); cy.wait('@getEntities'); cy.get('server1').should('not.exist'); cy.contains('synth-node-trace-logs'); cy.contains('foo').should('not.exist'); + cy.getByTestSubj('entityTypes_multiSelect_filter').click(); + cy.getByTestSubj('entityTypes_multiSelect_filter_selection_service').click(); + cy.getByTestSubj('inventoryGroupTitle_entity.type_service').should('not.exist'); }); it('Filters entities by host type', () => { cy.intercept('GET', '/internal/entities/managed/enablement', { fixture: 'eem_enabled.json', }).as('getEEMStatus'); - cy.intercept('POST', 'internal/controls/optionsList/entities-*-latest').as( - 'entityTypeControlGroupOptions' - ); cy.intercept('GET', '/internal/inventory/entities?**').as('getEntities'); cy.intercept('GET', '/internal/inventory/entities/types').as('getEntitiesTypes'); cy.intercept('GET', '/internal/inventory/entities/group_by/**').as('getGroups'); cy.visitKibana('/app/inventory'); + cy.wait('@getEntitiesTypes'); cy.wait('@getEEMStatus'); - cy.getByTestSubj('optionsList-control-entity.type').click(); - cy.wait('@entityTypeControlGroupOptions'); - cy.getByTestSubj('optionsList-control-selection-host').click(); + cy.getByTestSubj('entityTypes_multiSelect_filter').click(); + cy.getByTestSubj('entityTypes_multiSelect_filter_selection_host').click(); cy.wait('@getGroups'); cy.getByTestSubj('inventoryGroupTitle_entity.type_host').click(); cy.wait('@getEntities'); cy.contains('server1'); cy.contains('synth-node-trace-logs').should('not.exist'); cy.contains('foo').should('not.exist'); + cy.getByTestSubj('entityTypes_multiSelect_filter').click(); + cy.getByTestSubj('entityTypes_multiSelect_filter_selection_host').click(); + cy.getByTestSubj('inventoryGroupTitle_entity.type_host').should('not.exist'); }); it('Filters entities by container type', () => { cy.intercept('GET', '/internal/entities/managed/enablement', { fixture: 'eem_enabled.json', }).as('getEEMStatus'); - cy.intercept('POST', 'internal/controls/optionsList/entities-*-latest').as( - 'entityTypeControlGroupOptions' - ); cy.intercept('GET', '/internal/inventory/entities?**').as('getEntities'); cy.intercept('GET', '/internal/inventory/entities/types').as('getEntitiesTypes'); cy.intercept('GET', '/internal/inventory/entities/group_by/**').as('getGroups'); cy.visitKibana('/app/inventory'); + cy.wait('@getEntitiesTypes'); cy.wait('@getEEMStatus'); - cy.getByTestSubj('optionsList-control-entity.type').click(); - cy.wait('@entityTypeControlGroupOptions'); - cy.getByTestSubj('optionsList-control-selection-container').click(); + cy.getByTestSubj('entityTypes_multiSelect_filter').click(); + cy.getByTestSubj('entityTypes_multiSelect_filter_selection_container').click(); cy.wait('@getGroups'); cy.getByTestSubj('inventoryGroupTitle_entity.type_container').click(); cy.wait('@getEntities'); cy.contains('server1').should('not.exist'); cy.contains('synth-node-trace-logs').should('not.exist'); cy.contains('foo'); + cy.getByTestSubj('entityTypes_multiSelect_filter').click(); + cy.getByTestSubj('entityTypes_multiSelect_filter_selection_container').click(); + cy.getByTestSubj('inventoryGroupTitle_entity.type_container').should('not.exist'); }); it('Navigates to discover with actions button in the entities list', () => { diff --git a/x-pack/plugins/observability_solution/inventory/e2e/cypress/support/commands.ts b/x-pack/plugins/observability_solution/inventory/e2e/cypress/support/commands.ts index 6694b50ce9c70..c3462f8b6ff18 100644 --- a/x-pack/plugins/observability_solution/inventory/e2e/cypress/support/commands.ts +++ b/x-pack/plugins/observability_solution/inventory/e2e/cypress/support/commands.ts @@ -27,23 +27,31 @@ Cypress.Commands.add('loginAsSuperUser', () => { Cypress.Commands.add( 'loginAs', ({ username, password }: { username: string; password: string }) => { - const kibanaUrl = Cypress.env('KIBANA_URL'); - cy.log(`Logging in as ${username} on ${kibanaUrl}`); - cy.visit('/'); - cy.request({ - log: true, - method: 'POST', - url: `${kibanaUrl}/internal/security/login`, - body: { - providerType: 'basic', - providerName: 'basic', - currentURL: `${kibanaUrl}/login`, - params: { username, password }, + cy.session( + username, + () => { + const kibanaUrl = Cypress.env('KIBANA_URL'); + cy.log(`Logging in as ${username} on ${kibanaUrl}`); + cy.visit('/'); + cy.request({ + log: true, + method: 'POST', + url: `${kibanaUrl}/internal/security/login`, + body: { + providerType: 'basic', + providerName: 'basic', + currentURL: `${kibanaUrl}/login`, + params: { username, password }, + }, + headers: { + 'kbn-xsrf': 'e2e_test', + }, + }); + cy.visit('/'); }, - headers: { - 'kbn-xsrf': 'e2e_test', - }, - }); - cy.visit('/'); + { + cacheAcrossSpecs: true, + } + ); } ); diff --git a/x-pack/plugins/observability_solution/inventory/kibana.jsonc b/x-pack/plugins/observability_solution/inventory/kibana.jsonc index e6e7c5f2fa2f8..e7cc398c9c655 100644 --- a/x-pack/plugins/observability_solution/inventory/kibana.jsonc +++ b/x-pack/plugins/observability_solution/inventory/kibana.jsonc @@ -21,7 +21,7 @@ "ruleRegistry", "share" ], - "requiredBundles": ["kibanaReact","controls"], + "requiredBundles": ["kibanaReact"], "optionalPlugins": ["spaces", "cloud"], "extraPublicDirs": [] } diff --git a/x-pack/plugins/observability_solution/inventory/public/components/alerts_badge/alerts_badge.test.tsx b/x-pack/plugins/observability_solution/inventory/public/components/alerts_badge/alerts_badge.test.tsx index 5195a35b93f4e..1892dd0109490 100644 --- a/x-pack/plugins/observability_solution/inventory/public/components/alerts_badge/alerts_badge.test.tsx +++ b/x-pack/plugins/observability_solution/inventory/public/components/alerts_badge/alerts_badge.test.tsx @@ -15,12 +15,10 @@ const useKibanaMock = useKibana as jest.Mock; const commonEntityFields: Partial = { entityLastSeenTimestamp: 'foo', - entityId: '1', + entityId: 'entity1', }; describe('AlertsBadge', () => { - const mockAsKqlFilter = jest.fn(); - beforeEach(() => { jest.clearAllMocks(); @@ -31,11 +29,6 @@ describe('AlertsBadge', () => { prepend: (path: string) => path, }, }, - entityManager: { - entityClient: { - asKqlFilter: mockAsKqlFilter, - }, - }, }, }); }); @@ -59,11 +52,10 @@ describe('AlertsBadge', () => { provider: null, }, }; - mockAsKqlFilter.mockReturnValue('host.name: foo'); render(); expect(screen.queryByTestId('inventoryAlertsBadgeLink')?.getAttribute('href')).toEqual( - "/app/observability/alerts?_a=(kuery:'host.name: foo',status:active)" + `/app/observability/alerts?_a=(kuery:\"entity1\",status:active)` ); expect(screen.queryByTestId('inventoryAlertsBadgeLink')?.textContent).toEqual('1'); }); @@ -86,40 +78,11 @@ describe('AlertsBadge', () => { alertsCount: 5, }; - mockAsKqlFilter.mockReturnValue('service.name: bar'); render(); expect(screen.queryByTestId('inventoryAlertsBadgeLink')?.getAttribute('href')).toEqual( - "/app/observability/alerts?_a=(kuery:'service.name: bar',status:active)" + `/app/observability/alerts?_a=(kuery:\"entity1\",status:active)` ); expect(screen.queryByTestId('inventoryAlertsBadgeLink')?.textContent).toEqual('5'); }); - it('render alerts badge for a service entity with multiple identity fields', () => { - const entity: InventoryEntity = { - ...(commonEntityFields as InventoryEntity), - entityType: 'service', - entityDisplayName: 'foo', - entityIdentityFields: ['service.name', 'service.environment'], - entityDefinitionId: 'service', - service: { - name: 'bar', - environment: 'prod', - }, - agent: { - name: 'node', - }, - cloud: { - provider: null, - }, - alertsCount: 2, - }; - - mockAsKqlFilter.mockReturnValue('service.name: bar AND service.environment: prod'); - - render(); - expect(screen.queryByTestId('inventoryAlertsBadgeLink')?.getAttribute('href')).toEqual( - "/app/observability/alerts?_a=(kuery:'service.name: bar AND service.environment: prod',status:active)" - ); - expect(screen.queryByTestId('inventoryAlertsBadgeLink')?.textContent).toEqual('2'); - }); }); diff --git a/x-pack/plugins/observability_solution/inventory/public/components/alerts_badge/alerts_badge.tsx b/x-pack/plugins/observability_solution/inventory/public/components/alerts_badge/alerts_badge.tsx index ed873bdb68c21..228cd3d8bbfd8 100644 --- a/x-pack/plugins/observability_solution/inventory/public/components/alerts_badge/alerts_badge.tsx +++ b/x-pack/plugins/observability_solution/inventory/public/components/alerts_badge/alerts_badge.tsx @@ -15,21 +15,16 @@ export function AlertsBadge({ entity }: { entity: InventoryEntity }) { const { services: { http: { basePath }, - entityManager, }, } = useKibana(); const activeAlertsHref = basePath.prepend( `/app/observability/alerts?_a=${rison.encode({ - kuery: entityManager.entityClient.asKqlFilter({ - entity: { - identity_fields: entity.entityIdentityFields, - }, - ...entity, - }), + kuery: `"${entity.entityId}"`, status: 'active', })}` ); + return ( { }); it('opens the popover when the badge is clicked', () => { - render(); + render(); expect(screen.queryByTestId(popoverContentDataTestId)).not.toBeInTheDocument(); fireEvent.click(screen.getByText(value)); expect(screen.queryByTestId(popoverContentDataTestId)).toBeInTheDocument(); @@ -35,9 +35,25 @@ describe('BadgeFilterWithPopover', () => { }); it('copies value to clipboard when the "Copy value" button is clicked', () => { - render(); + render(); fireEvent.click(screen.getByText(value)); fireEvent.click(screen.getByTestId('inventoryBadgeFilterWithPopoverCopyValueButton')); expect(copyToClipboard).toHaveBeenCalledWith(value); }); + + it('Filter for an entity', () => { + const handleFilter = jest.fn(); + render(); + fireEvent.click(screen.getByText(value)); + fireEvent.click(screen.getByTestId('inventoryBadgeFilterWithPopoverFilterForButton')); + expect(handleFilter).toHaveBeenCalledWith(value, 'on'); + }); + + it('Filter out an entity', () => { + const handleFilter = jest.fn(); + render(); + fireEvent.click(screen.getByText(value)); + fireEvent.click(screen.getByTestId('inventoryBadgeFilterWithPopoverFilterOutButton')); + expect(handleFilter).toHaveBeenCalledWith(value, 'off'); + }); }); diff --git a/x-pack/plugins/observability_solution/inventory/public/components/badge_filter_with_popover/index.tsx b/x-pack/plugins/observability_solution/inventory/public/components/badge_filter_with_popover/index.tsx index 83e0bb02e6d8d..ea85754dcbf75 100644 --- a/x-pack/plugins/observability_solution/inventory/public/components/badge_filter_with_popover/index.tsx +++ b/x-pack/plugins/observability_solution/inventory/public/components/badge_filter_with_popover/index.tsx @@ -18,19 +18,18 @@ import { } from '@elastic/eui'; import { css } from '@emotion/react'; import { i18n } from '@kbn/i18n'; -import { ENTITY_TYPE } from '@kbn/observability-shared-plugin/common'; import React, { useState } from 'react'; -import { useUnifiedSearchContext } from '../../hooks/use_unified_search_context'; +import type { EntityTypeCheckOptions } from '../../../common/rt_types'; interface Props { field: string; value: string; + onFilter: (value: string, checked: EntityTypeCheckOptions) => void; } -export function BadgeFilterWithPopover({ field, value }: Props) { +export function BadgeFilterWithPopover({ field, value, onFilter }: Props) { const [isOpen, setIsOpen] = useState(false); const theme = useEuiTheme(); - const { addFilter } = useUnifiedSearchContext(); return ( { - addFilter({ fieldName: ENTITY_TYPE, operation: '+', value }); + onFilter(value, 'on'); }} > {i18n.translate('xpack.inventory.badgeFilterWithPopover.filterForButtonEmptyLabel', { @@ -92,10 +91,10 @@ export function BadgeFilterWithPopover({ field, value }: Props) { { - addFilter({ fieldName: ENTITY_TYPE, operation: '-', value }); + onFilter(value, 'off'); }} > {i18n.translate('xpack.inventory.badgeFilterWithPopover.filterForButtonEmptyLabel', { diff --git a/x-pack/plugins/observability_solution/inventory/public/components/entities_grid/entities_grid.stories.tsx b/x-pack/plugins/observability_solution/inventory/public/components/entities_grid/entities_grid.stories.tsx index ae80bf09ecae2..b5e9287a836dd 100644 --- a/x-pack/plugins/observability_solution/inventory/public/components/entities_grid/entities_grid.stories.tsx +++ b/x-pack/plugins/observability_solution/inventory/public/components/entities_grid/entities_grid.stories.tsx @@ -77,6 +77,7 @@ export const Grid: Story = (args) => { onChangePage={setPageIndex} onChangeSort={setSort} pageIndex={pageIndex} + onFilterByType={() => {}} /> @@ -99,6 +100,7 @@ export const EmptyGrid: Story = (args) => { onChangePage={setPageIndex} onChangeSort={setSort} pageIndex={pageIndex} + onFilterByType={() => {}} /> ); }; diff --git a/x-pack/plugins/observability_solution/inventory/public/components/entities_grid/index.tsx b/x-pack/plugins/observability_solution/inventory/public/components/entities_grid/index.tsx index 541af76350723..b26676494833e 100644 --- a/x-pack/plugins/observability_solution/inventory/public/components/entities_grid/index.tsx +++ b/x-pack/plugins/observability_solution/inventory/public/components/entities_grid/index.tsx @@ -22,6 +22,7 @@ import { getColumns } from './grid_columns'; import { AlertsBadge } from '../alerts_badge/alerts_badge'; import { EntityName } from './entity_name'; import { EntityActions } from '../entity_actions'; +import { type EntityTypeCheckOptions } from '../../../common/rt_types'; interface Props { loading: boolean; @@ -31,6 +32,7 @@ interface Props { pageIndex: number; onChangeSort: (sorting: EuiDataGridSorting['columns'][0]) => void; onChangePage: (nextPage: number) => void; + onFilterByType: (value: string, checked: EntityTypeCheckOptions) => void; } const PAGE_SIZE = 20; @@ -43,6 +45,7 @@ export function EntitiesGrid({ pageIndex, onChangePage, onChangeSort, + onFilterByType, }: Props) { const [showActions, setShowActions] = useState(true); @@ -84,7 +87,13 @@ export function EntitiesGrid({ return entity?.alertsCount ? : null; case 'entityType': - return ; + return ( + + ); case 'entityLastSeenTimestamp': return ( @@ -120,7 +129,7 @@ export function EntitiesGrid({ return null; } }, - [entities] + [entities, onFilterByType] ); if (loading) { diff --git a/x-pack/plugins/observability_solution/inventory/public/components/grouped_inventory/inventory_summary.test.tsx b/x-pack/plugins/observability_solution/inventory/public/components/entities_summary/entities_summary.test.tsx similarity index 72% rename from x-pack/plugins/observability_solution/inventory/public/components/grouped_inventory/inventory_summary.test.tsx rename to x-pack/plugins/observability_solution/inventory/public/components/entities_summary/entities_summary.test.tsx index 63583e60b0edd..9f4a5df76e0d9 100644 --- a/x-pack/plugins/observability_solution/inventory/public/components/grouped_inventory/inventory_summary.test.tsx +++ b/x-pack/plugins/observability_solution/inventory/public/components/entities_summary/entities_summary.test.tsx @@ -9,12 +9,7 @@ import React from 'react'; import { render, screen } from '@testing-library/react'; import { EuiThemeProvider } from '@elastic/eui'; import { I18nProvider } from '@kbn/i18n-react'; -import { InventorySummary } from './inventory_summary'; - -// Do not test the GroupSelector, as it needs a lot more complicated setup -jest.mock('./group_selector', () => ({ - GroupSelector: () => <>Selector, -})); +import { EntitiesSummary } from '.'; function MockEnvWrapper({ children }: { children?: React.ReactNode }) { return ( @@ -24,19 +19,19 @@ function MockEnvWrapper({ children }: { children?: React.ReactNode }) { ); } -describe('InventorySummary', () => { +describe('EntitiesSummary', () => { it('renders the total entities without any group totals', () => { - render(, { wrapper: MockEnvWrapper }); + render(, { wrapper: MockEnvWrapper }); expect(screen.getByText('10 Entities')).toBeInTheDocument(); expect(screen.queryByTestId('inventorySummaryGroupsTotal')).not.toBeInTheDocument(); }); it('renders the total entities with group totals', () => { - render(, { wrapper: MockEnvWrapper }); + render(, { wrapper: MockEnvWrapper }); expect(screen.getByText('15 Entities')).toBeInTheDocument(); expect(screen.queryByText('3 Groups')).toBeInTheDocument(); }); it("won't render either totals when not provided anything", () => { - render(, { wrapper: MockEnvWrapper }); + render(, { wrapper: MockEnvWrapper }); expect(screen.queryByTestId('inventorySummaryEntitiesTotal')).not.toBeInTheDocument(); expect(screen.queryByTestId('inventorySummaryGroupsTotal')).not.toBeInTheDocument(); }); diff --git a/x-pack/plugins/observability_solution/inventory/public/components/entities_summary/index.tsx b/x-pack/plugins/observability_solution/inventory/public/components/entities_summary/index.tsx new file mode 100644 index 0000000000000..8388ad64407ac --- /dev/null +++ b/x-pack/plugins/observability_solution/inventory/public/components/entities_summary/index.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 { EuiFlexGroup, EuiFlexItem, useEuiTheme } from '@elastic/eui'; +import { css } from '@emotion/react'; +import { FormattedMessage } from '@kbn/i18n-react'; + +export function EntitiesSummary({ + totalEntities, + totalGroups, +}: { + totalEntities?: number; + totalGroups?: number; +}) { + const { euiTheme } = useEuiTheme(); + + const isGrouped = totalGroups !== undefined; + + return ( + + {totalEntities !== undefined && ( + + + + + + )} + {isGrouped ? ( + + + + + + ) : null} + + ); +} diff --git a/x-pack/plugins/observability_solution/inventory/public/components/grouped_inventory/inventory_panel_badge.tsx b/x-pack/plugins/observability_solution/inventory/public/components/entity_group_accordion/entity_count_badge.tsx similarity index 95% rename from x-pack/plugins/observability_solution/inventory/public/components/grouped_inventory/inventory_panel_badge.tsx rename to x-pack/plugins/observability_solution/inventory/public/components/entity_group_accordion/entity_count_badge.tsx index 43db1c39154bc..a0c9a2a18c4a6 100644 --- a/x-pack/plugins/observability_solution/inventory/public/components/grouped_inventory/inventory_panel_badge.tsx +++ b/x-pack/plugins/observability_solution/inventory/public/components/entity_group_accordion/entity_count_badge.tsx @@ -7,7 +7,7 @@ import { EuiBadge, EuiFlexGroup, EuiFlexItem, EuiText } from '@elastic/eui'; import React from 'react'; -export function InventoryPanelBadge({ +export function EntityCountBadge({ name, value, 'data-test-subj': dataTestSubj, diff --git a/x-pack/plugins/observability_solution/inventory/public/components/grouped_inventory/inventory_group_accordion.test.tsx b/x-pack/plugins/observability_solution/inventory/public/components/entity_group_accordion/entity_group_accordion.test.tsx similarity index 80% rename from x-pack/plugins/observability_solution/inventory/public/components/grouped_inventory/inventory_group_accordion.test.tsx rename to x-pack/plugins/observability_solution/inventory/public/components/entity_group_accordion/entity_group_accordion.test.tsx index bf0b7064033f4..747124808df2e 100644 --- a/x-pack/plugins/observability_solution/inventory/public/components/grouped_inventory/inventory_group_accordion.test.tsx +++ b/x-pack/plugins/observability_solution/inventory/public/components/entity_group_accordion/entity_group_accordion.test.tsx @@ -7,10 +7,9 @@ import React from 'react'; import { render, screen, within } from '@testing-library/react'; +import { EntityGroupAccordion } from '.'; -import { InventoryGroupAccordion } from './inventory_group_accordion'; - -describe('Grouped Inventory Accordion', () => { +describe('EntityGroupAccordion', () => { it('renders with correct values', () => { const props = { groupBy: 'entity.type', @@ -26,14 +25,14 @@ describe('Grouped Inventory Accordion', () => { ], }; render( - ); expect(screen.getByText(props.groups[0]['entity.type'])).toBeInTheDocument(); - const container = screen.getByTestId('inventoryPanelBadgeEntitiesCount_entity.type_host'); + const container = screen.getByTestId('entityCountBadge_entity.type_host'); expect(within(container).getByText('Entities:')).toBeInTheDocument(); expect(within(container).getByText(props.groups[0].count)).toBeInTheDocument(); }); diff --git a/x-pack/plugins/observability_solution/inventory/public/components/grouped_inventory/grouped_entities_grid.tsx b/x-pack/plugins/observability_solution/inventory/public/components/entity_group_accordion/grouped_entities_grid.tsx similarity index 67% rename from x-pack/plugins/observability_solution/inventory/public/components/grouped_inventory/grouped_entities_grid.tsx rename to x-pack/plugins/observability_solution/inventory/public/components/entity_group_accordion/grouped_entities_grid.tsx index 911e997401023..5dde32cbb4aac 100644 --- a/x-pack/plugins/observability_solution/inventory/public/components/grouped_inventory/grouped_entities_grid.tsx +++ b/x-pack/plugins/observability_solution/inventory/public/components/entity_group_accordion/grouped_entities_grid.tsx @@ -5,15 +5,16 @@ * 2.0. */ import { EuiDataGridSorting } from '@elastic/eui'; -import { decodeOrThrow } from '@kbn/io-ts-utils'; import React from 'react'; import useEffectOnce from 'react-use/lib/useEffectOnce'; +import { type EntityColumnIds } from '../../../common/entities'; import { + type EntityTypeCheckOptions, entityPaginationRt, - type EntityColumnIds, - type EntityPagination, -} from '../../../common/entities'; + entityTypesRt, +} from '../../../common/rt_types'; import { useInventoryAbortableAsync } from '../../hooks/use_inventory_abortable_async'; +import { useInventoryDecodedQueryParams } from '../../hooks/use_inventory_decoded_query_params'; import { useInventoryParams } from '../../hooks/use_inventory_params'; import { useInventoryRouter } from '../../hooks/use_inventory_router'; import { useKibana } from '../../hooks/use_kibana'; @@ -24,29 +25,14 @@ interface Props { groupValue: string; } -const paginationDecoder = decodeOrThrow(entityPaginationRt); - export function GroupedEntitiesGrid({ groupValue }: Props) { const { query } = useInventoryParams('/'); - const { sortField, sortDirection, pagination: paginationQuery } = query; + const { sortField, sortDirection, kuery } = query; + const { pagination, entityTypes } = useInventoryDecodedQueryParams(); const inventoryRoute = useInventoryRouter(); - let pagination: EntityPagination | undefined = {}; - const { stringifiedEsQuery } = useUnifiedSearchContext(); - try { - pagination = paginationDecoder(paginationQuery); - } catch (error) { - inventoryRoute.push('/', { - path: {}, - query: { - ...query, - pagination: undefined, - }, - }); - window.location.reload(); - } const pageIndex = pagination?.[groupValue] ?? 0; - const { refreshSubject$, isControlPanelsInitiated } = useUnifiedSearchContext(); + const { refreshSubject$ } = useUnifiedSearchContext(); const { services: { inventoryAPIClient }, } = useKibana(); @@ -57,28 +43,19 @@ export function GroupedEntitiesGrid({ groupValue }: Props) { refresh, } = useInventoryAbortableAsync( ({ signal }) => { - if (isControlPanelsInitiated) { - return inventoryAPIClient.fetch('GET /internal/inventory/entities', { - params: { - query: { - sortDirection, - sortField, - esQuery: stringifiedEsQuery, - entityTypes: groupValue?.length ? JSON.stringify([groupValue]) : undefined, - }, + return inventoryAPIClient.fetch('GET /internal/inventory/entities', { + params: { + query: { + sortDirection, + sortField, + kuery, + entityTypes: groupValue?.length ? JSON.stringify([groupValue]) : undefined, }, - signal, - }); - } + }, + signal, + }); }, - [ - groupValue, - inventoryAPIClient, - sortDirection, - sortField, - isControlPanelsInitiated, - stringifiedEsQuery, - ] + [groupValue, inventoryAPIClient, sortDirection, sortField, kuery] ); useEffectOnce(() => { @@ -111,6 +88,16 @@ export function GroupedEntitiesGrid({ groupValue }: Props) { }); } + function handleEntityTypeFilter(entityType: string, checkOption: EntityTypeCheckOptions) { + inventoryRoute.push('/', { + path: {}, + query: { + ...query, + entityTypes: entityTypesRt.encode({ ...entityTypes, [entityType]: checkOption }), + }, + }); + } + return ( ); } diff --git a/x-pack/plugins/observability_solution/inventory/public/components/grouped_inventory/inventory_group_accordion.tsx b/x-pack/plugins/observability_solution/inventory/public/components/entity_group_accordion/index.tsx similarity index 85% rename from x-pack/plugins/observability_solution/inventory/public/components/grouped_inventory/inventory_group_accordion.tsx rename to x-pack/plugins/observability_solution/inventory/public/components/entity_group_accordion/index.tsx index 0b4e9a46d4288..fa365625474b0 100644 --- a/x-pack/plugins/observability_solution/inventory/public/components/grouped_inventory/inventory_group_accordion.tsx +++ b/x-pack/plugins/observability_solution/inventory/public/components/entity_group_accordion/index.tsx @@ -8,27 +8,22 @@ import { EuiAccordion, EuiPanel, EuiSpacer, EuiTitle, useEuiTheme } from '@elast import { css } from '@emotion/react'; import { i18n } from '@kbn/i18n'; import React, { useCallback, useState } from 'react'; +import { EntityCountBadge } from './entity_count_badge'; import { GroupedEntitiesGrid } from './grouped_entities_grid'; -import { InventoryPanelBadge } from './inventory_panel_badge'; const ENTITIES_COUNT_BADGE = i18n.translate( 'xpack.inventory.inventoryGroupPanel.entitiesBadgeLabel', { defaultMessage: 'Entities' } ); -export interface InventoryGroupAccordionProps { +export interface Props { groupBy: string; groupValue: string; groupCount: number; isLoading?: boolean; } -export function InventoryGroupAccordion({ - groupBy, - groupValue, - groupCount, - isLoading, -}: InventoryGroupAccordionProps) { +export function EntityGroupAccordion({ groupBy, groupValue, groupCount, isLoading }: Props) { const { euiTheme } = useEuiTheme(); const [open, setOpen] = useState(false); @@ -55,8 +50,8 @@ export function InventoryGroupAccordion({ } buttonElement="div" extraAction={ - diff --git a/x-pack/plugins/observability_solution/inventory/public/components/grouped_inventory/mock/inventory_component_wrapper_mock.tsx b/x-pack/plugins/observability_solution/inventory/public/components/entity_group_accordion/mock/inventory_component_wrapper_mock.tsx similarity index 100% rename from x-pack/plugins/observability_solution/inventory/public/components/grouped_inventory/mock/inventory_component_wrapper_mock.tsx rename to x-pack/plugins/observability_solution/inventory/public/components/entity_group_accordion/mock/inventory_component_wrapper_mock.tsx diff --git a/x-pack/plugins/observability_solution/inventory/public/components/group_by_selector/group_by_selector.test.tsx b/x-pack/plugins/observability_solution/inventory/public/components/group_by_selector/group_by_selector.test.tsx new file mode 100644 index 0000000000000..6f504715e99c8 --- /dev/null +++ b/x-pack/plugins/observability_solution/inventory/public/components/group_by_selector/group_by_selector.test.tsx @@ -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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { render, screen } from '@testing-library/react'; +import React from 'react'; +import { GroupBySelector } from '.'; +import { InventoryComponentWrapperMock } from '../entity_group_accordion/mock/inventory_component_wrapper_mock'; + +describe('GroupBySelector', () => { + beforeEach(() => { + render( + + + + ); + }); + it('Should default to Type', async () => { + expect(await screen.findByText('Group entities by: Type')).toBeInTheDocument(); + }); +}); diff --git a/x-pack/plugins/observability_solution/inventory/public/components/grouped_inventory/group_selector.tsx b/x-pack/plugins/observability_solution/inventory/public/components/group_by_selector/index.tsx similarity index 50% rename from x-pack/plugins/observability_solution/inventory/public/components/grouped_inventory/group_selector.tsx rename to x-pack/plugins/observability_solution/inventory/public/components/group_by_selector/index.tsx index 95264f3c81303..b9aa28d3f2980 100644 --- a/x-pack/plugins/observability_solution/inventory/public/components/grouped_inventory/group_selector.tsx +++ b/x-pack/plugins/observability_solution/inventory/public/components/group_by_selector/index.tsx @@ -5,49 +5,17 @@ * 2.0. */ -import { EuiPopover, EuiContextMenu, EuiButtonEmpty } from '@elastic/eui'; -import React, { useCallback, useState } from 'react'; +import { EuiButtonEmpty, EuiContextMenu, EuiPopover } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; -import type { EntityView } from '../../../common/entities'; -import { useInventoryParams } from '../../hooks/use_inventory_params'; -import { useInventoryRouter } from '../../hooks/use_inventory_router'; +import React, { useCallback, useState } from 'react'; -const GROUP_LABELS: Record = { - unified: i18n.translate('xpack.inventory.groupedInventoryPage.noneLabel', { - defaultMessage: 'None', - }), - grouped: i18n.translate('xpack.inventory.groupedInventoryPage.typeLabel', { - defaultMessage: 'Type', - }), -}; +const ENTITY_TYPE_LABEL = i18n.translate('xpack.inventory.groupedInventoryPage.typeLabel', { + defaultMessage: 'Type', +}); -export interface GroupedSelectorProps { - groupSelected: string; - onGroupChange: (groupSelection: string) => void; -} - -export function GroupSelector() { - const { query } = useInventoryParams('/'); - const inventoryRoute = useInventoryRouter(); +export function GroupBySelector() { const [isPopoverOpen, setIsPopoverOpen] = useState(false); - const groupBy = query.view ?? 'grouped'; - - const onGroupChange = (selected: EntityView) => { - const { pagination: _, ...rest } = query; - - inventoryRoute.push('/', { - path: {}, - query: { - ...rest, - view: groupBy === selected ? 'unified' : selected, - }, - }); - }; - - const isGroupSelected = (groupKey: EntityView) => { - return groupBy === groupKey; - }; const panels = [ { @@ -56,17 +24,10 @@ export function GroupSelector() { defaultMessage: 'Select grouping', }), items: [ - { - 'data-test-subj': 'panelUnified', - name: GROUP_LABELS.unified, - icon: isGroupSelected('unified') ? 'check' : 'empty', - onClick: () => onGroupChange('unified'), - }, { 'data-test-subj': 'panelType', - name: GROUP_LABELS.grouped, - icon: isGroupSelected('grouped') ? 'check' : 'empty', - onClick: () => onGroupChange('grouped'), + name: ENTITY_TYPE_LABEL, + icon: 'check', }, ], }, @@ -83,13 +44,13 @@ export function GroupSelector() { iconSize="s" iconType="arrowDown" onClick={onButtonClick} - title={GROUP_LABELS[groupBy]} + title={ENTITY_TYPE_LABEL} size="s" > ); diff --git a/x-pack/plugins/observability_solution/inventory/public/components/grouped_inventory/group_selector.test.tsx b/x-pack/plugins/observability_solution/inventory/public/components/grouped_inventory/group_selector.test.tsx deleted file mode 100644 index 23cbb5b43c43b..0000000000000 --- a/x-pack/plugins/observability_solution/inventory/public/components/grouped_inventory/group_selector.test.tsx +++ /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; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; -import { render, screen } from '@testing-library/react'; -import userEvent from '@testing-library/user-event'; - -import { GroupSelector } from './group_selector'; - -import { InventoryComponentWrapperMock } from './mock/inventory_component_wrapper_mock'; - -describe('GroupSelector', () => { - beforeEach(() => { - render( - - - - ); - }); - it('Should default to Type', async () => { - expect(await screen.findByText('Group entities by: Type')).toBeInTheDocument(); - }); - - it.skip('Should change to None', async () => { - const user = userEvent.setup(); - - const selector = screen.getByText('Group entities by: Type'); - - expect(selector).toBeInTheDocument(); - - await user.click(selector); - - const noneOption = screen.getByTestId('panelUnified'); - - expect(noneOption).toBeInTheDocument(); - - await user.click(noneOption); - - expect(await screen.findByText('Group entities by: None')).toBeInTheDocument(); - }); -}); diff --git a/x-pack/plugins/observability_solution/inventory/public/components/grouped_inventory/index.tsx b/x-pack/plugins/observability_solution/inventory/public/components/grouped_inventory/index.tsx deleted file mode 100644 index 6cfdc079be299..0000000000000 --- a/x-pack/plugins/observability_solution/inventory/public/components/grouped_inventory/index.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; you may not use this file except in compliance with the Elastic License - * 2.0. - */ -import { EuiSpacer } from '@elastic/eui'; -import { ENTITY_TYPE } from '@kbn/observability-shared-plugin/common'; -import React from 'react'; -import useEffectOnce from 'react-use/lib/useEffectOnce'; -import { flattenObject } from '@kbn/observability-utils-common/object/flatten_object'; -import { useInventoryAbortableAsync } from '../../hooks/use_inventory_abortable_async'; -import { useKibana } from '../../hooks/use_kibana'; -import { useUnifiedSearchContext } from '../../hooks/use_unified_search_context'; -import { InventoryGroupAccordion } from './inventory_group_accordion'; -import { InventorySummary } from './inventory_summary'; - -export function GroupedInventory() { - const { - services: { inventoryAPIClient }, - } = useKibana(); - const { refreshSubject$, isControlPanelsInitiated, stringifiedEsQuery } = - useUnifiedSearchContext(); - - const { - value = { groupBy: ENTITY_TYPE, groups: [], entitiesCount: 0 }, - refresh, - loading, - } = useInventoryAbortableAsync( - ({ signal }) => { - if (isControlPanelsInitiated) { - return inventoryAPIClient.fetch('GET /internal/inventory/entities/group_by/{field}', { - params: { - path: { - field: ENTITY_TYPE, - }, - query: { esQuery: stringifiedEsQuery }, - }, - signal, - }); - } - }, - [inventoryAPIClient, stringifiedEsQuery, isControlPanelsInitiated] - ); - - useEffectOnce(() => { - const refreshSubscription = refreshSubject$.subscribe(refresh); - - return () => refreshSubscription.unsubscribe(); - }); - - return ( - <> - - - {value.groups.map((group) => { - const groupValue = flattenObject(group)[value.groupBy]; - return ( - - ); - })} - - ); -} diff --git a/x-pack/plugins/observability_solution/inventory/public/components/grouped_inventory/inventory_summary.tsx b/x-pack/plugins/observability_solution/inventory/public/components/grouped_inventory/inventory_summary.tsx deleted file mode 100644 index 55697790c4ee9..0000000000000 --- a/x-pack/plugins/observability_solution/inventory/public/components/grouped_inventory/inventory_summary.tsx +++ /dev/null @@ -1,69 +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 { EuiFlexGroup, EuiFlexItem, useEuiTheme } from '@elastic/eui'; -import { css } from '@emotion/react'; -import { FormattedMessage } from '@kbn/i18n-react'; -import { GroupSelector } from './group_selector'; - -export function InventorySummary({ - totalEntities, - totalGroups, -}: { - totalEntities?: number; - totalGroups?: number; -}) { - const { euiTheme } = useEuiTheme(); - - const isGrouped = totalGroups !== undefined; - - return ( - - - - {totalEntities !== undefined && ( - - - - - - )} - {isGrouped ? ( - - - - - - ) : null} - - - - - - - ); -} diff --git a/x-pack/plugins/observability_solution/inventory/public/components/search_bar/control_groups.tsx b/x-pack/plugins/observability_solution/inventory/public/components/search_bar/control_groups.tsx deleted file mode 100644 index 9c263e39562f1..0000000000000 --- a/x-pack/plugins/observability_solution/inventory/public/components/search_bar/control_groups.tsx +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { - ControlGroupRenderer, - ControlGroupRendererApi, - ControlGroupRuntimeState, -} from '@kbn/controls-plugin/public'; -import { ENTITY_TYPE } from '@kbn/observability-shared-plugin/common'; -import { ControlPanels, useControlPanels } from '@kbn/observability-shared-plugin/public'; -import React, { useCallback, useEffect, useRef } from 'react'; -import { skip, Subscription } from 'rxjs'; -import { useUnifiedSearchContext } from '../../hooks/use_unified_search_context'; - -const controlPanelDefinitions: ControlPanels = { - [ENTITY_TYPE]: { - order: 0, - type: 'optionsListControl', - fieldName: ENTITY_TYPE, - width: 'small', - grow: false, - title: 'Type', - }, -}; - -export function ControlGroups() { - const { - isControlPanelsInitiated, - setIsControlPanelsInitiated, - dataView, - searchState, - onPanelFiltersChange, - } = useUnifiedSearchContext(); - const [controlPanels, setControlPanels] = useControlPanels(controlPanelDefinitions, dataView); - const subscriptions = useRef(new Subscription()); - - const getInitialInput = useCallback( - () => async () => { - const initialInput: Partial = { - chainingSystem: 'HIERARCHICAL', - labelPosition: 'oneLine', - initialChildControlState: controlPanels, - }; - - return { initialState: initialInput }; - }, - [controlPanels] - ); - - const loadCompleteHandler = useCallback( - (controlGroup: ControlGroupRendererApi) => { - if (!controlGroup) return; - - subscriptions.current.add( - controlGroup.filters$.pipe(skip(1)).subscribe((newFilters = []) => { - onPanelFiltersChange(newFilters); - }) - ); - - subscriptions.current.add( - controlGroup.getInput$().subscribe(({ initialChildControlState }) => { - if (!isControlPanelsInitiated) { - setIsControlPanelsInitiated(true); - } - setControlPanels(initialChildControlState); - }) - ); - }, - [isControlPanelsInitiated, onPanelFiltersChange, setControlPanels, setIsControlPanelsInitiated] - ); - - useEffect(() => { - const currentSubscriptions = subscriptions.current; - return () => { - currentSubscriptions.unsubscribe(); - }; - }, []); - - if (!dataView) { - return null; - } - - return ( -
        - -
        - ); -} diff --git a/x-pack/plugins/observability_solution/inventory/public/components/search_bar/entity_types_multi_select.tsx b/x-pack/plugins/observability_solution/inventory/public/components/search_bar/entity_types_multi_select.tsx new file mode 100644 index 0000000000000..0b4853e82a474 --- /dev/null +++ b/x-pack/plugins/observability_solution/inventory/public/components/search_bar/entity_types_multi_select.tsx @@ -0,0 +1,146 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor 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 { + EuiFilterButton, + EuiFilterGroup, + EuiPopover, + EuiPopoverTitle, + EuiSelectable, + EuiSelectableOption, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import React, { useCallback, useMemo, useState } from 'react'; +import { entityTypesRt, type EntityType } from '../../../common/rt_types'; +import { useInventoryAbortableAsync } from '../../hooks/use_inventory_abortable_async'; +import { useInventoryDecodedQueryParams } from '../../hooks/use_inventory_decoded_query_params'; +import { useInventoryParams } from '../../hooks/use_inventory_params'; +import { useInventoryRouter } from '../../hooks/use_inventory_router'; +import { useKibana } from '../../hooks/use_kibana'; +import { groupEntityTypesByStatus } from '../../utils/group_entity_types_by_status'; + +export function EntityTypesMultiSelect() { + const inventoryRoute = useInventoryRouter(); + const { query } = useInventoryParams('/*'); + const { entityTypes: selectedEntityTypes } = useInventoryDecodedQueryParams(); + + const { + services: { inventoryAPIClient, telemetry }, + } = useKibana(); + const [isPopoverOpen, setIsPopoverOpen] = useState(false); + + const { value, loading } = useInventoryAbortableAsync( + ({ signal }) => inventoryAPIClient.fetch('GET /internal/inventory/entities/types', { signal }), + [inventoryAPIClient] + ); + + const items = useMemo( + () => + value?.entityTypes.map((type): EuiSelectableOption => { + const checked = selectedEntityTypes?.[type]; + return { + label: type, + checked, + 'data-test-subj': `entityTypes_multiSelect_filter_selection_${type}`, + }; + }) || [], + [selectedEntityTypes, value?.entityTypes] + ); + + const registerEntityTypeFilteredEvent = useCallback( + ({ filterEntityTypes }: { filterEntityTypes: EntityType }) => { + const { entityTypesOff, entityTypesOn } = groupEntityTypesByStatus(filterEntityTypes); + + telemetry.reportEntityInventoryEntityTypeFiltered({ + include_entity_types: entityTypesOn, + exclude_entity_types: entityTypesOff, + }); + }, + [telemetry] + ); + + function handleEntityTypeChecked(nextItems: EntityType) { + registerEntityTypeFilteredEvent({ filterEntityTypes: nextItems }); + inventoryRoute.push('/', { + path: {}, + query: { + ...query, + entityTypes: entityTypesRt.encode(nextItems), + }, + }); + } + + return ( + + setIsPopoverOpen((state) => !state)} + isSelected={isPopoverOpen} + numFilters={items.filter((item) => item.checked !== 'off').length} + hasActiveFilters={!!items.find((item) => item.checked === 'on')} + numActiveFilters={items.filter((item) => item.checked === 'on').length} + > + {i18n.translate('xpack.inventory.entityTypesMultSelect.typeFilterButtonLabel', { + defaultMessage: 'Type', + })} + + } + isOpen={isPopoverOpen} + closePopover={() => setIsPopoverOpen(false)} + panelPaddingSize="none" + > + { + handleEntityTypeChecked( + newOptions + .filter((item) => item.checked) + .reduce((acc, curr) => ({ ...acc, [curr.label]: curr.checked! }), {}) + ); + }} + isLoading={loading} + loadingMessage={i18n.translate( + 'xpack.inventory.entityTypesMultSelect.euiSelectable.loading', + { defaultMessage: 'Loading types' } + )} + emptyMessage={i18n.translate( + 'xpack.inventory.entityTypesMultSelect.euiSelectable.empty', + { defaultMessage: 'No types available' } + )} + noMatchesMessage={i18n.translate( + 'xpack.inventory.entityTypesMultSelect.euiSelectable.notFound', + { defaultMessage: 'No types found' } + )} + > + {(list, search) => ( +
        + {search} + {list} +
        + )} +
        +
        +
        + ); +} diff --git a/x-pack/plugins/observability_solution/inventory/public/components/search_bar/index.tsx b/x-pack/plugins/observability_solution/inventory/public/components/search_bar/index.tsx index 3464c5749dbc3..16df0927df355 100644 --- a/x-pack/plugins/observability_solution/inventory/public/components/search_bar/index.tsx +++ b/x-pack/plugins/observability_solution/inventory/public/components/search_bar/index.tsx @@ -4,19 +4,24 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import type { Query } from '@kbn/es-query'; import { i18n } from '@kbn/i18n'; import type { SearchBarOwnProps } from '@kbn/unified-search-plugin/public/search_bar'; import deepEqual from 'fast-deep-equal'; import React, { useCallback, useEffect } from 'react'; +import { useInventoryParams } from '../../hooks/use_inventory_params'; +import { useInventoryRouter } from '../../hooks/use_inventory_router'; import { useKibana } from '../../hooks/use_kibana'; import { useUnifiedSearchContext } from '../../hooks/use_unified_search_context'; import { getKqlFieldsWithFallback } from '../../utils/get_kql_field_names_with_fallback'; -import { ControlGroups } from './control_groups'; +import { EntityTypesMultiSelect } from './entity_types_multi_select'; export function SearchBar() { - const { refreshSubject$, dataView, searchState, onQueryChange } = useUnifiedSearchContext(); - + const { refreshSubject$, dataView } = useUnifiedSearchContext(); + const inventoryRoute = useInventoryRouter(); + const { + query, + query: { kuery }, + } = useInventoryParams('/*'); const { services: { unifiedSearch, @@ -30,44 +35,40 @@ export function SearchBar() { const { SearchBar: UnifiedSearchBar } = unifiedSearch.ui; const syncSearchBarWithUrl = useCallback(() => { - const query = searchState.query; - if (query && !deepEqual(queryStringService.getQuery(), query)) { - queryStringService.setQuery(query); + const _query = kuery ? { query: kuery, language: 'kuery' } : undefined; + if (_query && !deepEqual(queryStringService.getQuery(), _query)) { + queryStringService.setQuery(_query); } - if (!query) { + if (!_query) { queryStringService.clearQuery(); } - }, [searchState.query, queryStringService]); + }, [kuery, queryStringService]); useEffect(() => { syncSearchBarWithUrl(); }, [syncSearchBarWithUrl]); - const registerSearchSubmittedEvent = useCallback( - ({ searchQuery, searchIsUpdate }: { searchQuery?: Query; searchIsUpdate?: boolean }) => { - telemetry.reportEntityInventorySearchQuerySubmitted({ - kuery_fields: getKqlFieldsWithFallback(searchQuery?.query as string), - action: searchIsUpdate ? 'submit' : 'refresh', + const handleQuerySubmit = useCallback>( + ({ query: _query = { language: 'kuery', query: '' } }, isUpdate) => { + inventoryRoute.push('/', { + path: {}, + query: { + ...query, + kuery: _query?.query as string, + }, }); - }, - [telemetry] - ); - const handleQuerySubmit = useCallback>( - ({ query = { language: 'kuery', query: '' } }, isUpdate) => { - if (isUpdate) { - onQueryChange(query); - } else { + if (!isUpdate) { refreshSubject$.next(); } - registerSearchSubmittedEvent({ - searchQuery: query, - searchIsUpdate: isUpdate, + telemetry.reportEntityInventorySearchQuerySubmitted({ + kuery_fields: getKqlFieldsWithFallback(_query?.query as string), + action: isUpdate ? 'submit' : 'refresh', }); }, - [registerSearchSubmittedEvent, onQueryChange, refreshSubject$] + [inventoryRoute, query, telemetry, refreshSubject$] ); return ( @@ -75,16 +76,14 @@ export function SearchBar() { appName="Inventory" displayStyle="inPage" indexPatterns={dataView ? [dataView] : undefined} - renderQueryInputAppend={() => } + renderQueryInputAppend={() => } onQuerySubmit={handleQuerySubmit} placeholder={i18n.translate('xpack.inventory.searchBar.placeholder', { defaultMessage: 'Search for your entities by name or its metadata (e.g. entity.type : service)', })} showDatePicker={false} - showFilterBar - showQueryInput - showQueryMenu + showFilterBar={false} /> ); } diff --git a/x-pack/plugins/observability_solution/inventory/public/components/unified_inventory/index.tsx b/x-pack/plugins/observability_solution/inventory/public/components/unified_inventory/index.tsx deleted file mode 100644 index 1bec6dee990d1..0000000000000 --- a/x-pack/plugins/observability_solution/inventory/public/components/unified_inventory/index.tsx +++ /dev/null @@ -1,117 +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 { EuiDataGridSorting } from '@elastic/eui'; -import { decodeOrThrow } from '@kbn/io-ts-utils'; -import React from 'react'; -import useEffectOnce from 'react-use/lib/useEffectOnce'; -import { - entityPaginationRt, - type EntityColumnIds, - type EntityPagination, -} from '../../../common/entities'; -import { useInventoryAbortableAsync } from '../../hooks/use_inventory_abortable_async'; -import { useInventoryParams } from '../../hooks/use_inventory_params'; -import { useInventoryRouter } from '../../hooks/use_inventory_router'; -import { useKibana } from '../../hooks/use_kibana'; -import { useUnifiedSearchContext } from '../../hooks/use_unified_search_context'; -import { EntitiesGrid } from '../entities_grid'; -import { InventorySummary } from '../grouped_inventory/inventory_summary'; - -const paginationDecoder = decodeOrThrow(entityPaginationRt); - -export function UnifiedInventory() { - const { - services: { inventoryAPIClient }, - } = useKibana(); - const { refreshSubject$, isControlPanelsInitiated, stringifiedEsQuery } = - useUnifiedSearchContext(); - const { query } = useInventoryParams('/'); - const { sortDirection, sortField, pagination: paginationQuery } = query; - - let pagination: EntityPagination | undefined = {}; - const inventoryRoute = useInventoryRouter(); - try { - pagination = paginationDecoder(paginationQuery); - } catch (error) { - inventoryRoute.push('/', { - path: {}, - query: { - ...query, - pagination: undefined, - }, - }); - window.location.reload(); - } - - const pageIndex = pagination?.unified ?? 0; - - const { - value = { entities: [] }, - loading, - refresh, - } = useInventoryAbortableAsync( - ({ signal }) => { - if (isControlPanelsInitiated) { - return inventoryAPIClient.fetch('GET /internal/inventory/entities', { - params: { - query: { - sortDirection, - sortField, - esQuery: stringifiedEsQuery, - }, - }, - signal, - }); - } - }, - [inventoryAPIClient, sortDirection, sortField, isControlPanelsInitiated, stringifiedEsQuery] - ); - - useEffectOnce(() => { - const refreshSubscription = refreshSubject$.subscribe(refresh); - return () => refreshSubscription.unsubscribe(); - }); - - function handlePageChange(nextPage: number) { - inventoryRoute.push('/', { - path: {}, - query: { - ...query, - pagination: entityPaginationRt.encode({ - ...pagination, - unified: nextPage, - }), - }, - }); - } - - function handleSortChange(sorting: EuiDataGridSorting['columns'][0]) { - inventoryRoute.push('/', { - path: {}, - query: { - ...query, - sortField: sorting.id as EntityColumnIds, - sortDirection: sorting.direction, - }, - }); - } - - return ( - <> - - - - ); -} diff --git a/x-pack/plugins/observability_solution/inventory/public/hooks/use_detail_view_redirect.test.ts b/x-pack/plugins/observability_solution/inventory/public/hooks/use_detail_view_redirect.test.ts index c5b35b521b3bc..f05cdcf21cb2e 100644 --- a/x-pack/plugins/observability_solution/inventory/public/hooks/use_detail_view_redirect.test.ts +++ b/x-pack/plugins/observability_solution/inventory/public/hooks/use_detail_view_redirect.test.ts @@ -129,7 +129,6 @@ describe('useDetailViewRedirect', () => { expect(url).toBe('service-overview-url'); expect(mockGetRedirectUrl).toHaveBeenCalledWith({ serviceName: 'service-1', - environment: 'prod', }); }); diff --git a/x-pack/plugins/observability_solution/inventory/public/hooks/use_detail_view_redirect.ts b/x-pack/plugins/observability_solution/inventory/public/hooks/use_detail_view_redirect.ts index 02a77b8f2afa1..ec193ae9dfcad 100644 --- a/x-pack/plugins/observability_solution/inventory/public/hooks/use_detail_view_redirect.ts +++ b/x-pack/plugins/observability_solution/inventory/public/hooks/use_detail_view_redirect.ts @@ -65,9 +65,6 @@ export const useDetailViewRedirect = () => { if (isBuiltinEntityOfType('service', entity)) { return serviceOverviewLocator?.getRedirectUrl({ serviceName: identityFieldsValue[identityFields[0]], - environment: entity.service?.environment - ? castArray(entity.service?.environment)[0] - : undefined, }); } diff --git a/x-pack/plugins/observability_solution/inventory/public/hooks/use_discover_redirect.ts b/x-pack/plugins/observability_solution/inventory/public/hooks/use_discover_redirect.ts index 406dd44b505f4..dc9f5bf4a4740 100644 --- a/x-pack/plugins/observability_solution/inventory/public/hooks/use_discover_redirect.ts +++ b/x-pack/plugins/observability_solution/inventory/public/hooks/use_discover_redirect.ts @@ -6,9 +6,9 @@ */ import { useCallback, useMemo } from 'react'; import type { InventoryEntity } from '../../common/entities'; -import { useKibana } from './use_kibana'; -import { useFetchEntityDefinition } from './use_fetch_entity_definition'; import { useAdHocDataView } from './use_adhoc_data_view'; +import { useFetchEntityDefinition } from './use_fetch_entity_definition'; +import { useKibana } from './use_kibana'; export const useDiscoverRedirect = (entity: InventoryEntity) => { const { diff --git a/x-pack/plugins/observability_solution/inventory/public/hooks/use_inventory_decoded_query_params.ts b/x-pack/plugins/observability_solution/inventory/public/hooks/use_inventory_decoded_query_params.ts new file mode 100644 index 0000000000000..c02a33a8c06f7 --- /dev/null +++ b/x-pack/plugins/observability_solution/inventory/public/hooks/use_inventory_decoded_query_params.ts @@ -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 { decodeOrThrow } from '@kbn/io-ts-utils'; +import { useCallback, useMemo } from 'react'; +import { + entityPaginationRt, + entityTypesRt, + type EntityPagination, + type EntityType, +} from '../../common/rt_types'; +import { useInventoryParams } from './use_inventory_params'; +import { useInventoryRouter } from './use_inventory_router'; + +const entityTypeDecoder = decodeOrThrow(entityTypesRt); +const paginationDecoder = decodeOrThrow(entityPaginationRt); + +export function useInventoryDecodedQueryParams() { + const inventoryRoute = useInventoryRouter(); + const { + query, + query: { entityTypes, pagination }, + } = useInventoryParams('/*'); + + const resetUrlParam = useCallback( + (queryParamName: string) => { + inventoryRoute.push('/', { + path: {}, + query: { + ...query, + [queryParamName]: undefined, + }, + }); + }, + [inventoryRoute, query] + ); + + const selectedEntityTypes: EntityType = useMemo(() => { + try { + return entityTypeDecoder(entityTypes) || {}; + } catch (e) { + resetUrlParam('entityTypes'); + return {}; + } + }, [entityTypes, resetUrlParam]); + + const selectedPagination: EntityPagination = useMemo(() => { + try { + return paginationDecoder(pagination) || {}; + } catch (error) { + resetUrlParam('pagination'); + return {}; + } + }, [pagination, resetUrlParam]); + + return { entityTypes: selectedEntityTypes, pagination: selectedPagination }; +} diff --git a/x-pack/plugins/observability_solution/inventory/public/hooks/use_unified_search_context.ts b/x-pack/plugins/observability_solution/inventory/public/hooks/use_unified_search_context.ts index 3c520867540c9..c5715fb1d50b6 100644 --- a/x-pack/plugins/observability_solution/inventory/public/hooks/use_unified_search_context.ts +++ b/x-pack/plugins/observability_solution/inventory/public/hooks/use_unified_search_context.ts @@ -4,162 +4,19 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { buildEsQuery, type Filter, fromKueryExpression, type Query } from '@kbn/es-query'; import createContainer from 'constate'; -import { useCallback, useEffect, useMemo, useState } from 'react'; -import { map, Subject, Subscription, tap } from 'rxjs'; -import { generateFilters } from '@kbn/data-plugin/public'; -import useEffectOnce from 'react-use/lib/useEffectOnce'; -import deepEqual from 'fast-deep-equal'; -import { i18n } from '@kbn/i18n'; -import { useKibanaQuerySettings } from '@kbn/observability-shared-plugin/public'; +import { useState } from 'react'; +import { Subject } from 'rxjs'; import { ENTITIES_LATEST_ALIAS } from '../../common/entities'; import { useAdHocDataView } from './use_adhoc_data_view'; -import { useUnifiedSearchUrl } from './use_unified_search_url'; -import { useKibana } from './use_kibana'; function useUnifiedSearch() { - const [isControlPanelsInitiated, setIsControlPanelsInitiated] = useState(false); const { dataView } = useAdHocDataView(ENTITIES_LATEST_ALIAS); const [refreshSubject$] = useState>(new Subject()); - const { searchState, setSearchState } = useUnifiedSearchUrl(); - const kibanaQuerySettings = useKibanaQuerySettings(); - const { - services: { - data: { - query: { filterManager: filterManagerService, queryString: queryStringService }, - }, - notifications, - }, - } = useKibana(); - - useEffectOnce(() => { - if (!deepEqual(filterManagerService.getFilters(), searchState.filters)) { - filterManagerService.setFilters( - searchState.filters.map((item) => ({ - ...item, - meta: { ...item.meta, index: dataView?.id }, - })) - ); - } - - if (!deepEqual(queryStringService.getQuery(), searchState.query)) { - queryStringService.setQuery(searchState.query); - } - }); - - useEffect(() => { - const subscription = new Subscription(); - subscription.add( - filterManagerService - .getUpdates$() - .pipe( - map(() => filterManagerService.getFilters()), - tap((filters) => setSearchState({ type: 'SET_FILTERS', filters })) - ) - .subscribe() - ); - - subscription.add( - queryStringService - .getUpdates$() - .pipe( - map(() => queryStringService.getQuery() as Query), - tap((query) => setSearchState({ type: 'SET_QUERY', query })) - ) - .subscribe() - ); - - return () => { - subscription.unsubscribe(); - }; - }, [filterManagerService, queryStringService, setSearchState]); - - const validateQuery = useCallback( - (query: Query) => { - fromKueryExpression(query.query, kibanaQuerySettings); - }, - [kibanaQuerySettings] - ); - - const onQueryChange = useCallback( - (query: Query) => { - try { - validateQuery(query); - setSearchState({ type: 'SET_QUERY', query }); - } catch (e) { - const err = e as Error; - notifications.toasts.addDanger({ - title: i18n.translate('xpack.inventory.unifiedSearchContext.queryError', { - defaultMessage: 'Error while updating the new query', - }), - text: err.message, - }); - } - }, - [validateQuery, setSearchState, notifications.toasts] - ); - - const onPanelFiltersChange = useCallback( - (panelFilters: Filter[]) => { - setSearchState({ type: 'SET_PANEL_FILTERS', panelFilters }); - }, - [setSearchState] - ); - - const onFiltersChange = useCallback( - (filters: Filter[]) => { - setSearchState({ type: 'SET_FILTERS', filters }); - }, - [setSearchState] - ); - - const addFilter = useCallback( - ({ - fieldName, - operation, - value, - }: { - fieldName: string; - value: string; - operation: '+' | '-'; - }) => { - if (dataView) { - const newFilters = generateFilters( - filterManagerService, - fieldName, - value, - operation, - dataView - ); - setSearchState({ type: 'SET_FILTERS', filters: [...newFilters, ...searchState.filters] }); - } - }, - [dataView, filterManagerService, searchState.filters, setSearchState] - ); - - const stringifiedEsQuery = useMemo(() => { - if (dataView) { - return JSON.stringify( - buildEsQuery(dataView, searchState.query, [ - ...searchState.panelFilters, - ...searchState.filters, - ]) - ); - } - }, [dataView, searchState.panelFilters, searchState.filters, searchState.query]); return { - isControlPanelsInitiated, - setIsControlPanelsInitiated, dataView, refreshSubject$, - searchState, - addFilter, - stringifiedEsQuery, - onQueryChange, - onPanelFiltersChange, - onFiltersChange, }; } diff --git a/x-pack/plugins/observability_solution/inventory/public/hooks/use_unified_search_url.ts b/x-pack/plugins/observability_solution/inventory/public/hooks/use_unified_search_url.ts deleted file mode 100644 index 17cf0ef0d9597..0000000000000 --- a/x-pack/plugins/observability_solution/inventory/public/hooks/use_unified_search_url.ts +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ -import { FilterStateStore } from '@kbn/es-query'; -import { useUrlState } from '@kbn/observability-shared-plugin/public'; -import { enumeration } from '@kbn/securitysolution-io-ts-types'; -import { fold } from 'fp-ts/lib/Either'; -import { constant, identity } from 'fp-ts/lib/function'; -import { pipe } from 'fp-ts/lib/pipeable'; -import * as t from 'io-ts'; -import { useReducer } from 'react'; -import deepEqual from 'fast-deep-equal'; - -const FilterRT = t.intersection([ - t.type({ - meta: t.partial({ - alias: t.union([t.null, t.string]), - disabled: t.boolean, - negate: t.boolean, - controlledBy: t.string, - group: t.string, - index: t.string, - isMultiIndex: t.boolean, - type: t.string, - key: t.string, - params: t.any, - value: t.any, - }), - }), - t.partial({ - query: t.record(t.string, t.any), - $state: t.type({ - store: enumeration('FilterStateStore', FilterStateStore), - }), - }), -]); -const FiltersRT = t.array(FilterRT); - -const QueryStateRT = t.type({ - language: t.string, - query: t.union([t.string, t.record(t.string, t.any)]), -}); - -const SearchStateRT = t.type({ - panelFilters: FiltersRT, - filters: FiltersRT, - query: QueryStateRT, -}); - -const encodeUrlState = SearchStateRT.encode; -const decodeUrlState = (value: unknown) => { - return pipe(SearchStateRT.decode(value), fold(constant(undefined), identity)); -}; - -type SearchState = t.TypeOf; - -const INITIAL_VALUE: SearchState = { - query: { language: 'kuery', query: '' }, - panelFilters: [], - filters: [], -}; - -export type StateAction = - | { type: 'SET_FILTERS'; filters: SearchState['filters'] } - | { type: 'SET_QUERY'; query: SearchState['query'] } - | { type: 'SET_PANEL_FILTERS'; panelFilters: SearchState['panelFilters'] }; - -const reducer = (state: SearchState, action: StateAction): SearchState => { - switch (action.type) { - case 'SET_FILTERS': - return { ...state, filters: action.filters }; - case 'SET_QUERY': - return { ...state, query: action.query }; - case 'SET_PANEL_FILTERS': - return { ...state, panelFilters: action.panelFilters }; - default: - return state; - } -}; - -export function useUnifiedSearchUrl() { - const [urlState, setUrlState] = useUrlState({ - defaultState: INITIAL_VALUE, - decodeUrlState, - encodeUrlState, - urlStateKey: '_a', - writeDefaultState: true, - }); - - const [searchState, setSearchState] = useReducer(reducer, urlState); - - if (!deepEqual(searchState, urlState)) { - setUrlState(searchState); - } - - return { searchState, setSearchState }; -} diff --git a/x-pack/plugins/observability_solution/inventory/public/pages/inventory_page/index.tsx b/x-pack/plugins/observability_solution/inventory/public/pages/inventory_page/index.tsx index f34df1a3c8b32..6eab905a40692 100644 --- a/x-pack/plugins/observability_solution/inventory/public/pages/inventory_page/index.tsx +++ b/x-pack/plugins/observability_solution/inventory/public/pages/inventory_page/index.tsx @@ -4,12 +4,83 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ +import { EuiFlexGroup, EuiFlexItem, EuiSpacer } from '@elastic/eui'; +import { ENTITY_TYPE } from '@kbn/observability-shared-plugin/common'; +import { flattenObject } from '@kbn/observability-utils-common/object/flatten_object'; import React from 'react'; -import { GroupedInventory } from '../../components/grouped_inventory'; -import { UnifiedInventory } from '../../components/unified_inventory'; +import useEffectOnce from 'react-use/lib/useEffectOnce'; +import { EntitiesSummary } from '../../components/entities_summary'; +import { EntityGroupAccordion } from '../../components/entity_group_accordion'; +import { useInventoryAbortableAsync } from '../../hooks/use_inventory_abortable_async'; +import { useInventoryDecodedQueryParams } from '../../hooks/use_inventory_decoded_query_params'; import { useInventoryParams } from '../../hooks/use_inventory_params'; +import { useKibana } from '../../hooks/use_kibana'; +import { useUnifiedSearchContext } from '../../hooks/use_unified_search_context'; +import { GroupBySelector } from '../../components/group_by_selector'; +import { groupEntityTypesByStatus } from '../../utils/group_entity_types_by_status'; export function InventoryPage() { - const { query } = useInventoryParams('/'); - return query.view === 'unified' ? : ; + const { + services: { inventoryAPIClient }, + } = useKibana(); + const { refreshSubject$ } = useUnifiedSearchContext(); + const { + query: { kuery }, + } = useInventoryParams('/'); + const { entityTypes } = useInventoryDecodedQueryParams(); + + const { + value = { groupBy: ENTITY_TYPE, groups: [], entitiesCount: 0 }, + refresh, + loading, + } = useInventoryAbortableAsync( + ({ signal }) => { + const { entityTypesOff, entityTypesOn } = groupEntityTypesByStatus(entityTypes); + return inventoryAPIClient.fetch('GET /internal/inventory/entities/group_by/{field}', { + params: { + path: { + field: ENTITY_TYPE, + }, + query: { + includeEntityTypes: entityTypesOn.length ? JSON.stringify(entityTypesOn) : undefined, + excludeEntityTypes: entityTypesOff.length ? JSON.stringify(entityTypesOff) : undefined, + kuery, + }, + }, + signal, + }); + }, + [entityTypes, inventoryAPIClient, kuery] + ); + + useEffectOnce(() => { + const refreshSubscription = refreshSubject$.subscribe(refresh); + return () => refreshSubscription.unsubscribe(); + }); + + return ( + <> + + + + + + + + + + {value.groups.map((group) => { + const groupValue = flattenObject(group)[value.groupBy]; + return ( + + ); + })} + + ); } diff --git a/x-pack/plugins/observability_solution/inventory/public/routes/config.tsx b/x-pack/plugins/observability_solution/inventory/public/routes/config.tsx index bf5f8324aab25..32db48130a89c 100644 --- a/x-pack/plugins/observability_solution/inventory/public/routes/config.tsx +++ b/x-pack/plugins/observability_solution/inventory/public/routes/config.tsx @@ -7,9 +7,9 @@ import { Outlet, createRouter } from '@kbn/typed-react-router-config'; import * as t from 'io-ts'; import React from 'react'; +import { defaultEntitySortField, entityColumnIdsRt } from '../../common/entities'; import { InventoryPageTemplate } from '../components/inventory_page_template'; import { InventoryPage } from '../pages/inventory_page'; -import { defaultEntitySortField, entityColumnIdsRt, entityViewRt } from '../../common/entities'; /** * The array of route definitions to be used when the application @@ -29,10 +29,9 @@ const inventoryRoutes = { sortDirection: t.union([t.literal('asc'), t.literal('desc')]), }), t.partial({ - view: entityViewRt, pagination: t.string, - _a: t.string, - controlPanels: t.string, + entityTypes: t.string, + kuery: t.string, }), ]), }), @@ -40,7 +39,6 @@ const inventoryRoutes = { query: { sortField: defaultEntitySortField, sortDirection: 'desc', - view: 'grouped', }, }, children: { diff --git a/x-pack/plugins/observability_solution/inventory/public/services/telemetry/telemetry_client.ts b/x-pack/plugins/observability_solution/inventory/public/services/telemetry/telemetry_client.ts index c4c238fba5f8f..d7806c2f6cb2e 100644 --- a/x-pack/plugins/observability_solution/inventory/public/services/telemetry/telemetry_client.ts +++ b/x-pack/plugins/observability_solution/inventory/public/services/telemetry/telemetry_client.ts @@ -14,6 +14,7 @@ import { type EntityInventoryViewedParams, type EntityInventorySearchQuerySubmittedParams, type EntityViewClickedParams, + type EntityInventoryEntityTypeFilteredParams, } from './types'; export class TelemetryClient implements ITelemetryClient { @@ -36,4 +37,10 @@ export class TelemetryClient implements ITelemetryClient { public reportEntityViewClicked = (params: EntityViewClickedParams) => { this.analytics.reportEvent(TelemetryEventTypes.ENTITY_VIEW_CLICKED, params); }; + + public reportEntityInventoryEntityTypeFiltered = ( + params: EntityInventoryEntityTypeFilteredParams + ) => { + this.analytics.reportEvent(TelemetryEventTypes.ENTITY_INVENTORY_ENTITY_TYPE_FILTERED, params); + }; } diff --git a/x-pack/plugins/observability_solution/inventory/public/services/telemetry/telemetry_events.ts b/x-pack/plugins/observability_solution/inventory/public/services/telemetry/telemetry_events.ts index ec2623fe2a2cc..707852f9f3cd6 100644 --- a/x-pack/plugins/observability_solution/inventory/public/services/telemetry/telemetry_events.ts +++ b/x-pack/plugins/observability_solution/inventory/public/services/telemetry/telemetry_events.ts @@ -58,6 +58,30 @@ const searchQuerySubmittedEventType: TelemetryEvent = { }, }; +const entityInventoryEntityTypeFilteredEventType: TelemetryEvent = { + eventType: TelemetryEventTypes.ENTITY_INVENTORY_ENTITY_TYPE_FILTERED, + schema: { + include_entity_types: { + type: 'array', + items: { + type: 'keyword', + _meta: { + description: 'List of Entity types used to filter for.', + }, + }, + }, + exclude_entity_types: { + type: 'array', + items: { + type: 'keyword', + _meta: { + description: 'List of Entity types used to filter out.', + }, + }, + }, + }, +}; + const entityViewClickedEventType: TelemetryEvent = { eventType: TelemetryEventTypes.ENTITY_VIEW_CLICKED, schema: { @@ -81,4 +105,5 @@ export const inventoryTelemetryEventBasedTypes = [ entityInventoryViewedEventType, searchQuerySubmittedEventType, entityViewClickedEventType, + entityInventoryEntityTypeFilteredEventType, ]; diff --git a/x-pack/plugins/observability_solution/inventory/public/services/telemetry/telemetry_service.test.ts b/x-pack/plugins/observability_solution/inventory/public/services/telemetry/telemetry_service.test.ts index 639b771788f5b..6a4854f754831 100644 --- a/x-pack/plugins/observability_solution/inventory/public/services/telemetry/telemetry_service.test.ts +++ b/x-pack/plugins/observability_solution/inventory/public/services/telemetry/telemetry_service.test.ts @@ -13,6 +13,7 @@ import { type EntityViewClickedParams, type EntityInventorySearchQuerySubmittedParams, TelemetryEventTypes, + EntityInventoryEntityTypeFilteredParams, } from './types'; describe('TelemetryService', () => { @@ -145,4 +146,24 @@ describe('TelemetryService', () => { ); }); }); + + describe('#reportEntityInventoryEntityTypeFiltered', () => { + it('should report entity type filtered with properties', async () => { + const setupParams = getSetupParams(); + service.setup(setupParams); + const telemetry = service.start(); + const params: EntityInventoryEntityTypeFilteredParams = { + include_entity_types: ['container'], + exclude_entity_types: ['service'], + }; + + telemetry.reportEntityInventoryEntityTypeFiltered(params); + + expect(setupParams.analytics.reportEvent).toHaveBeenCalledTimes(1); + expect(setupParams.analytics.reportEvent).toHaveBeenCalledWith( + TelemetryEventTypes.ENTITY_INVENTORY_ENTITY_TYPE_FILTERED, + params + ); + }); + }); }); diff --git a/x-pack/plugins/observability_solution/inventory/public/services/telemetry/types.ts b/x-pack/plugins/observability_solution/inventory/public/services/telemetry/types.ts index 0d56f44c2c2f2..e8ce3eb94e9ba 100644 --- a/x-pack/plugins/observability_solution/inventory/public/services/telemetry/types.ts +++ b/x-pack/plugins/observability_solution/inventory/public/services/telemetry/types.ts @@ -30,6 +30,11 @@ export interface EntityInventorySearchQuerySubmittedParams { action: 'submit' | 'refresh'; } +export interface EntityInventoryEntityTypeFilteredParams { + include_entity_types: string[]; + exclude_entity_types: string[]; +} + export interface EntityViewClickedParams { entity_type: string; view_type: 'detail' | 'flyout'; @@ -39,7 +44,8 @@ export type TelemetryEventParams = | InventoryAddDataParams | EntityInventoryViewedParams | EntityInventorySearchQuerySubmittedParams - | EntityViewClickedParams; + | EntityViewClickedParams + | EntityInventoryEntityTypeFilteredParams; export interface ITelemetryClient { reportInventoryAddData(params: InventoryAddDataParams): void; @@ -48,6 +54,7 @@ export interface ITelemetryClient { params: EntityInventorySearchQuerySubmittedParams ): void; reportEntityViewClicked(params: EntityViewClickedParams): void; + reportEntityInventoryEntityTypeFiltered(params: EntityInventoryEntityTypeFilteredParams): void; } export enum TelemetryEventTypes { diff --git a/x-pack/plugins/observability_solution/inventory/public/utils/group_entity_types_by_status.ts b/x-pack/plugins/observability_solution/inventory/public/utils/group_entity_types_by_status.ts new file mode 100644 index 0000000000000..f842663dd56e9 --- /dev/null +++ b/x-pack/plugins/observability_solution/inventory/public/utils/group_entity_types_by_status.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 { EntityType } from '../../common/rt_types'; + +export function groupEntityTypesByStatus(entityTypes: EntityType) { + const entityTypesKeys = Object.keys(entityTypes); + return { + entityTypesOn: entityTypesKeys.filter((key) => entityTypes[key] === 'on').sort(), + entityTypesOff: entityTypesKeys.filter((key) => entityTypes[key] === 'off').sort(), + }; +} diff --git a/x-pack/plugins/observability_solution/inventory/server/lib/create_alerts_client.ts/create_alerts_client.ts b/x-pack/plugins/observability_solution/inventory/server/lib/create_alerts_client/create_alerts_client.ts similarity index 93% rename from x-pack/plugins/observability_solution/inventory/server/lib/create_alerts_client.ts/create_alerts_client.ts rename to x-pack/plugins/observability_solution/inventory/server/lib/create_alerts_client/create_alerts_client.ts index 150e946fd98d6..878abd516e5bd 100644 --- a/x-pack/plugins/observability_solution/inventory/server/lib/create_alerts_client.ts/create_alerts_client.ts +++ b/x-pack/plugins/observability_solution/inventory/server/lib/create_alerts_client/create_alerts_client.ts @@ -8,6 +8,7 @@ import { isEmpty } from 'lodash'; import { ESSearchRequest, InferSearchResponseOf } from '@kbn/es-types'; import { ParsedTechnicalFields } from '@kbn/rule-registry-plugin/common'; +import { OBSERVABILITY_RULE_TYPE_IDS } from '@kbn/rule-data-utils'; import { InventoryRouteHandlerResources } from '../../routes/types'; export type AlertsClient = Awaited>; @@ -18,13 +19,7 @@ export async function createAlertsClient({ }: Pick) { const ruleRegistryPluginStart = await plugins.ruleRegistry.start(); const alertsClient = await ruleRegistryPluginStart.getRacClientWithRequest(request); - const alertsIndices = await alertsClient.getAuthorizedAlertsIndices([ - 'logs', - 'infrastructure', - 'apm', - 'slo', - 'observability', - ]); + const alertsIndices = await alertsClient.getAuthorizedAlertsIndices(OBSERVABILITY_RULE_TYPE_IDS); if (!alertsIndices || isEmpty(alertsIndices)) { throw Error('No alert indices exist'); diff --git a/x-pack/plugins/observability_solution/inventory/server/routes/entities/get_entity_groups.ts b/x-pack/plugins/observability_solution/inventory/server/routes/entities/get_entity_groups.ts index 816b3c6af6ec2..ead3109060d13 100644 --- a/x-pack/plugins/observability_solution/inventory/server/routes/entities/get_entity_groups.ts +++ b/x-pack/plugins/observability_solution/inventory/server/routes/entities/get_entity_groups.ts @@ -5,26 +5,43 @@ * 2.0. */ -import type { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/types'; +import type { ScalarValue } from '@elastic/elasticsearch/lib/api/types'; +import { kqlQuery } from '@kbn/observability-plugin/server'; +import { ENTITY_TYPE } from '@kbn/observability-shared-plugin/common'; import type { ObservabilityElasticsearchClient } from '@kbn/observability-utils-server/es/client/create_observability_es_client'; import { ENTITIES_LATEST_ALIAS, - type EntityGroup, MAX_NUMBER_OF_ENTITIES, + type EntityGroup, } from '../../../common/entities'; import { getBuiltinEntityDefinitionIdESQLWhereClause } from './query_helper'; export async function getEntityGroupsBy({ inventoryEsClient, field, - esQuery, + kuery, + includeEntityTypes = [], + excludeEntityTypes = [], }: { inventoryEsClient: ObservabilityElasticsearchClient; field: string; - esQuery?: QueryDslQueryContainer; + includeEntityTypes?: string[]; + excludeEntityTypes?: string[]; + kuery?: string; }): Promise { const from = `FROM ${ENTITIES_LATEST_ALIAS}`; const where = [getBuiltinEntityDefinitionIdESQLWhereClause()]; + const params: ScalarValue[] = []; + + if (includeEntityTypes.length) { + where.push(`WHERE ${ENTITY_TYPE} IN (${includeEntityTypes.map(() => '?').join()})`); + params.push(...includeEntityTypes); + } + + if (excludeEntityTypes.length) { + where.push(`WHERE ${ENTITY_TYPE} NOT IN (${excludeEntityTypes.map(() => '?').join()})`); + params.push(...excludeEntityTypes); + } const group = `STATS count = COUNT(*) by ${field}`; const sort = `SORT ${field} asc`; @@ -35,7 +52,8 @@ export async function getEntityGroupsBy({ 'get_entities_groups', { query, - filter: esQuery, + filter: { bool: { filter: kqlQuery(kuery) } }, + params, }, { transform: 'plain' } ); diff --git a/x-pack/plugins/observability_solution/inventory/server/routes/entities/get_latest_entities.ts b/x-pack/plugins/observability_solution/inventory/server/routes/entities/get_latest_entities.ts index 9dcf17250ad68..83f576220d12a 100644 --- a/x-pack/plugins/observability_solution/inventory/server/routes/entities/get_latest_entities.ts +++ b/x-pack/plugins/observability_solution/inventory/server/routes/entities/get_latest_entities.ts @@ -5,19 +5,20 @@ * 2.0. */ -import type { QueryDslQueryContainer, ScalarValue } from '@elastic/elasticsearch/lib/api/types'; +import type { ScalarValue } from '@elastic/elasticsearch/lib/api/types'; +import { kqlQuery } from '@kbn/observability-plugin/server'; import { ENTITY_DISPLAY_NAME, ENTITY_LAST_SEEN, ENTITY_TYPE, } from '@kbn/observability-shared-plugin/common'; -import type { ObservabilityElasticsearchClient } from '@kbn/observability-utils-server/es/client/create_observability_es_client'; import { unflattenObject } from '@kbn/observability-utils-common/object/unflatten_object'; +import type { ObservabilityElasticsearchClient } from '@kbn/observability-utils-server/es/client/create_observability_es_client'; import { ENTITIES_LATEST_ALIAS, - InventoryEntity, MAX_NUMBER_OF_ENTITIES, type EntityColumnIds, + type InventoryEntity, } from '../../../common/entities'; import { getBuiltinEntityDefinitionIdESQLWhereClause } from './query_helper'; @@ -35,13 +36,13 @@ export async function getLatestEntities({ inventoryEsClient, sortDirection, sortField, - esQuery, + kuery, entityTypes, }: { inventoryEsClient: ObservabilityElasticsearchClient; sortDirection: 'asc' | 'desc'; sortField: EntityColumnIds; - esQuery?: QueryDslQueryContainer; + kuery?: string; entityTypes?: string[]; }): Promise { // alertsCount doesn't exist in entities index. Ignore it and sort by entity.lastSeenTimestamp by default. @@ -78,7 +79,7 @@ export async function getLatestEntities({ 'get_latest_entities', { query, - filter: esQuery, + filter: { bool: { filter: kqlQuery(kuery) } }, params, }, { transform: 'plain' } diff --git a/x-pack/plugins/observability_solution/inventory/server/routes/entities/get_latest_entities_alerts.ts b/x-pack/plugins/observability_solution/inventory/server/routes/entities/get_latest_entities_alerts.ts index 0f1ace0407233..d4c69505a4637 100644 --- a/x-pack/plugins/observability_solution/inventory/server/routes/entities/get_latest_entities_alerts.ts +++ b/x-pack/plugins/observability_solution/inventory/server/routes/entities/get_latest_entities_alerts.ts @@ -7,7 +7,7 @@ import { termQuery } from '@kbn/observability-plugin/server'; import { ALERT_STATUS, ALERT_STATUS_ACTIVE } from '@kbn/rule-data-utils'; -import { AlertsClient } from '../../lib/create_alerts_client.ts/create_alerts_client'; +import { AlertsClient } from '../../lib/create_alerts_client/create_alerts_client'; import { getGroupByTermsAgg } from './get_group_by_terms_agg'; import { IdentityFieldsPerEntityType } from './get_identity_fields_per_entity_type'; diff --git a/x-pack/plugins/observability_solution/inventory/server/routes/entities/route.ts b/x-pack/plugins/observability_solution/inventory/server/routes/entities/route.ts index 992729a9c1aa0..c4a0a21f50eb2 100644 --- a/x-pack/plugins/observability_solution/inventory/server/routes/entities/route.ts +++ b/x-pack/plugins/observability_solution/inventory/server/routes/entities/route.ts @@ -12,7 +12,7 @@ import { createObservabilityEsClient } from '@kbn/observability-utils-server/es/ import * as t from 'io-ts'; import { orderBy } from 'lodash'; import { InventoryEntity, entityColumnIdsRt } from '../../../common/entities'; -import { createAlertsClient } from '../../lib/create_alerts_client.ts/create_alerts_client'; +import { createAlertsClient } from '../../lib/create_alerts_client/create_alerts_client'; import { createInventoryServerRoute } from '../create_inventory_server_route'; import { getEntityGroupsBy } from './get_entity_groups'; import { getEntityTypes } from './get_entity_types'; @@ -47,7 +47,7 @@ export const listLatestEntitiesRoute = createInventoryServerRoute({ sortDirection: t.union([t.literal('asc'), t.literal('desc')]), }), t.partial({ - esQuery: jsonRt.pipe(t.UnknownRecord), + kuery: t.string, entityTypes: jsonRt.pipe(t.array(t.string)), }), ]), @@ -69,7 +69,7 @@ export const listLatestEntitiesRoute = createInventoryServerRoute({ plugin: `@kbn/${INVENTORY_APP_ID}-plugin`, }); - const { sortDirection, sortField, esQuery, entityTypes } = params.query; + const { sortDirection, sortField, kuery, entityTypes } = params.query; const [alertsClient, latestEntities] = await Promise.all([ createAlertsClient({ plugins, request }), @@ -77,7 +77,7 @@ export const listLatestEntitiesRoute = createInventoryServerRoute({ inventoryEsClient, sortDirection, sortField, - esQuery, + kuery, entityTypes, }), ]); @@ -113,7 +113,9 @@ export const groupEntitiesByRoute = createInventoryServerRoute({ t.type({ path: t.type({ field: t.literal(ENTITY_TYPE) }) }), t.partial({ query: t.partial({ - esQuery: jsonRt.pipe(t.UnknownRecord), + includeEntityTypes: jsonRt.pipe(t.array(t.string)), + excludeEntityTypes: jsonRt.pipe(t.array(t.string)), + kuery: t.string, }), }), ]), @@ -129,12 +131,14 @@ export const groupEntitiesByRoute = createInventoryServerRoute({ }); const { field } = params.path; - const { esQuery } = params.query ?? {}; + const { kuery, includeEntityTypes, excludeEntityTypes } = params.query ?? {}; const groups = await getEntityGroupsBy({ inventoryEsClient, field, - esQuery, + kuery, + includeEntityTypes, + excludeEntityTypes, }); const entitiesCount = groups.reduce((acc, group) => acc + group.count, 0); diff --git a/x-pack/plugins/observability_solution/inventory/tsconfig.json b/x-pack/plugins/observability_solution/inventory/tsconfig.json index b276c3e7e28b1..561ca62eaf97e 100644 --- a/x-pack/plugins/observability_solution/inventory/tsconfig.json +++ b/x-pack/plugins/observability_solution/inventory/tsconfig.json @@ -54,8 +54,6 @@ "@kbn/storybook", "@kbn/dashboard-plugin", "@kbn/deeplinks-analytics", - "@kbn/controls-plugin", - "@kbn/securitysolution-io-ts-types", "@kbn/react-hooks", "@kbn/observability-utils-common", "@kbn/observability-utils-browser", diff --git a/x-pack/plugins/observability_solution/investigate_app/server/services/get_alerts_client.ts b/x-pack/plugins/observability_solution/investigate_app/server/services/get_alerts_client.ts index bf1070307742a..c5eaf3f4c3d8e 100644 --- a/x-pack/plugins/observability_solution/investigate_app/server/services/get_alerts_client.ts +++ b/x-pack/plugins/observability_solution/investigate_app/server/services/get_alerts_client.ts @@ -8,6 +8,7 @@ import { isEmpty } from 'lodash'; import { ESSearchRequest, InferSearchResponseOf } from '@kbn/es-types'; import { ParsedTechnicalFields } from '@kbn/rule-registry-plugin/common'; +import { OBSERVABILITY_RULE_TYPE_IDS } from '@kbn/rule-data-utils'; import { InvestigateAppRouteHandlerResources } from '../routes/types'; export type AlertsClient = Awaited>; @@ -18,14 +19,7 @@ export async function getAlertsClient({ }: Pick) { const ruleRegistryPluginStart = await plugins.ruleRegistry.start(); const alertsClient = await ruleRegistryPluginStart.getRacClientWithRequest(request); - const alertsIndices = await alertsClient.getAuthorizedAlertsIndices([ - 'logs', - 'infrastructure', - 'apm', - 'slo', - 'uptime', - 'observability', - ]); + const alertsIndices = await alertsClient.getAuthorizedAlertsIndices(OBSERVABILITY_RULE_TYPE_IDS); if (!alertsIndices || isEmpty(alertsIndices)) { throw Error('No alert indices exist'); diff --git a/x-pack/plugins/observability_solution/logs_data_access/kibana.jsonc b/x-pack/plugins/observability_solution/logs_data_access/kibana.jsonc index ee8881a4479e7..02fcff85404a0 100644 --- a/x-pack/plugins/observability_solution/logs_data_access/kibana.jsonc +++ b/x-pack/plugins/observability_solution/logs_data_access/kibana.jsonc @@ -1,7 +1,7 @@ { "type": "plugin", "id": "@kbn/logs-data-access-plugin", - "owner": ["@elastic/obs-knowledge-team", "@elastic/obs-ux-logs-team"], + "owner": ["@elastic/obs-ux-logs-team"], "plugin": { "id": "logsDataAccess", "server": true, diff --git a/x-pack/plugins/observability_solution/logs_data_access/public/services/log_sources_service/index.ts b/x-pack/plugins/observability_solution/logs_data_access/public/services/log_sources_service/index.ts index f329907f145ef..e44b9cadcae08 100644 --- a/x-pack/plugins/observability_solution/logs_data_access/public/services/log_sources_service/index.ts +++ b/x-pack/plugins/observability_solution/logs_data_access/public/services/log_sources_service/index.ts @@ -12,23 +12,32 @@ import { RegisterServicesParams } from '../register_services'; export function createLogSourcesService(params: RegisterServicesParams): LogSourcesService { const { uiSettings } = params.deps; - return { - async getLogSources() { - const logSources = uiSettings.get(OBSERVABILITY_LOGS_DATA_ACCESS_LOG_SOURCES_ID); - return logSources.map((logSource) => ({ - indexPattern: logSource, - })); - }, - async getFlattenedLogSources() { - const logSources = await this.getLogSources(); - return flattenLogSources(logSources); - }, - async setLogSources(sources: LogSource[]) { - await uiSettings.set( - OBSERVABILITY_LOGS_DATA_ACCESS_LOG_SOURCES_ID, - sources.map((source) => source.indexPattern) - ); - return; - }, + + const getLogSources = async () => { + const logSources = uiSettings.get(OBSERVABILITY_LOGS_DATA_ACCESS_LOG_SOURCES_ID); + return logSources.map((logSource) => ({ + indexPattern: logSource, + })); + }; + + const getFlattenedLogSources = async () => { + const logSources = await getLogSources(); + return flattenLogSources(logSources); + }; + + const setLogSources = async (sources: LogSource[]) => { + await uiSettings.set( + OBSERVABILITY_LOGS_DATA_ACCESS_LOG_SOURCES_ID, + sources.map((source) => source.indexPattern) + ); + return; + }; + + const logSourcesService: LogSourcesService = { + getLogSources, + getFlattenedLogSources, + setLogSources, }; + + return logSourcesService; } diff --git a/x-pack/plugins/observability_solution/logs_shared/kibana.jsonc b/x-pack/plugins/observability_solution/logs_shared/kibana.jsonc index f5e9f76c2ace6..69539098f2463 100644 --- a/x-pack/plugins/observability_solution/logs_shared/kibana.jsonc +++ b/x-pack/plugins/observability_solution/logs_shared/kibana.jsonc @@ -18,11 +18,13 @@ "observabilityShared", "share", "usageCollection", + "embeddable", ], "optionalPlugins": [ "observabilityAIAssistant", ], - "requiredBundles": ["kibanaUtils", "kibanaReact", "unifiedDocViewer"], + "requiredBundles": ["kibanaUtils", "kibanaReact"], "extraPublicDirs": ["common"] } } + \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/logs_shared/public/plugin.tsx b/x-pack/plugins/observability_solution/logs_shared/public/plugin.tsx index 0321651607ed1..e6ec419ae8b0f 100644 --- a/x-pack/plugins/observability_solution/logs_shared/public/plugin.tsx +++ b/x-pack/plugins/observability_solution/logs_shared/public/plugin.tsx @@ -61,7 +61,6 @@ export class LogsSharedPlugin implements LogsSharedClientPluginClass { logsDataAccess, observabilityAIAssistant, share, - fieldFormats, } = plugins; const logViews = this.logViews.start({ @@ -72,14 +71,14 @@ export class LogsSharedPlugin implements LogsSharedClientPluginClass { }); const LogsOverview = createLogsOverview({ - core, charts, logsDataAccess, search: data.search.search, + searchSource: data.search.searchSource, uiSettings: settings, share, dataViews, - fieldFormats, + embeddable: plugins.embeddable, }); if (!observabilityAIAssistant) { diff --git a/x-pack/plugins/observability_solution/logs_shared/public/types.ts b/x-pack/plugins/observability_solution/logs_shared/public/types.ts index e2435fa1f4915..90bbd89f2481d 100644 --- a/x-pack/plugins/observability_solution/logs_shared/public/types.ts +++ b/x-pack/plugins/observability_solution/logs_shared/public/types.ts @@ -15,6 +15,8 @@ import type { ObservabilityAIAssistantPublicStart } from '@kbn/observability-ai- import type { SharePluginSetup, SharePluginStart } from '@kbn/share-plugin/public'; import type { UiActionsStart } from '@kbn/ui-actions-plugin/public'; import { FieldFormatsStart } from '@kbn/field-formats-plugin/public'; +import { EmbeddableStart } from '@kbn/embeddable-plugin/public'; +import { SavedSearchPublicPluginStart } from '@kbn/saved-search-plugin/public'; import type { LogsSharedLocators } from '../common/locators'; import type { LogAIAssistantProps } from './components/log_ai_assistant/log_ai_assistant'; import type { SelfContainedLogsOverview } from './components/logs_overview'; @@ -46,6 +48,8 @@ export interface LogsSharedClientStartDeps { share: SharePluginStart; uiActions: UiActionsStart; fieldFormats: FieldFormatsStart; + embeddable: EmbeddableStart; + savedSearch: SavedSearchPublicPluginStart; } export type LogsSharedClientCoreSetup = CoreSetup< diff --git a/x-pack/plugins/observability_solution/logs_shared/tsconfig.json b/x-pack/plugins/observability_solution/logs_shared/tsconfig.json index f171c79afccd0..acaed5073a176 100644 --- a/x-pack/plugins/observability_solution/logs_shared/tsconfig.json +++ b/x-pack/plugins/observability_solution/logs_shared/tsconfig.json @@ -49,5 +49,7 @@ "@kbn/charts-plugin", "@kbn/core-ui-settings-common", "@kbn/field-formats-plugin", + "@kbn/embeddable-plugin", + "@kbn/saved-search-plugin", ] } diff --git a/x-pack/plugins/observability_solution/metrics_data_access/kibana.jsonc b/x-pack/plugins/observability_solution/metrics_data_access/kibana.jsonc index 17ad2991f315d..3188d318b64cb 100644 --- a/x-pack/plugins/observability_solution/metrics_data_access/kibana.jsonc +++ b/x-pack/plugins/observability_solution/metrics_data_access/kibana.jsonc @@ -1,10 +1,7 @@ { "type": "plugin", "id": "@kbn/metrics-data-access-plugin", - "owner": [ - "@elastic/obs-knowledge-team", - "@elastic/obs-ux-infra_services-team" - ], + "owner": ["@elastic/obs-ux-infra_services-team"], "group": "observability", "visibility": "private", "description": "Exposes utilities for accessing metrics data", diff --git a/x-pack/plugins/observability_solution/metrics_data_access/server/lib/adapters/framework/adapter_types.ts b/x-pack/plugins/observability_solution/metrics_data_access/server/lib/adapters/framework/adapter_types.ts index 246988ed96307..6449fcc30b2dc 100644 --- a/x-pack/plugins/observability_solution/metrics_data_access/server/lib/adapters/framework/adapter_types.ts +++ b/x-pack/plugins/observability_solution/metrics_data_access/server/lib/adapters/framework/adapter_types.ts @@ -19,7 +19,7 @@ import { PluginStart as DataViewsPluginStart } from '@kbn/data-views-plugin/serv import { HomeServerPluginSetup } from '@kbn/home-plugin/server'; import { FeaturesPluginSetup } from '@kbn/features-plugin/server'; import { SpacesPluginSetup } from '@kbn/spaces-plugin/server'; -import { PluginSetupContract as AlertingPluginContract } from '@kbn/alerting-plugin/server'; +import type { AlertingServerSetup } from '@kbn/alerting-plugin/server'; import { MlPluginSetup } from '@kbn/ml-plugin/server'; import { RuleRegistryPluginSetupContract } from '@kbn/rule-registry-plugin/server'; import { ObservabilityPluginSetup } from '@kbn/observability-plugin/server'; @@ -27,7 +27,7 @@ import { VersionedRouteConfig } from '@kbn/core-http-server'; import { MetricsDataPluginSetup } from '../../../types'; export interface InfraServerPluginSetupDeps { - alerting: AlertingPluginContract; + alerting: AlertingServerSetup; data: DataPluginSetup; home: HomeServerPluginSetup; features: FeaturesPluginSetup; diff --git a/x-pack/plugins/observability_solution/observability/common/constants.ts b/x-pack/plugins/observability_solution/observability/common/constants.ts index 0286e4bef0825..785f1caf4cb6d 100644 --- a/x-pack/plugins/observability_solution/observability/common/constants.ts +++ b/x-pack/plugins/observability_solution/observability/common/constants.ts @@ -5,7 +5,11 @@ * 2.0. */ -import { AlertConsumers } from '@kbn/rule-data-utils'; +import { + AlertConsumers, + STACK_RULE_TYPE_IDS_SUPPORTED_BY_OBSERVABILITY, + OBSERVABILITY_RULE_TYPE_IDS, +} from '@kbn/rule-data-utils'; import type { ValidFeatureId } from '@kbn/rule-data-utils'; import type { RuleCreationValidConsumer } from '@kbn/triggers-actions-ui-plugin/public'; @@ -20,6 +24,7 @@ export const observabilityAlertFeatureIds: ValidFeatureId[] = [ AlertConsumers.UPTIME, AlertConsumers.SLO, AlertConsumers.OBSERVABILITY, + AlertConsumers.ALERTS, ]; export const observabilityRuleCreationValidConsumers: RuleCreationValidConsumer[] = [ @@ -29,3 +34,8 @@ export const observabilityRuleCreationValidConsumers: RuleCreationValidConsumer[ ]; export const EventsAsUnit = 'events'; + +export const OBSERVABILITY_RULE_TYPE_IDS_WITH_SUPPORTED_STACK_RULE_TYPES = [ + ...OBSERVABILITY_RULE_TYPE_IDS, + ...STACK_RULE_TYPE_IDS_SUPPORTED_BY_OBSERVABILITY, +]; diff --git a/x-pack/plugins/observability_solution/observability/public/components/alert_search_bar/alert_search_bar.test.tsx b/x-pack/plugins/observability_solution/observability/public/components/alert_search_bar/alert_search_bar.test.tsx index b7da84869679a..d64d8dcbb1a41 100644 --- a/x-pack/plugins/observability_solution/observability/public/components/alert_search_bar/alert_search_bar.test.tsx +++ b/x-pack/plugins/observability_solution/observability/public/components/alert_search_bar/alert_search_bar.test.tsx @@ -12,8 +12,8 @@ import { uiSettingsServiceMock } from '@kbn/core-ui-settings-browser-mocks'; import { ObservabilityAlertSearchBarProps, Services } from './types'; import { ObservabilityAlertSearchBar } from './alert_search_bar'; -import { observabilityAlertFeatureIds } from '../../../common/constants'; import { render } from '../../utils/test_helper'; +import { OBSERVABILITY_RULE_TYPE_IDS_WITH_SUPPORTED_STACK_RULE_TYPES } from '../../../common/constants'; const getAlertsSearchBarMock = jest.fn(); const ALERT_SEARCH_BAR_DATA_TEST_SUBJ = 'alerts-search-bar'; @@ -69,7 +69,7 @@ describe('ObservabilityAlertSearchBar', () => { expect(getAlertsSearchBarMock).toHaveBeenCalledWith( expect.objectContaining({ appName: 'testAppName', - featureIds: observabilityAlertFeatureIds, + ruleTypeIds: OBSERVABILITY_RULE_TYPE_IDS_WITH_SUPPORTED_STACK_RULE_TYPES, rangeFrom: 'now-15m', rangeTo: 'now', query: '', diff --git a/x-pack/plugins/observability_solution/observability/public/components/alert_search_bar/alert_search_bar.tsx b/x-pack/plugins/observability_solution/observability/public/components/alert_search_bar/alert_search_bar.tsx index 863855bbbb3b8..dd855829edf6f 100644 --- a/x-pack/plugins/observability_solution/observability/public/components/alert_search_bar/alert_search_bar.tsx +++ b/x-pack/plugins/observability_solution/observability/public/components/alert_search_bar/alert_search_bar.tsx @@ -11,8 +11,8 @@ import React, { useCallback, useEffect } from 'react'; import { i18n } from '@kbn/i18n'; import { Filter, Query } from '@kbn/es-query'; import { getEsQueryConfig } from '@kbn/data-plugin/common'; +import { OBSERVABILITY_RULE_TYPE_IDS_WITH_SUPPORTED_STACK_RULE_TYPES } from '../../../common/constants'; import { AlertsStatusFilter } from './components'; -import { observabilityAlertFeatureIds } from '../../../common/constants'; import { ALERT_STATUS_QUERY, DEFAULT_QUERIES, DEFAULT_QUERY_STRING } from './constants'; import { ObservabilityAlertSearchBarProps } from './types'; import { buildEsQuery } from '../../utils/build_es_query'; @@ -161,7 +161,7 @@ export function ObservabilityAlertSearchBar({ ['services'], @@ -25,7 +24,7 @@ interface GetPersistentControlsParams { export const getPersistentControlsHook = ({ groupingId, - featureIds, + ruleTypeIds, maxGroupingLevels = 3, services: { dataViews, http, notifications }, }: GetPersistentControlsParams) => @@ -43,7 +42,7 @@ export const getPersistentControlsHook = ); const { dataView } = useAlertsDataView({ - featureIds, + ruleTypeIds, dataViewsService: dataViews, http, toasts: notifications.toasts, diff --git a/x-pack/plugins/observability_solution/observability/public/pages/alert_details/components/alert_history.tsx b/x-pack/plugins/observability_solution/observability/public/pages/alert_details/components/alert_history.tsx index dfcf01e4e4c13..614a842963868 100644 --- a/x-pack/plugins/observability_solution/observability/public/pages/alert_details/components/alert_history.tsx +++ b/x-pack/plugins/observability_solution/observability/public/pages/alert_details/components/alert_history.tsx @@ -6,7 +6,6 @@ */ import React from 'react'; -import { ALERTING_FEATURE_ID } from '@kbn/alerting-plugin/common'; import { EuiPanel, EuiFlexGroup, @@ -17,12 +16,10 @@ import { EuiLoadingSpinner, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { ALERT_INSTANCE_ID, ALERT_RULE_UUID, type AlertConsumers } from '@kbn/rule-data-utils'; +import { ALERT_INSTANCE_ID, ALERT_RULE_UUID } from '@kbn/rule-data-utils'; import { useAlertsHistory } from '@kbn/observability-alert-details'; import type { Rule } from '@kbn/triggers-actions-ui-plugin/public'; import { convertTo } from '../../../../common/utils/formatters'; -import { useFetchRuleTypes } from '../../../hooks/use_fetch_rule_types'; -import { useGetFilteredRuleTypes } from '../../../hooks/use_get_filtered_rule_types'; import { useKibana } from '../../../utils/kibana_react'; import { TopAlert } from '../../..'; import { getDefaultAlertSummaryTimeRange } from '../../../utils/alert_summary_widget'; @@ -43,19 +40,11 @@ export function AlertHistoryChart({ rule, alert }: Props) { notifications, triggersActionsUi: { getAlertSummaryWidget: AlertSummaryWidget }, } = useKibana().services; + const instanceId = alert.fields[ALERT_INSTANCE_ID]; - const filteredRuleTypes = useGetFilteredRuleTypes(); - const { ruleTypes } = useFetchRuleTypes({ - filterByRuleTypeIds: filteredRuleTypes, - }); - const ruleType = ruleTypes?.find((type) => type.id === rule?.ruleTypeId); - const featureIds = - rule?.consumer === ALERTING_FEATURE_ID && ruleType?.producer - ? [ruleType.producer as AlertConsumers] - : rule - ? [rule.consumer as AlertConsumers] - : []; const ruleId = alert.fields[ALERT_RULE_UUID]; + const ruleTypeIds = [rule.ruleTypeId]; + const consumers = [rule.consumer]; const { data: { avgTimeToRecoverUS, totalTriggeredAlerts }, @@ -63,7 +52,8 @@ export function AlertHistoryChart({ rule, alert }: Props) { isError, } = useAlertsHistory({ http, - featureIds, + ruleTypeIds, + consumers, ruleId: rule.id, dateRange, instanceId, @@ -162,7 +152,8 @@ export function AlertHistoryChart({ rule, alert }: Props) { {esQuery && ( - featureIds={observabilityAlertFeatureIds} + ruleTypeIds={OBSERVABILITY_RULE_TYPE_IDS_WITH_SUPPORTED_STACK_RULE_TYPES} + consumers={observabilityAlertFeatureIds} defaultFilters={ALERT_STATUS_FILTER[alertSearchBarStateProps.status] ?? DEFAULT_FILTERS} from={alertSearchBarStateProps.rangeFrom} to={alertSearchBarStateProps.rangeTo} @@ -149,7 +153,8 @@ export function InternalRelatedAlerts({ alert }: Props) { return ( {esQuery && ( - featureIds={observabilityAlertFeatureIds} + ruleTypeIds={OBSERVABILITY_RULE_TYPE_IDS_WITH_SUPPORTED_STACK_RULE_TYPES} + consumers={observabilityAlertFeatureIds} defaultFilters={ ALERT_STATUS_FILTER[alertSearchBarStateProps.status] ?? DEFAULT_FILTERS } @@ -286,7 +291,8 @@ function InternalAlertsPage() { return ( ; ruleId: string; ruleType: any; @@ -49,7 +49,7 @@ interface Props { export function RuleDetailsTabs({ activeTabId, esQuery, - featureIds, + ruleTypeIds, rule, ruleId, ruleType, @@ -90,12 +90,13 @@ export function RuleDetailsTabs({ - {esQuery && featureIds && ( + {esQuery && ruleTypeIds && ( type.id === rule?.ruleTypeId); - const isEditable = isRuleEditable({ capabilities, rule, ruleType, ruleTypeRegistry }); - const featureIds = - rule?.consumer === ALERTING_FEATURE_ID && ruleType?.producer - ? [ruleType.producer as AlertConsumers] - : rule - ? [rule.consumer as AlertConsumers] - : []; - const ruleStatusMessage = rule?.executionStatus.error?.reason === RuleExecutionStatusErrorReasons.License ? rulesStatusesTranslationsMapping.noLicense @@ -234,7 +229,8 @@ export function RuleDetailsPage() { >; @@ -75,7 +76,8 @@ export function RulesTab({ setRefresh, stateRefresh }: RulesTabProps) { return ( ; interface PluginSetup { - alerting: PluginSetupContract; + alerting: AlertingServerSetup; features: FeaturesPluginSetup; guidedOnboarding?: GuidedOnboardingPluginSetup; ruleRegistry: RuleRegistryPluginSetupContract; @@ -74,21 +66,17 @@ interface PluginSetup { } interface PluginStart { - alerting: PluginStartContract; + alerting: AlertingServerStart; spaces?: SpacesPluginStart; dataViews: DataViewsServerPluginStart; } -const o11yRuleTypes = [ - SLO_BURN_RATE_RULE_TYPE_ID, - OBSERVABILITY_THRESHOLD_RULE_TYPE_ID, - ES_QUERY_ID, - ML_ANOMALY_DETECTION_RULE_TYPE_ID, - METRIC_INVENTORY_THRESHOLD_ALERT_TYPE_ID, - ...Object.values(ApmRuleType), - SYNTHETICS_STATUS_RULE, - SYNTHETICS_TLS_RULE, -]; +const alertingFeatures = OBSERVABILITY_RULE_TYPE_IDS_WITH_SUPPORTED_STACK_RULE_TYPES.map( + (ruleTypeId) => ({ + ruleTypeId, + consumers: [observabilityFeatureId, ALERTING_FEATURE_ID], + }) +); export class ObservabilityPlugin implements Plugin { private logger: Logger; @@ -141,7 +129,7 @@ export class ObservabilityPlugin implements Plugin { scope: [KibanaFeatureScope.Spaces, KibanaFeatureScope.Security], app: [observabilityFeatureId], catalogue: [observabilityFeatureId], - alerting: o11yRuleTypes, + alerting: alertingFeatures, privileges: { all: { app: [observabilityFeatureId], @@ -153,10 +141,10 @@ export class ObservabilityPlugin implements Plugin { }, alerting: { rule: { - all: o11yRuleTypes, + all: alertingFeatures, }, alert: { - all: o11yRuleTypes, + all: alertingFeatures, }, }, ui: ['read', 'write'], @@ -171,10 +159,10 @@ export class ObservabilityPlugin implements Plugin { }, alerting: { rule: { - read: o11yRuleTypes, + read: alertingFeatures, }, alert: { - read: o11yRuleTypes, + read: alertingFeatures, }, }, ui: ['read'], diff --git a/x-pack/plugins/observability_solution/observability/server/routes/register_routes.ts b/x-pack/plugins/observability_solution/observability/server/routes/register_routes.ts index 9ce2d7c9f1829..e10ce506bc99a 100644 --- a/x-pack/plugins/observability_solution/observability/server/routes/register_routes.ts +++ b/x-pack/plugins/observability_solution/observability/server/routes/register_routes.ts @@ -30,7 +30,7 @@ export interface RegisterRoutesDependencies { assistant: { alertDetailsContextualInsightsService: AlertDetailsContextualInsightsService; }; - getRulesClientWithRequest: (request: KibanaRequest) => RulesClientApi; + getRulesClientWithRequest: (request: KibanaRequest) => Promise; } export function registerRoutes({ repository, core, logger, dependencies }: RegisterRoutes) { diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/public/analytics/index.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/public/analytics/index.ts index 049c5a1e65fb0..422ef625cdc64 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/public/analytics/index.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/public/analytics/index.ts @@ -10,10 +10,16 @@ import { AssistantScope } from '@kbn/ai-assistant-common'; import type { Message } from '../../common'; import { chatFeedbackEventSchema, ChatFeedback } from './schemas/chat_feedback'; import { insightFeedbackEventSchema, InsightFeedback } from './schemas/insight_feedback'; +import { insightResponseEventSchema, InsightResponse } from './schemas/insight_response'; import { userSentPromptEventSchema } from './schemas/user_sent_prompt'; import { ObservabilityAIAssistantTelemetryEventType } from './telemetry_event_type'; -const schemas = [chatFeedbackEventSchema, insightFeedbackEventSchema, userSentPromptEventSchema]; +const schemas = [ + chatFeedbackEventSchema, + insightFeedbackEventSchema, + userSentPromptEventSchema, + insightResponseEventSchema, +]; export type TelemetryEventTypeWithPayload = | { type: ObservabilityAIAssistantTelemetryEventType.ChatFeedback; payload: ChatFeedback } @@ -21,6 +27,10 @@ export type TelemetryEventTypeWithPayload = | { type: ObservabilityAIAssistantTelemetryEventType.UserSentPromptInChat; payload: Message & { scopes: AssistantScope[] }; + } + | { + type: ObservabilityAIAssistantTelemetryEventType.InsightResponse; + payload: InsightResponse; }; export const registerTelemetryEventTypes = (analytics: AnalyticsServiceSetup) => { diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/public/analytics/schemas/insight_response.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/public/analytics/schemas/insight_response.ts new file mode 100644 index 0000000000000..e46eabf7316c0 --- /dev/null +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/public/analytics/schemas/insight_response.ts @@ -0,0 +1,25 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { EventTypeOpts } from '@kbn/core/public'; +import { ObservabilityAIAssistantTelemetryEventType } from '../telemetry_event_type'; + +export interface InsightResponse { + '@timestamp': string; +} + +export const insightResponseEventSchema: EventTypeOpts = { + eventType: ObservabilityAIAssistantTelemetryEventType.InsightResponse, + schema: { + '@timestamp': { + type: 'text', + _meta: { + description: 'The timestamp of the last response from the LLM.', + }, + }, + }, +}; diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/public/analytics/telemetry_event_type.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/public/analytics/telemetry_event_type.ts index e15ae317a7730..17f9c1d53acde 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/public/analytics/telemetry_event_type.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/public/analytics/telemetry_event_type.ts @@ -9,4 +9,5 @@ export enum ObservabilityAIAssistantTelemetryEventType { ChatFeedback = 'observability_ai_assistant_chat_feedback', InsightFeedback = 'observability_ai_assistant_insight_feedback', UserSentPromptInChat = 'observability_ai_assistant_user_sent_prompt_in_chat', + InsightResponse = 'observability_ai_assistant_insight_response', } diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/public/components/insight/insight.tsx b/x-pack/plugins/observability_solution/observability_ai_assistant/public/components/insight/insight.tsx index e5168470be8f1..680a92f559f0a 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/public/components/insight/insight.tsx +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/public/components/insight/insight.tsx @@ -81,6 +81,17 @@ function ChatContent({ next(initialMessagesRef.current); }, [next]); + useEffect(() => { + if (state !== ChatState.Loading && lastAssistantResponse) { + chatService.sendAnalyticsEvent({ + type: ObservabilityAIAssistantTelemetryEventType.InsightResponse, + payload: { + '@timestamp': lastAssistantResponse['@timestamp'], + }, + }); + } + }, [state, lastAssistantResponse, chatService]); + return ( <> ; +let hookResult: RenderHookResult; describe('useChat', () => { beforeEach(() => { diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/server/routes/knowledge_base/route.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/server/routes/knowledge_base/route.ts index 50ce85e3578e9..37e9248a0c624 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/server/routes/knowledge_base/route.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/server/routes/knowledge_base/route.ts @@ -133,7 +133,7 @@ const saveKnowledgeBaseUserInstruction = createObservabilityAIAssistantServerRou params: t.type({ body: t.type({ id: t.string, - text: nonEmptyStringRt, + text: t.string, public: toBooleanRt, }), }), diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/server/routes/types.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/server/routes/types.ts index 62365536f3823..645da146dfb89 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/server/routes/types.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/server/routes/types.ts @@ -28,7 +28,7 @@ type ObservabilityAIAssistantRequestHandlerContextBase = CustomRequestHandlerCon // these two are here for compatibility with APM functions rac: Pick; alerting: { - getRulesClient: () => RulesClientApi; + getRulesClient: () => Promise; }; }>; diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/knowledge_base_service/index.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/knowledge_base_service/index.ts index a98cf6f810f2c..fdde5ebb49970 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/knowledge_base_service/index.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/knowledge_base_service/index.ts @@ -405,7 +405,7 @@ export class KnowledgeBaseService { document: { '@timestamp': new Date().toISOString(), ...doc, - semantic_text: doc.text, + ...(doc.text ? { semantic_text: doc.text } : {}), user, namespace, }, diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/server/types.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/server/types.ts index a8ab57b8ee53c..f44911c172ce4 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/server/types.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/server/types.ts @@ -22,10 +22,7 @@ import type { LicensingPluginSetup, LicensingPluginStart } from '@kbn/licensing- import type { CloudSetup, CloudStart } from '@kbn/cloud-plugin/server'; import type { ServerlessPluginSetup, ServerlessPluginStart } from '@kbn/serverless/server'; import type { RuleRegistryPluginStartContract } from '@kbn/rule-registry-plugin/server'; -import type { - PluginSetupContract as AlertingPluginSetup, - PluginStartContract as AlertingPluginStart, -} from '@kbn/alerting-plugin/server'; +import type { AlertingServerSetup, AlertingServerStart } from '@kbn/alerting-plugin/server'; import type { ObservabilityAIAssistantService } from './service'; export interface ObservabilityAIAssistantServerSetup { @@ -51,7 +48,7 @@ export interface ObservabilityAIAssistantPluginSetupDependencies { licensing: LicensingPluginSetup; cloud?: CloudSetup; serverless?: ServerlessPluginSetup; - alerting: AlertingPluginSetup; + alerting: AlertingServerSetup; } export interface ObservabilityAIAssistantPluginStartDependencies { @@ -64,5 +61,5 @@ export interface ObservabilityAIAssistantPluginStartDependencies { ruleRegistry: RuleRegistryPluginStartContract; cloud?: CloudStart; serverless?: ServerlessPluginStart; - alerting: AlertingPluginStart; + alerting: AlertingServerStart; } diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/public/hooks/use_local_storage.test.ts b/x-pack/plugins/observability_solution/observability_ai_assistant_app/public/hooks/use_local_storage.test.ts index ab1d00392fdb9..ea4ed05e36b66 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/public/hooks/use_local_storage.test.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant_app/public/hooks/use_local_storage.test.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { renderHook, act } from '@testing-library/react-hooks'; +import { renderHook, act } from '@testing-library/react'; import { useLocalStorage } from './use_local_storage'; describe('useLocalStorage', () => { diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/alerts.ts b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/alerts.ts index 682f2e2a4b19b..5408dbbf4ab4f 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/alerts.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/alerts.ts @@ -14,8 +14,10 @@ import { ParsedTechnicalFields } from '@kbn/rule-registry-plugin/common'; import { ALERT_STATUS, ALERT_STATUS_ACTIVE, + AlertConsumers, } from '@kbn/rule-registry-plugin/common/technical_rule_data_field_names'; import { omit } from 'lodash'; +import { OBSERVABILITY_RULE_TYPE_IDS_WITH_SUPPORTED_STACK_RULE_TYPES } from '@kbn/observability-plugin/common/constants'; import { FunctionRegistrationParameters } from '.'; const defaultFields = [ @@ -61,15 +63,6 @@ const OMITTED_ALERT_FIELDS = [ 'kibana.version', ] as const; -const DEFAULT_FEATURE_IDS = [ - 'apm', - 'infrastructure', - 'logs', - 'uptime', - 'slo', - 'observability', -] as const; - export function registerAlertsFunction({ functions, resources, @@ -183,7 +176,16 @@ export function registerAlertsFunction({ const kqlQuery = !filter ? [] : [toElasticsearchQuery(fromKueryExpression(filter))]; const response = await alertsClient.find({ - featureIds: DEFAULT_FEATURE_IDS as unknown as string[], + ruleTypeIds: OBSERVABILITY_RULE_TYPE_IDS_WITH_SUPPORTED_STACK_RULE_TYPES, + consumers: [ + AlertConsumers.APM, + AlertConsumers.INFRASTRUCTURE, + AlertConsumers.LOGS, + AlertConsumers.UPTIME, + AlertConsumers.SLO, + AlertConsumers.OBSERVABILITY, + AlertConsumers.ALERTS, + ], query: { bool: { filter: [ @@ -194,17 +196,17 @@ export function registerAlertsFunction({ lte: end, }, }, - }, - ...kqlQuery, - ...(!includeRecovered - ? [ - { - term: { - [ALERT_STATUS]: ALERT_STATUS_ACTIVE, + ...kqlQuery, + ...(!includeRecovered + ? [ + { + term: { + [ALERT_STATUS]: ALERT_STATUS_ACTIVE, + }, }, - }, - ] - : []), + ] + : []), + }, ], }, }, diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/types.ts b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/types.ts index a1196be6a829a..0a3fc6d9dc12d 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/types.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/types.ts @@ -9,10 +9,7 @@ import type { PluginSetupContract as ActionsPluginSetup, PluginStartContract as ActionsPluginStart, } from '@kbn/actions-plugin/server'; -import type { - PluginSetupContract as AlertingPluginSetup, - PluginStartContract as AlertingPluginStart, -} from '@kbn/alerting-plugin/server'; +import type { AlertingServerSetup, AlertingServerStart } from '@kbn/alerting-plugin/server'; import type { DataViewsServerPluginSetup, DataViewsServerPluginStart, @@ -47,7 +44,7 @@ export interface ObservabilityAIAssistantAppServerSetup {} export interface ObservabilityAIAssistantAppPluginStartDependencies { observabilityAIAssistant: ObservabilityAIAssistantServerStart; ruleRegistry: RuleRegistryPluginStartContract; - alerting: AlertingPluginStart; + alerting: AlertingServerStart; licensing: LicensingPluginStart; actions: ActionsPluginStart; security: SecurityPluginStart; @@ -64,7 +61,7 @@ export interface ObservabilityAIAssistantAppPluginStartDependencies { export interface ObservabilityAIAssistantAppPluginSetupDependencies { observabilityAIAssistant: ObservabilityAIAssistantServerSetup; ruleRegistry: RuleRegistryPluginSetupContract; - alerting: AlertingPluginSetup; + alerting: AlertingServerSetup; licensing: LicensingPluginSetup; actions: ActionsPluginSetup; security: SecurityPluginSetup; diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_management/public/routes/components/knowledge_base_edit_user_instruction_flyout.tsx b/x-pack/plugins/observability_solution/observability_ai_assistant_management/public/routes/components/knowledge_base_edit_user_instruction_flyout.tsx index 1c05ca6d52b3f..51801c44a6835 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_management/public/routes/components/knowledge_base_edit_user_instruction_flyout.tsx +++ b/x-pack/plugins/observability_solution/observability_ai_assistant_management/public/routes/components/knowledge_base_edit_user_instruction_flyout.tsx @@ -31,7 +31,6 @@ export function KnowledgeBaseEditUserInstructionFlyout({ onClose }: { onClose: ( const { mutateAsync: createEntry, isLoading: isSaving } = useCreateKnowledgeBaseUserInstruction(); const [newEntryText, setNewEntryText] = useState(''); const [newEntryId, setNewEntryId] = useState(); - const isSubmitDisabled = newEntryText.trim() === ''; useEffect(() => { const userInstruction = userInstructions?.find((entry) => !entry.public); @@ -118,7 +117,6 @@ export function KnowledgeBaseEditUserInstructionFlyout({ onClose }: { onClose: ( fill isLoading={isSaving} onClick={handleSubmit} - isDisabled={isSubmitDisabled} > {i18n.translate( 'xpack.observabilityAiAssistantManagement.knowledgeBaseNewManualEntryFlyout.saveButtonLabel', diff --git a/x-pack/plugins/observability_solution/profiling/public/components/contexts/license/license_context.tsx b/x-pack/plugins/observability_solution/profiling/public/components/contexts/license/license_context.tsx index dcf15d83ef937..f0274ab739b9a 100644 --- a/x-pack/plugins/observability_solution/profiling/public/components/contexts/license/license_context.tsx +++ b/x-pack/plugins/observability_solution/profiling/public/components/contexts/license/license_context.tsx @@ -14,8 +14,8 @@ import { useProfilingDependencies } from '../profiling_dependencies/use_profilin export const LicenseContext = React.createContext(undefined); -export function LicenseProvider({ children }: { children: React.ReactChild }) { - const { license$ } = useProfilingDependencies().setup.licensing; +export function LicenseProvider({ children }: { children: React.ReactNode }) { + const { license$ } = useProfilingDependencies().start.licensing; const license = useObservable(license$); // if license is not loaded yet, consider it valid const hasInvalidLicense = license?.isActive === false; diff --git a/x-pack/plugins/observability_solution/profiling/public/hooks/use_calculate_impact_estimates.test.ts b/x-pack/plugins/observability_solution/profiling/public/hooks/use_calculate_impact_estimates.test.ts index 1c4017a468eae..4bb49fcf8ac55 100644 --- a/x-pack/plugins/observability_solution/profiling/public/hooks/use_calculate_impact_estimates.test.ts +++ b/x-pack/plugins/observability_solution/profiling/public/hooks/use_calculate_impact_estimates.test.ts @@ -40,9 +40,9 @@ describe('useCalculateImpactEstimate', () => { it('calculates impact when countExclusive is lower than countInclusive', () => { const calculateImpactEstimates = useCalculateImpactEstimate(); const { selfCPU, totalCPU, totalSamples } = calculateImpactEstimates({ - countExclusive: 500, - countInclusive: 1000, - totalSamples: 10000, + countExclusive: 475, + countInclusive: 950, + totalSamples: 9500, totalSeconds: 15 * 60, // 15m }); @@ -68,9 +68,9 @@ describe('useCalculateImpactEstimate', () => { it('calculates impact', () => { const calculateImpactEstimates = useCalculateImpactEstimate(); const { selfCPU, totalCPU, totalSamples } = calculateImpactEstimates({ - countExclusive: 1000, - countInclusive: 1000, - totalSamples: 10000, + countExclusive: 950, + countInclusive: 950, + totalSamples: 9500, totalSeconds: 15 * 60, // 15m }); diff --git a/x-pack/plugins/observability_solution/profiling/public/hooks/use_calculate_impact_estimates.ts b/x-pack/plugins/observability_solution/profiling/public/hooks/use_calculate_impact_estimates.ts index d148e0cc262dd..a56f8c96d95db 100644 --- a/x-pack/plugins/observability_solution/profiling/public/hooks/use_calculate_impact_estimates.ts +++ b/x-pack/plugins/observability_solution/profiling/public/hooks/use_calculate_impact_estimates.ts @@ -28,7 +28,7 @@ export function useCalculateImpactEstimate() { totalSeconds: number; }) { const annualizedScaleUp = ANNUAL_SECONDS / totalSeconds; - const totalCoreSeconds = totalSamples / 20; + const totalCoreSeconds = totalSamples / 19; const percentage = samples / totalSamples; const coreSeconds = totalCoreSeconds * percentage; const annualizedCoreSeconds = coreSeconds * annualizedScaleUp; diff --git a/x-pack/plugins/observability_solution/profiling/public/types.ts b/x-pack/plugins/observability_solution/profiling/public/types.ts index 89a8f999010ce..31532150cc1fd 100644 --- a/x-pack/plugins/observability_solution/profiling/public/types.ts +++ b/x-pack/plugins/observability_solution/profiling/public/types.ts @@ -18,7 +18,7 @@ import { ObservabilitySharedPluginStart, } from '@kbn/observability-shared-plugin/public/plugin'; import { ChartsPluginSetup, ChartsPluginStart } from '@kbn/charts-plugin/public'; -import { LicensingPluginSetup } from '@kbn/licensing-plugin/public'; +import type { LicensingPluginStart } from '@kbn/licensing-plugin/public'; import type { SharePluginSetup, SharePluginStart } from '@kbn/share-plugin/public'; import { ObservabilityAIAssistantPublicSetup, @@ -36,7 +36,6 @@ export interface ProfilingPluginPublicSetupDeps { dataViews: DataViewsPublicPluginSetup; data: DataPublicPluginSetup; charts: ChartsPluginSetup; - licensing: LicensingPluginSetup; share: SharePluginSetup; unifiedSearch: UnifiedSearchPluginSetup; } @@ -50,4 +49,5 @@ export interface ProfilingPluginPublicStartDeps { charts: ChartsPluginStart; share: SharePluginStart; unifiedSearch: UnifiedSearchPublicPluginStart; + licensing: LicensingPluginStart; } diff --git a/x-pack/plugins/observability_solution/profiling/server/routes/apm.ts b/x-pack/plugins/observability_solution/profiling/server/routes/apm.ts index 4d5a7cca0ff7f..7ad001831c0e4 100644 --- a/x-pack/plugins/observability_solution/profiling/server/routes/apm.ts +++ b/x-pack/plugins/observability_solution/profiling/server/routes/apm.ts @@ -52,7 +52,9 @@ export function registerTopNFunctionsAPMTransactionsRoute({ }); } const core = await context.core; - const { transaction: transactionIndices } = await apmDataAccess.getApmIndices(); + const { transaction: transactionIndices } = await apmDataAccess.getApmIndices( + core.savedObjects.client + ); const esClient = await getClient(context); diff --git a/x-pack/plugins/observability_solution/slo/README.md b/x-pack/plugins/observability_solution/slo/README.md index f577b2da35ec9..df6872a5e9ec8 100755 --- a/x-pack/plugins/observability_solution/slo/README.md +++ b/x-pack/plugins/observability_solution/slo/README.md @@ -20,3 +20,27 @@ See the [kibana contributing guide](https://github.com/elastic/kibana/blob/main/
        yarn plugin-helpers dev --watch
        Execute this to build your plugin ui browser side so Kibana could pick up when started in development
        + + +## API Integration Tests +The SLO tests are located under `x-pack/test/api_integration/deployment_agnostic/apis/observability/slo` folder. In order to run the SLO tests of your interest, you can grep accordingly. Use the commands below to run all SLO tests (`grep=SLO`) on stateful or serverless. + +### Stateful + +``` +# start server +node scripts/functional_tests_server --config x-pack/test/api_integration/deployment_agnostic/configs/stateful/oblt.stateful.config.ts + +# run tests +node scripts/functional_test_runner --config x-pack/test/api_integration/deployment_agnostic/configs/stateful/oblt.stateful.config.ts --grep=SLO +``` + +### Serverless + +``` +# start server +node scripts/functional_tests_server --config x-pack/test/api_integration/deployment_agnostic/configs/serverless/oblt.serverless.config.ts + +# run tests +node scripts/functional_test_runner --config x-pack/test/api_integration/deployment_agnostic/configs/serverless/oblt.serverless.config.ts --grep=SLO +``` diff --git a/x-pack/plugins/observability_solution/slo/docs/openapi/slo/bundled.json b/x-pack/plugins/observability_solution/slo/docs/openapi/slo/bundled.json index b4d66229dc495..915fa9e108d4a 100644 --- a/x-pack/plugins/observability_solution/slo/docs/openapi/slo/bundled.json +++ b/x-pack/plugins/observability_solution/slo/docs/openapi/slo/bundled.json @@ -14,8 +14,12 @@ }, "servers": [ { - "url": "http://localhost:5601", - "description": "local" + "url": "https://{kibana_url}", + "variables": { + "kibana_url": { + "default": "localhost:5601" + } + } } ], "tags": [ @@ -102,12 +106,7 @@ } } } - }, - "servers": [ - { - "url": "https://localhost:5601" - } - ] + } }, "get": { "summary": "Get a paginated list of SLOs", @@ -738,12 +737,7 @@ } } } - }, - "servers": [ - { - "url": "https://localhost:5601" - } - ] + } } } }, @@ -1653,20 +1647,25 @@ "description": "Defines properties for SLO settings.", "type": "object", "properties": { + "syncField": { + "description": "The date field that is used to identify new documents in the source. It is strongly recommended to use a field that contains the ingest timestamp. If you use a different field, you might need to set the delay such that it accounts for data transmission delays. When unspecified, we use the indicator timestamp field.", + "type": "string", + "example": "event.ingested" + }, "syncDelay": { - "description": "The synch delay to apply to the transform. Default 1m", + "description": "The time delay in minutes between the current time and the latest source data time. Increasing the value will delay any alerting. The default value is 1 minute. The minimum value is 1m and the maximum is 359m. It should always be greater then source index refresh interval.", "type": "string", "default": "1m", "example": "5m" }, "frequency": { - "description": "Configure how often the transform runs, default 1m", + "description": "The interval between checks for changes in the source data. The minimum value is 1m and the maximum is 59m. The default value is 1 minute.", "type": "string", "default": "1m", "example": "5m" }, "preventInitialBackfill": { - "description": "Prevents the transform from backfilling data when it starts.", + "description": "Start aggregating data from the time the SLO is created, instead of backfilling data from the beginning of the time window.", "type": "boolean", "default": false, "example": true diff --git a/x-pack/plugins/observability_solution/slo/docs/openapi/slo/bundled.yaml b/x-pack/plugins/observability_solution/slo/docs/openapi/slo/bundled.yaml index fde29b3602be0..96d63163b1d51 100644 --- a/x-pack/plugins/observability_solution/slo/docs/openapi/slo/bundled.yaml +++ b/x-pack/plugins/observability_solution/slo/docs/openapi/slo/bundled.yaml @@ -9,8 +9,10 @@ info: name: Elastic License 2.0 url: https://www.elastic.co/licensing/elastic-license servers: - - url: http://localhost:5601 - description: local + - url: https://{kibana_url} + variables: + kibana_url: + default: localhost:5601 tags: - name: slo description: SLO APIs enable you to define, manage and track service-level objectives @@ -63,8 +65,6 @@ paths: application/json: schema: $ref: '#/components/schemas/409_response' - servers: - - url: https://localhost:5601 get: summary: Get a paginated list of SLOs operationId: findSlosOp @@ -448,8 +448,6 @@ paths: application/json: schema: $ref: '#/components/schemas/403_response' - servers: - - url: https://localhost:5601 components: parameters: kbn_xsrf: @@ -1139,18 +1137,22 @@ components: description: Defines properties for SLO settings. type: object properties: + syncField: + description: The date field that is used to identify new documents in the source. It is strongly recommended to use a field that contains the ingest timestamp. If you use a different field, you might need to set the delay such that it accounts for data transmission delays. When unspecified, we use the indicator timestamp field. + type: string + example: event.ingested syncDelay: - description: The synch delay to apply to the transform. Default 1m + description: The time delay in minutes between the current time and the latest source data time. Increasing the value will delay any alerting. The default value is 1 minute. The minimum value is 1m and the maximum is 359m. It should always be greater then source index refresh interval. type: string default: 1m example: 5m frequency: - description: Configure how often the transform runs, default 1m + description: The interval between checks for changes in the source data. The minimum value is 1m and the maximum is 59m. The default value is 1 minute. type: string default: 1m example: 5m preventInitialBackfill: - description: Prevents the transform from backfilling data when it starts. + description: Start aggregating data from the time the SLO is created, instead of backfilling data from the beginning of the time window. type: boolean default: false example: true diff --git a/x-pack/plugins/observability_solution/slo/docs/openapi/slo/components/schemas/settings.yaml b/x-pack/plugins/observability_solution/slo/docs/openapi/slo/components/schemas/settings.yaml index a50ce0c28c136..e811e18734d51 100644 --- a/x-pack/plugins/observability_solution/slo/docs/openapi/slo/components/schemas/settings.yaml +++ b/x-pack/plugins/observability_solution/slo/docs/openapi/slo/components/schemas/settings.yaml @@ -2,18 +2,22 @@ title: Settings description: Defines properties for SLO settings. type: object properties: + syncField: + description: The date field that is used to identify new documents in the source. It is strongly recommended to use a field that contains the ingest timestamp. If you use a different field, you might need to set the delay such that it accounts for data transmission delays. When unspecified, we use the indicator timestamp field. + type: string + example: 'event.ingested' syncDelay: - description: The synch delay to apply to the transform. Default 1m + description: The time delay in minutes between the current time and the latest source data time. Increasing the value will delay any alerting. The default value is 1 minute. The minimum value is 1m and the maximum is 359m. It should always be greater then source index refresh interval. type: string default: 1m example: 5m frequency: - description: Configure how often the transform runs, default 1m + description: The interval between checks for changes in the source data. The minimum value is 1m and the maximum is 59m. The default value is 1 minute. type: string default: 1m example: 5m preventInitialBackfill: - description: Prevents the transform from backfilling data when it starts. + description: Start aggregating data from the time the SLO is created, instead of backfilling data from the beginning of the time window. type: boolean default: false example: true diff --git a/x-pack/plugins/observability_solution/slo/docs/openapi/slo/entrypoint.yaml b/x-pack/plugins/observability_solution/slo/docs/openapi/slo/entrypoint.yaml index a1f7a8739c07c..413540ecb96c6 100644 --- a/x-pack/plugins/observability_solution/slo/docs/openapi/slo/entrypoint.yaml +++ b/x-pack/plugins/observability_solution/slo/docs/openapi/slo/entrypoint.yaml @@ -12,8 +12,10 @@ tags: - name: slo description: SLO APIs enable you to define, manage and track service-level objectives servers: - - url: "http://localhost:5601" - description: local + - url: https://{kibana_url} + variables: + kibana_url: + default: localhost:5601 paths: "/s/{spaceId}/api/observability/slos": $ref: "paths/s@{spaceid}@api@slos.yaml" @@ -31,17 +33,3 @@ paths: # $ref: "paths/s@{spaceid}@api@slos@_definitions.yaml" "/s/{spaceId}/api/observability/slos/_delete_instances": $ref: "paths/s@{spaceid}@api@slos@_delete_instances.yaml" -# Security is defined when files are joined in oas_docs -# components: -# securitySchemes: -# basicAuth: -# type: http -# scheme: basic -# apiKeyAuth: -# type: apiKey -# in: header -# name: Authorization -# description: 'e.g. Authorization: ApiKey base64AccessApiKey' -# security: -# - basicAuth: [] -# - apiKeyAuth: [] diff --git a/x-pack/plugins/observability_solution/slo/docs/openapi/slo/paths/s@{spaceid}@api@slos.yaml b/x-pack/plugins/observability_solution/slo/docs/openapi/slo/paths/s@{spaceid}@api@slos.yaml index ed489df00d800..68de4d633a820 100644 --- a/x-pack/plugins/observability_solution/slo/docs/openapi/slo/paths/s@{spaceid}@api@slos.yaml +++ b/x-pack/plugins/observability_solution/slo/docs/openapi/slo/paths/s@{spaceid}@api@slos.yaml @@ -46,9 +46,6 @@ post: application/json: schema: $ref: '../components/schemas/409_response.yaml' - servers: - - url: https://localhost:5601 - get: summary: Get a paginated list of SLOs operationId: findSlosOp diff --git a/x-pack/plugins/observability_solution/slo/docs/openapi/slo/paths/s@{spaceid}@api@slos@_delete_instances.yaml b/x-pack/plugins/observability_solution/slo/docs/openapi/slo/paths/s@{spaceid}@api@slos@_delete_instances.yaml index 3ae6388f09d59..f7d0e3a3c884c 100644 --- a/x-pack/plugins/observability_solution/slo/docs/openapi/slo/paths/s@{spaceid}@api@slos@_delete_instances.yaml +++ b/x-pack/plugins/observability_solution/slo/docs/openapi/slo/paths/s@{spaceid}@api@slos@_delete_instances.yaml @@ -37,5 +37,3 @@ post: application/json: schema: $ref: '../components/schemas/403_response.yaml' - servers: - - url: https://localhost:5601 diff --git a/x-pack/plugins/observability_solution/slo/public/data/slo/slo.ts b/x-pack/plugins/observability_solution/slo/public/data/slo/slo.ts index ce50190eb7adf..0fccc4deb0f8b 100644 --- a/x-pack/plugins/observability_solution/slo/public/data/slo/slo.ts +++ b/x-pack/plugins/observability_solution/slo/public/data/slo/slo.ts @@ -39,6 +39,7 @@ const baseSlo: Omit = { good: 'http_status: 2xx', total: 'a query', timestampField: 'custom_timestamp', + dataViewId: 'some-data-view-id', }, }, timeWindow: { diff --git a/x-pack/plugins/observability_solution/slo/public/embeddable/slo/alerts/components/slo_alerts_summary.tsx b/x-pack/plugins/observability_solution/slo/public/embeddable/slo/alerts/components/slo_alerts_summary.tsx index 968d1f80a0824..9aea7b17f43f1 100644 --- a/x-pack/plugins/observability_solution/slo/public/embeddable/slo/alerts/components/slo_alerts_summary.tsx +++ b/x-pack/plugins/observability_solution/slo/public/embeddable/slo/alerts/components/slo_alerts_summary.tsx @@ -9,7 +9,7 @@ import type { TimeRange } from '@kbn/es-query'; import { useTimeBuckets } from '@kbn/observability-plugin/public'; import { getAlertSummaryTimeRange } from '@kbn/observability-plugin/public'; import { calculateTimeRangeBucketSize } from '@kbn/observability-plugin/public'; -import { observabilityAlertFeatureIds } from '@kbn/observability-plugin/common'; +import { AlertConsumers, SLO_RULE_TYPE_IDS } from '@kbn/rule-data-utils'; import { useSloAlertsQuery } from './slo_alerts_table'; import { SloEmbeddableDeps } from '../types'; @@ -61,7 +61,8 @@ export function SloAlertsSummary({ return ( (`${BASE_RAC_ALERTS_API_PATH}/find`, { body: JSON.stringify({ - feature_ids: [AlertConsumers.SLO, AlertConsumers.OBSERVABILITY], + rule_type_ids: SLO_RULE_TYPE_IDS, + consumers: [AlertConsumers.SLO, AlertConsumers.OBSERVABILITY, AlertConsumers.ALERTS], size: 0, query: { bool: { @@ -69,11 +73,6 @@ export function useFetchActiveAlerts({ }, }, }, - { - term: { - 'kibana.alert.rule.rule_type_id': 'slo.rules.burnRate', - }, - }, { term: { 'kibana.alert.status': 'active', diff --git a/x-pack/plugins/observability_solution/slo/public/hooks/use_fetch_slos_with_burn_rate_rules.ts b/x-pack/plugins/observability_solution/slo/public/hooks/use_fetch_slos_with_burn_rate_rules.ts index ce1efab910723..65546a3f6c96c 100644 --- a/x-pack/plugins/observability_solution/slo/public/hooks/use_fetch_slos_with_burn_rate_rules.ts +++ b/x-pack/plugins/observability_solution/slo/public/hooks/use_fetch_slos_with_burn_rate_rules.ts @@ -12,8 +12,9 @@ import { useQuery, } from '@tanstack/react-query'; import type { Rule } from '@kbn/triggers-actions-ui-plugin/public'; -import { BASE_ALERTING_API_PATH } from '@kbn/alerting-plugin/common'; +import { INTERNAL_ALERTING_API_FIND_RULES_PATH } from '@kbn/alerting-plugin/common'; import { HttpSetup } from '@kbn/core/public'; +import { SLO_RULE_TYPE_IDS } from '@kbn/rule-data-utils'; import { useKibana } from './use_kibana'; import { sloKeys } from './query_key_factory'; import { WindowSchema } from '../typings'; @@ -54,17 +55,15 @@ async function fetchRules({ http: HttpSetup; signal?: AbortSignal; }) { - const filter = 'alert.attributes.alertTypeId:slo.rules.burnRate'; - - const query = { + const body = { search, - filter, fields: ['id', 'params.windows', 'name'], per_page: 1000, + rule_type_ids: SLO_RULE_TYPE_IDS, }; - const response = await http.get(`${BASE_ALERTING_API_PATH}/rules/_find`, { - query, + const response = await http.post(INTERNAL_ALERTING_API_FIND_RULES_PATH, { + body: JSON.stringify({ ...body }), signal, }); diff --git a/x-pack/plugins/observability_solution/slo/public/locators/slo_edit.test.ts b/x-pack/plugins/observability_solution/slo/public/locators/slo_edit.test.ts index 40fcae8c840ee..55305a4a3719b 100644 --- a/x-pack/plugins/observability_solution/slo/public/locators/slo_edit.test.ts +++ b/x-pack/plugins/observability_solution/slo/public/locators/slo_edit.test.ts @@ -11,16 +11,21 @@ import { SloEditLocatorDefinition } from './slo_edit'; describe('SloEditLocator', () => { const locator = new SloEditLocatorDefinition(); - it('should return correct url when empty params are provided', async () => { + it('returns the correct url when empty params are provided', async () => { const location = await locator.getLocation({}); expect(location.app).toEqual('slo'); expect(location.path).toEqual('/create?_a=()'); }); - it('should return correct url when slo is provided', async () => { - const location = await locator.getLocation(buildSlo({ id: 'foo' })); + it('returns the correct url when slo id is provided', async () => { + const location = await locator.getLocation({ id: 'existing-slo-id' }); + expect(location.path).toEqual('/edit/existing-slo-id'); + }); + + it('returns the correct url when partial slo input is provided', async () => { + const location = await locator.getLocation(buildSlo({ id: undefined })); expect(location.path).toEqual( - "/edit/foo?_a=(budgetingMethod:occurrences,createdAt:'2022-12-29T10:11:12.000Z',description:'some%20description%20useful',enabled:!t,groupBy:'*',groupings:(),id:foo,indicator:(params:(filter:'baz:%20foo%20and%20bar%20%3E%202',good:'http_status:%202xx',index:some-index,timestampField:custom_timestamp,total:'a%20query'),type:sli.kql.custom),instanceId:'*',meta:(),name:'super%20important%20level%20service',objective:(target:0.98),revision:1,settings:(frequency:'1m',preventInitialBackfill:!f,syncDelay:'1m'),summary:(errorBudget:(consumed:0.064,initial:0.02,isEstimated:!f,remaining:0.936),fiveMinuteBurnRate:0,oneDayBurnRate:0,oneHourBurnRate:0,sliValue:0.99872,status:HEALTHY),tags:!(k8s,production,critical),timeWindow:(duration:'30d',type:rolling),updatedAt:'2022-12-29T10:11:12.000Z',version:2)" + "/create?_a=(budgetingMethod:occurrences,createdAt:'2022-12-29T10:11:12.000Z',description:'some%20description%20useful',enabled:!t,groupBy:'*',groupings:(),indicator:(params:(dataViewId:some-data-view-id,filter:'baz:%20foo%20and%20bar%20%3E%202',good:'http_status:%202xx',index:some-index,timestampField:custom_timestamp,total:'a%20query'),type:sli.kql.custom),instanceId:'*',meta:(),name:'super%20important%20level%20service',objective:(target:0.98),revision:1,settings:(frequency:'1m',preventInitialBackfill:!f,syncDelay:'1m'),summary:(errorBudget:(consumed:0.064,initial:0.02,isEstimated:!f,remaining:0.936),fiveMinuteBurnRate:0,oneDayBurnRate:0,oneHourBurnRate:0,sliValue:0.99872,status:HEALTHY),tags:!(k8s,production,critical),timeWindow:(duration:'30d',type:rolling),updatedAt:'2022-12-29T10:11:12.000Z',version:2)" ); }); }); diff --git a/x-pack/plugins/observability_solution/slo/public/locators/slo_edit.ts b/x-pack/plugins/observability_solution/slo/public/locators/slo_edit.ts index 120bc533e9eea..2233ea9c5718b 100644 --- a/x-pack/plugins/observability_solution/slo/public/locators/slo_edit.ts +++ b/x-pack/plugins/observability_solution/slo/public/locators/slo_edit.ts @@ -5,31 +5,34 @@ * 2.0. */ -import { setStateToKbnUrl } from '@kbn/kibana-utils-plugin/public'; import type { RecursivePartial } from '@elastic/charts'; -import type { SerializableRecord } from '@kbn/utility-types'; -import type { LocatorDefinition } from '@kbn/share-plugin/public'; +import { setStateToKbnUrl } from '@kbn/kibana-utils-plugin/public'; import { sloEditLocatorID } from '@kbn/observability-plugin/common'; -import type { CreateSLOForm } from '../pages/slo_edit/types'; +import type { LocatorDefinition } from '@kbn/share-plugin/public'; +import { CreateSLOInput } from '@kbn/slo-schema'; import { SLO_CREATE_PATH } from '../../common/locators/paths'; -export type SloEditParams = RecursivePartial; - -export interface SloEditLocatorParams extends SloEditParams, SerializableRecord {} +export type SloEditLocatorParams = RecursivePartial; export class SloEditLocatorDefinition implements LocatorDefinition { public readonly id = sloEditLocatorID; public readonly getLocation = async (slo: SloEditLocatorParams) => { + if (!!slo.id) { + return { + app: 'slo', + path: `/edit/${encodeURIComponent(slo.id)}`, + state: {}, + }; + } + return { app: 'slo', - path: setStateToKbnUrl( + path: setStateToKbnUrl>( '_a', - { - ...slo, - }, + slo, { useHash: false, storeInHashQuery: false }, - slo.id ? `/edit/${encodeURIComponent(String(slo.id))}` : `${SLO_CREATE_PATH}` + SLO_CREATE_PATH ), state: {}, }; diff --git a/x-pack/plugins/observability_solution/slo/public/pages/slo_details/components/overview/overview.tsx b/x-pack/plugins/observability_solution/slo/public/pages/slo_details/components/overview/overview.tsx index 34f3b0132dc8a..9a2f798ab628e 100644 --- a/x-pack/plugins/observability_solution/slo/public/pages/slo_details/components/overview/overview.tsx +++ b/x-pack/plugins/observability_solution/slo/public/pages/slo_details/components/overview/overview.tsx @@ -8,15 +8,14 @@ import { EuiFlexGrid, EuiPanel, EuiText, useIsWithinBreakpoints } from '@elastic/eui'; import numeral from '@elastic/numeral'; import { i18n } from '@kbn/i18n'; +import { TagsList } from '@kbn/observability-shared-plugin/public'; import { + SLOWithSummaryResponse, occurrencesBudgetingMethodSchema, querySchema, rollingTimeWindowTypeSchema, - SLOWithSummaryResponse, } from '@kbn/slo-schema'; import React from 'react'; -import { TagsList } from '@kbn/observability-shared-plugin/public'; -import { DisplayQuery } from './display_query'; import { useKibana } from '../../../../hooks/use_kibana'; import { BUDGETING_METHOD_OCCURRENCES, @@ -26,9 +25,9 @@ import { toIndicatorTypeLabel, } from '../../../../utils/slo/labels'; import { ApmIndicatorOverview } from './apm_indicator_overview'; -import { SyntheticsIndicatorOverview } from './synthetics_indicator_overview'; - +import { DisplayQuery } from './display_query'; import { OverviewItem } from './overview_item'; +import { SyntheticsIndicatorOverview } from './synthetics_indicator_overview'; export interface Props { slo: SLOWithSummaryResponse; @@ -170,6 +169,19 @@ export function Overview({ slo }: Props) { } /> )} + + + ); diff --git a/x-pack/plugins/observability_solution/slo/public/pages/slo_details/components/slo_detail_alerts.tsx b/x-pack/plugins/observability_solution/slo/public/pages/slo_details/components/slo_detail_alerts.tsx index 3aa94c00b6441..7b31baf0d62b0 100644 --- a/x-pack/plugins/observability_solution/slo/public/pages/slo_details/components/slo_detail_alerts.tsx +++ b/x-pack/plugins/observability_solution/slo/public/pages/slo_details/components/slo_detail_alerts.tsx @@ -6,7 +6,7 @@ */ import { EuiFlexGroup, EuiFlexItem, EuiSpacer } from '@elastic/eui'; import React, { Fragment } from 'react'; -import { AlertConsumers } from '@kbn/rule-data-utils'; +import { AlertConsumers, SLO_RULE_TYPE_IDS } from '@kbn/rule-data-utils'; import { ALL_VALUE, SLOWithSummaryResponse } from '@kbn/slo-schema'; import { SLO_ALERTS_TABLE_ID } from '@kbn/observability-shared-plugin/common'; @@ -32,7 +32,8 @@ export function SloDetailsAlerts({ slo }: Props) { configurationId={AlertConsumers.OBSERVABILITY} id={SLO_ALERTS_TABLE_ID} data-test-subj="alertTable" - featureIds={[AlertConsumers.SLO, AlertConsumers.OBSERVABILITY]} + ruleTypeIds={SLO_RULE_TYPE_IDS} + consumers={[AlertConsumers.SLO, AlertConsumers.ALERTS, AlertConsumers.OBSERVABILITY]} query={{ bool: { filter: [ diff --git a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/indicator_section/advanced_settings/advanced_settings.tsx b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/indicator_section/advanced_settings/advanced_settings.tsx new file mode 100644 index 0000000000000..81a630990a256 --- /dev/null +++ b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/indicator_section/advanced_settings/advanced_settings.tsx @@ -0,0 +1,174 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor 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 { + EuiAccordion, + EuiCheckbox, + EuiFieldNumber, + EuiFlexGrid, + EuiFlexGroup, + EuiFlexItem, + EuiFormRow, + EuiIcon, + EuiIconTip, + EuiTitle, + useGeneratedHtmlId, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import React from 'react'; +import { Controller, useFormContext } from 'react-hook-form'; +import { CreateSLOForm } from '../../../types'; +import { SyncFieldSelector } from './sync_field_selector'; + +export function AdvancedSettings() { + const { control, getFieldState } = useFormContext(); + const preventBackfillCheckbox = useGeneratedHtmlId({ prefix: 'preventBackfill' }); + const advancedSettingsAccordion = useGeneratedHtmlId({ prefix: 'advancedSettingsAccordion' }); + + return ( + + + + + + + +

        + {i18n.translate('xpack.slo.sloEdit.settings.advancedSettingsLabel', { + defaultMessage: 'Advanced settings', + })} +

        +
        +
        +
        + } + > + + + + + + + + + {i18n.translate('xpack.slo.sloEdit.settings.syncDelay.label', { + defaultMessage: 'Sync delay (in minutes)', + })}{' '} + + + } + > + ( + onChange(event.target.value)} + /> + )} + /> + + + + + + {i18n.translate('xpack.slo.sloEdit.settings.frequency.label', { + defaultMessage: 'Frequency (in minutes)', + })}{' '} + + + } + > + ( + onChange(event.target.value)} + /> + )} + /> + + + + + + ( + + {i18n.translate('xpack.slo.sloEdit.settings.preventInitialBackfill.label', { + defaultMessage: 'Prevent initial backfill of data', + })}{' '} + + + } + checked={Boolean(field.value)} + onChange={(event: any) => onChange(event.target.checked)} + /> + )} + /> + + + + ); +} diff --git a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/indicator_section/advanced_settings/sync_field_selector.tsx b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/indicator_section/advanced_settings/sync_field_selector.tsx new file mode 100644 index 0000000000000..ddfb51bb28977 --- /dev/null +++ b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/indicator_section/advanced_settings/sync_field_selector.tsx @@ -0,0 +1,84 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor 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 { EuiComboBox, EuiComboBoxOptionOption, EuiFormRow, EuiIconTip } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import React from 'react'; +import { Controller, useFormContext } from 'react-hook-form'; +import { useCreateDataView } from '../../../../../hooks/use_create_data_view'; +import { createOptionsFromFields } from '../../../helpers/create_options'; +import { CreateSLOForm } from '../../../types'; +import { OptionalText } from '../../common/optional_text'; + +const placeholder = i18n.translate('xpack.slo.sloEdit.settings.syncField.placeholder', { + defaultMessage: 'Select a timestamp field', +}); + +export function SyncFieldSelector() { + const { control, watch, getFieldState } = useFormContext(); + const [index, dataViewId] = watch(['indicator.params.index', 'indicator.params.dataViewId']); + const { dataView, loading: isIndexFieldsLoading } = useCreateDataView({ + indexPatternString: index, + dataViewId, + }); + const timestampFields = dataView?.fields?.filter((field) => field.type === 'date') ?? []; + + return ( + + {i18n.translate('xpack.slo.sloEdit.settings.syncField.label', { + defaultMessage: 'Sync field', + })}{' '} + + + } + isInvalid={getFieldState('settings.syncField').invalid} + labelAppend={} + > + { + return ( + + {...field} + placeholder={placeholder} + aria-label={placeholder} + isClearable + isDisabled={isIndexFieldsLoading} + isInvalid={fieldState.invalid} + isLoading={isIndexFieldsLoading} + onChange={(selected: EuiComboBoxOptionOption[]) => { + if (selected.length) { + return field.onChange(selected[0].value); + } + + field.onChange(null); + }} + singleSelection={{ asPlainText: true }} + options={createOptionsFromFields(timestampFields)} + selectedOptions={ + !!timestampFields && !!field.value + ? [{ value: field.value, label: field.value }] + : [] + } + /> + ); + }} + /> + + ); +} diff --git a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/apm_availability/apm_availability_indicator_type_form.stories.tsx b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/indicator_section/apm_availability/apm_availability_indicator_type_form.stories.tsx similarity index 84% rename from x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/apm_availability/apm_availability_indicator_type_form.stories.tsx rename to x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/indicator_section/apm_availability/apm_availability_indicator_type_form.stories.tsx index c3c506eb484eb..d40d56941ccfe 100644 --- a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/apm_availability/apm_availability_indicator_type_form.stories.tsx +++ b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/indicator_section/apm_availability/apm_availability_indicator_type_form.stories.tsx @@ -9,9 +9,9 @@ import React from 'react'; import { ComponentStory } from '@storybook/react'; import { FormProvider, useForm } from 'react-hook-form'; -import { KibanaReactStorybookDecorator } from '../../../../utils/kibana_react.storybook_decorator'; +import { KibanaReactStorybookDecorator } from '../../../../../utils/kibana_react.storybook_decorator'; import { ApmAvailabilityIndicatorTypeForm as Component } from './apm_availability_indicator_type_form'; -import { SLO_EDIT_FORM_DEFAULT_VALUES } from '../../constants'; +import { SLO_EDIT_FORM_DEFAULT_VALUES } from '../../../constants'; export default { component: Component, diff --git a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/apm_availability/apm_availability_indicator_type_form.tsx b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/indicator_section/apm_availability/apm_availability_indicator_type_form.tsx similarity index 88% rename from x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/apm_availability/apm_availability_indicator_type_form.tsx rename to x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/indicator_section/apm_availability/apm_availability_indicator_type_form.tsx index 0dcddcdb232b5..fd00e3d359530 100644 --- a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/apm_availability/apm_availability_indicator_type_form.tsx +++ b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/indicator_section/apm_availability/apm_availability_indicator_type_form.tsx @@ -12,14 +12,14 @@ import React from 'react'; import { useFormContext } from 'react-hook-form'; import { useApmDefaultValues } from '../apm_common/use_apm_default_values'; import { DATA_VIEW_FIELD } from '../custom_common/index_selection'; -import { useCreateDataView } from '../../../../hooks/use_create_data_view'; -import { GroupByField } from '../common/group_by_field'; -import { useFetchApmIndex } from '../../../../hooks/use_fetch_apm_indices'; -import { CreateSLOForm } from '../../types'; +import { useCreateDataView } from '../../../../../hooks/use_create_data_view'; +import { GroupByField } from '../../common/group_by_field'; +import { useFetchApmIndex } from '../../../../../hooks/use_fetch_apm_indices'; +import { CreateSLOForm } from '../../../types'; import { FieldSelector } from '../apm_common/field_selector'; -import { DataPreviewChart } from '../common/data_preview_chart'; -import { QueryBuilder } from '../common/query_builder'; -import { formatAllFilters } from '../../helpers/format_filters'; +import { DataPreviewChart } from '../../common/data_preview_chart'; +import { QueryBuilder } from '../../common/query_builder'; +import { formatAllFilters } from '../../../helpers/format_filters'; import { getGroupByCardinalityFilters } from '../apm_common/get_group_by_cardinality_filters'; export function ApmAvailabilityIndicatorTypeForm() { @@ -56,8 +56,8 @@ export function ApmAvailabilityIndicatorTypeForm() { }); return ( - - + + - + - + { const { watch, setValue } = useFormContext>(); diff --git a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/apm_latency/apm_latency_indicator_type_form.stories.tsx b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/indicator_section/apm_latency/apm_latency_indicator_type_form.stories.tsx similarity index 84% rename from x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/apm_latency/apm_latency_indicator_type_form.stories.tsx rename to x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/indicator_section/apm_latency/apm_latency_indicator_type_form.stories.tsx index 3ca02641f9bfa..9b346c94dea9a 100644 --- a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/apm_latency/apm_latency_indicator_type_form.stories.tsx +++ b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/indicator_section/apm_latency/apm_latency_indicator_type_form.stories.tsx @@ -9,9 +9,9 @@ import React from 'react'; import { ComponentStory } from '@storybook/react'; import { FormProvider, useForm } from 'react-hook-form'; -import { KibanaReactStorybookDecorator } from '../../../../utils/kibana_react.storybook_decorator'; +import { KibanaReactStorybookDecorator } from '../../../../../utils/kibana_react.storybook_decorator'; import { ApmLatencyIndicatorTypeForm as Component } from './apm_latency_indicator_type_form'; -import { SLO_EDIT_FORM_DEFAULT_VALUES } from '../../constants'; +import { SLO_EDIT_FORM_DEFAULT_VALUES } from '../../../constants'; export default { component: Component, diff --git a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/apm_latency/apm_latency_indicator_type_form.tsx b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/indicator_section/apm_latency/apm_latency_indicator_type_form.tsx similarity index 91% rename from x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/apm_latency/apm_latency_indicator_type_form.tsx rename to x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/indicator_section/apm_latency/apm_latency_indicator_type_form.tsx index 03b47aafe4150..0d7b86d0b88d3 100644 --- a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/apm_latency/apm_latency_indicator_type_form.tsx +++ b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/indicator_section/apm_latency/apm_latency_indicator_type_form.tsx @@ -12,14 +12,14 @@ import React from 'react'; import { Controller, useFormContext } from 'react-hook-form'; import { useApmDefaultValues } from '../apm_common/use_apm_default_values'; import { DATA_VIEW_FIELD } from '../custom_common/index_selection'; -import { GroupByField } from '../common/group_by_field'; -import { useCreateDataView } from '../../../../hooks/use_create_data_view'; -import { useFetchApmIndex } from '../../../../hooks/use_fetch_apm_indices'; -import { CreateSLOForm } from '../../types'; +import { GroupByField } from '../../common/group_by_field'; +import { useCreateDataView } from '../../../../../hooks/use_create_data_view'; +import { useFetchApmIndex } from '../../../../../hooks/use_fetch_apm_indices'; +import { CreateSLOForm } from '../../../types'; import { FieldSelector } from '../apm_common/field_selector'; -import { DataPreviewChart } from '../common/data_preview_chart'; -import { QueryBuilder } from '../common/query_builder'; -import { formatAllFilters } from '../../helpers/format_filters'; +import { DataPreviewChart } from '../../common/data_preview_chart'; +import { QueryBuilder } from '../../common/query_builder'; +import { formatAllFilters } from '../../../helpers/format_filters'; import { getGroupByCardinalityFilters } from '../apm_common/get_group_by_cardinality_filters'; export function ApmLatencyIndicatorTypeForm() { @@ -58,8 +58,8 @@ export function ApmLatencyIndicatorTypeForm() { }); return ( - - + + - + (); const index = watch('indicator.params.index'); diff --git a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/custom_common/index_selection.stories.tsx b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/indicator_section/custom_common/index_selection.stories.tsx similarity index 84% rename from x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/custom_common/index_selection.stories.tsx rename to x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/indicator_section/custom_common/index_selection.stories.tsx index 4b8dce62f43bb..b1739a63881f5 100644 --- a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/custom_common/index_selection.stories.tsx +++ b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/indicator_section/custom_common/index_selection.stories.tsx @@ -9,9 +9,9 @@ import React from 'react'; import { ComponentStory } from '@storybook/react'; import { FormProvider, useForm } from 'react-hook-form'; -import { KibanaReactStorybookDecorator } from '../../../../utils/kibana_react.storybook_decorator'; +import { KibanaReactStorybookDecorator } from '../../../../../utils/kibana_react.storybook_decorator'; import { IndexSelection as Component } from './index_selection'; -import { SLO_EDIT_FORM_DEFAULT_VALUES } from '../../constants'; +import { SLO_EDIT_FORM_DEFAULT_VALUES } from '../../../constants'; export default { component: Component, diff --git a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/custom_common/index_selection.tsx b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/indicator_section/custom_common/index_selection.tsx similarity index 63% rename from x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/custom_common/index_selection.tsx rename to x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/indicator_section/custom_common/index_selection.tsx index 146d11be84ac8..9d5489ddd283f 100644 --- a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/custom_common/index_selection.tsx +++ b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/indicator_section/custom_common/index_selection.tsx @@ -8,37 +8,47 @@ import { EuiFormRow } from '@elastic/eui'; import { DataView } from '@kbn/data-views-plugin/public'; import { i18n } from '@kbn/i18n'; +import { ALL_VALUE } from '@kbn/slo-schema'; +import { DataViewPicker } from '@kbn/unified-search-plugin/public'; import React, { useEffect } from 'react'; import { Controller, useFormContext } from 'react-hook-form'; -import { DataViewPicker } from '@kbn/unified-search-plugin/public'; -import { getDataViewPattern, useAdhocDataViews } from './use_adhoc_data_views'; -import { SLOPublicPluginsStart } from '../../../..'; -import { useKibana } from '../../../../hooks/use_kibana'; -import { CreateSLOForm } from '../../types'; +import { SLOPublicPluginsStart } from '../../../../..'; +import { useKibana } from '../../../../../hooks/use_kibana'; +import { CreateSLOForm } from '../../../types'; +import { getDataViewPatternOrId, useAdhocDataViews } from './use_adhoc_data_views'; const BTN_MAX_WIDTH = 515; export const DATA_VIEW_FIELD = 'indicator.params.dataViewId'; const INDEX_FIELD = 'indicator.params.index'; -const TIMESTAMP_FIELD = 'indicator.params.timestampField'; +const INDICATOR_TIMESTAMP_FIELD = 'indicator.params.timestampField'; +const GROUP_BY_FIELD = 'groupBy'; +const SETTINGS_SYNC_FIELD = 'settings.syncField'; export function IndexSelection({ selectedDataView }: { selectedDataView?: DataView }) { const { control, getFieldState, setValue, watch } = useFormContext(); - const { dataViews: dataViewsService, dataViewFieldEditor } = useKibana().services; - - const { dataViewEditor } = useKibana().services; + const { + dataViews: dataViewsService, + dataViewFieldEditor, + dataViewEditor, + } = useKibana().services; const currentIndexPattern = watch(INDEX_FIELD); const currentDataViewId = watch(DATA_VIEW_FIELD); - const { dataViewsList, isDataViewsLoading, adHocDataViews, setAdHocDataViews, refetch } = - useAdhocDataViews({ - currentIndexPattern, - }); + const { + dataViewsList, + isDataViewsLoading, + adHocDataViews, + setAdHocDataViews, + refetchDataViewsList, + } = useAdhocDataViews({ + currentIndexPattern, + }); useEffect(() => { - const indPatternId = getDataViewPattern({ - byPatten: currentIndexPattern, + const indPatternId = getDataViewPatternOrId({ + byPattern: currentIndexPattern, dataViewsList, adHocDataViews, }); @@ -54,13 +64,24 @@ export function IndexSelection({ selectedDataView }: { selectedDataView?: DataVi setValue, ]); + const updateDataViewDependantFields = (indexPattern?: string, timestampField?: string) => { + setValue(INDEX_FIELD, indexPattern ?? ''); + setValue(INDICATOR_TIMESTAMP_FIELD, timestampField ?? ''); + setValue(GROUP_BY_FIELD, ALL_VALUE); + setValue(SETTINGS_SYNC_FIELD, null); + }; + return ( - + ( { - setValue( - INDEX_FIELD, - getDataViewPattern({ byId: newId, adHocDataViews, dataViewsList })! - ); field.onChange(newId); + dataViewsService.get(newId).then((dataView) => { - if (dataView.timeFieldName) { - setValue(TIMESTAMP_FIELD, dataView.timeFieldName); - } + updateDataViewDependantFields( + getDataViewPatternOrId({ byId: newId, adHocDataViews, dataViewsList })!, + dataView.timeFieldName + ); }); }} onAddField={ @@ -97,8 +116,8 @@ export function IndexSelection({ selectedDataView }: { selectedDataView?: DataVi } currentDataViewId={ field.value ?? - getDataViewPattern({ - byPatten: currentIndexPattern, + getDataViewPatternOrId({ + byPattern: currentIndexPattern, dataViewsList, adHocDataViews, }) @@ -108,17 +127,13 @@ export function IndexSelection({ selectedDataView }: { selectedDataView?: DataVi allowAdHocDataView: true, onSave: (dataView: DataView) => { if (!dataView.isPersisted()) { - setAdHocDataViews([...adHocDataViews, dataView]); - field.onChange(dataView.id); - setValue(INDEX_FIELD, dataView.getIndexPattern()); + setAdHocDataViews((prev) => [...prev, dataView]); } else { - refetch(); - field.onChange(dataView.id); - setValue(INDEX_FIELD, dataView.getIndexPattern()); - } - if (dataView.timeFieldName) { - setValue(TIMESTAMP_FIELD, dataView.timeFieldName); + refetchDataViewsList(); } + + field.onChange(dataView.id); + updateDataViewDependantFields(dataView.getIndexPattern(), dataView.timeFieldName); }, }); }} diff --git a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/custom_common/use_adhoc_data_views.ts b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/indicator_section/custom_common/use_adhoc_data_views.ts similarity index 79% rename from x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/custom_common/use_adhoc_data_views.ts rename to x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/indicator_section/custom_common/use_adhoc_data_views.ts index 67792b056408d..986b681c9bca9 100644 --- a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/custom_common/use_adhoc_data_views.ts +++ b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/indicator_section/custom_common/use_adhoc_data_views.ts @@ -8,16 +8,16 @@ import { useEffect, useState } from 'react'; import { DataView, DataViewListItem } from '@kbn/data-views-plugin/common'; import { useFetchDataViews } from '@kbn/observability-plugin/public'; -import { useKibana } from '../../../../hooks/use_kibana'; +import { useKibana } from '../../../../../hooks/use_kibana'; -export const getDataViewPattern = ({ +export const getDataViewPatternOrId = ({ byId, - byPatten, + byPattern, dataViewsList, adHocDataViews, }: { byId?: string; - byPatten?: string; + byPattern?: string; dataViewsList: DataViewListItem[]; adHocDataViews: DataView[]; }) => { @@ -28,20 +28,24 @@ export const getDataViewPattern = ({ if (byId) { return allDataViews.find((dv) => dv.id === byId)?.title; } - if (byPatten) { - return allDataViews.find((dv) => dv.title === byPatten)?.id; + if (byPattern) { + return allDataViews.find((dv) => dv.title === byPattern)?.id; } }; export const useAdhocDataViews = ({ currentIndexPattern }: { currentIndexPattern: string }) => { - const { isLoading: isDataViewsLoading, data: dataViewsList = [], refetch } = useFetchDataViews(); + const { + isLoading: isDataViewsLoading, + data: dataViewsList = [], + refetch: refetchDataViewsList, + } = useFetchDataViews(); const { dataViews: dataViewsService } = useKibana().services; const [adHocDataViews, setAdHocDataViews] = useState([]); useEffect(() => { if (!isDataViewsLoading) { - const missingDataView = getDataViewPattern({ - byPatten: currentIndexPattern, + const missingDataView = getDataViewPatternOrId({ + byPattern: currentIndexPattern, dataViewsList, adHocDataViews, }); @@ -70,6 +74,6 @@ export const useAdhocDataViews = ({ currentIndexPattern }: { currentIndexPattern setAdHocDataViews, dataViewsList, isDataViewsLoading, - refetch, + refetchDataViewsList, }; }; diff --git a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/custom_kql/custom_kql_indicator_type_form.stories.tsx b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/indicator_section/custom_kql/custom_kql_indicator_type_form.stories.tsx similarity index 84% rename from x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/custom_kql/custom_kql_indicator_type_form.stories.tsx rename to x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/indicator_section/custom_kql/custom_kql_indicator_type_form.stories.tsx index 5eb0b68070789..1ecf3f57c1496 100644 --- a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/custom_kql/custom_kql_indicator_type_form.stories.tsx +++ b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/indicator_section/custom_kql/custom_kql_indicator_type_form.stories.tsx @@ -9,9 +9,9 @@ import React from 'react'; import { ComponentStory } from '@storybook/react'; import { FormProvider, useForm } from 'react-hook-form'; -import { KibanaReactStorybookDecorator } from '../../../../utils/kibana_react.storybook_decorator'; +import { KibanaReactStorybookDecorator } from '../../../../../utils/kibana_react.storybook_decorator'; import { CustomKqlIndicatorTypeForm as Component } from './custom_kql_indicator_type_form'; -import { SLO_EDIT_FORM_DEFAULT_VALUES } from '../../constants'; +import { SLO_EDIT_FORM_DEFAULT_VALUES } from '../../../constants'; export default { component: Component, diff --git a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/custom_kql/custom_kql_indicator_type_form.tsx b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/indicator_section/custom_kql/custom_kql_indicator_type_form.tsx similarity index 91% rename from x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/custom_kql/custom_kql_indicator_type_form.tsx rename to x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/indicator_section/custom_kql/custom_kql_indicator_type_form.tsx index 92ba2cac50e7f..ccebca1fbb36f 100644 --- a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/custom_kql/custom_kql_indicator_type_form.tsx +++ b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/indicator_section/custom_kql/custom_kql_indicator_type_form.tsx @@ -9,12 +9,12 @@ import { EuiFlexGroup, EuiFlexItem, EuiIconTip } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import React from 'react'; import { useFormContext } from 'react-hook-form'; +import { useCreateDataView } from '../../../../../hooks/use_create_data_view'; +import { CreateSLOForm } from '../../../types'; +import { DataPreviewChart } from '../../common/data_preview_chart'; +import { GroupByField } from '../../common/group_by_field'; +import { QueryBuilder } from '../../common/query_builder'; import { IndexAndTimestampField } from '../custom_common/index_and_timestamp_field'; -import { GroupByField } from '../common/group_by_field'; -import { useCreateDataView } from '../../../../hooks/use_create_data_view'; -import { CreateSLOForm } from '../../types'; -import { DataPreviewChart } from '../common/data_preview_chart'; -import { QueryBuilder } from '../common/query_builder'; import { DATA_VIEW_FIELD } from '../custom_common/index_selection'; export function CustomKqlIndicatorTypeForm() { @@ -28,7 +28,7 @@ export function CustomKqlIndicatorTypeForm() { }); return ( - + diff --git a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/custom_metric/custom_metric_type_form.stories.tsx b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/indicator_section/custom_metric/custom_metric_type_form.stories.tsx similarity index 89% rename from x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/custom_metric/custom_metric_type_form.stories.tsx rename to x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/indicator_section/custom_metric/custom_metric_type_form.stories.tsx index 1abbff61a0dc8..771405a539f1b 100644 --- a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/custom_metric/custom_metric_type_form.stories.tsx +++ b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/indicator_section/custom_metric/custom_metric_type_form.stories.tsx @@ -9,9 +9,9 @@ import React from 'react'; import { ComponentStory } from '@storybook/react'; import { FormProvider, useForm } from 'react-hook-form'; -import { KibanaReactStorybookDecorator } from '../../../../utils/kibana_react.storybook_decorator'; +import { KibanaReactStorybookDecorator } from '../../../../../utils/kibana_react.storybook_decorator'; import { CustomMetricIndicatorTypeForm as Component } from './custom_metric_type_form'; -import { SLO_EDIT_FORM_DEFAULT_VALUES_CUSTOM_METRIC } from '../../constants'; +import { SLO_EDIT_FORM_DEFAULT_VALUES_CUSTOM_METRIC } from '../../../constants'; export default { component: Component, diff --git a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/custom_metric/custom_metric_type_form.tsx b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/indicator_section/custom_metric/custom_metric_type_form.tsx similarity index 91% rename from x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/custom_metric/custom_metric_type_form.tsx rename to x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/indicator_section/custom_metric/custom_metric_type_form.tsx index ee9bcf8d99649..365205ed6b4bf 100644 --- a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/custom_metric/custom_metric_type_form.tsx +++ b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/indicator_section/custom_metric/custom_metric_type_form.tsx @@ -18,11 +18,11 @@ import { FormattedMessage } from '@kbn/i18n-react'; import React from 'react'; import { useFormContext } from 'react-hook-form'; import { IndexAndTimestampField } from '../custom_common/index_and_timestamp_field'; -import { GroupByField } from '../common/group_by_field'; -import { useCreateDataView } from '../../../../hooks/use_create_data_view'; -import { CreateSLOForm } from '../../types'; -import { DataPreviewChart } from '../common/data_preview_chart'; -import { QueryBuilder } from '../common/query_builder'; +import { GroupByField } from '../../common/group_by_field'; +import { useCreateDataView } from '../../../../../hooks/use_create_data_view'; +import { CreateSLOForm } from '../../../types'; +import { DataPreviewChart } from '../../common/data_preview_chart'; +import { QueryBuilder } from '../../common/query_builder'; import { DATA_VIEW_FIELD } from '../custom_common/index_selection'; import { MetricIndicator } from './metric_indicator'; @@ -55,7 +55,7 @@ export function CustomMetricIndicatorTypeForm() { - + diff --git a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/custom_metric/metric_indicator.tsx b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/indicator_section/custom_metric/metric_indicator.tsx similarity index 60% rename from x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/custom_metric/metric_indicator.tsx rename to x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/indicator_section/custom_metric/metric_indicator.tsx index 03939dce314b6..519167be5db27 100644 --- a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/custom_metric/metric_indicator.tsx +++ b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/indicator_section/custom_metric/metric_indicator.tsx @@ -26,10 +26,10 @@ import { Controller, useFieldArray, useFormContext } from 'react-hook-form'; import { aggValueToLabel, CUSTOM_METRIC_AGGREGATION_OPTIONS, -} from '../../helpers/aggregation_options'; -import { createOptionsFromFields, Option } from '../../helpers/create_options'; -import { CreateSLOForm } from '../../types'; -import { QueryBuilder } from '../common/query_builder'; +} from '../../../helpers/aggregation_options'; +import { createOptionsFromFields, Option } from '../../../helpers/create_options'; +import { CreateSLOForm } from '../../../types'; +import { QueryBuilder } from '../../common/query_builder'; interface MetricIndicatorProps { type: 'good' | 'total'; @@ -134,95 +134,28 @@ export function MetricIndicator({ {fields?.map((metric, index, arr) => (
        - - - - - {i18n.translate('xpack.slo.sloEdit.customMetric.aggregationLabel', { - defaultMessage: 'Aggregation', - })}{' '} - {metric.name} - - } - > - ( - { - if (selected.length) { - return field.onChange(selected[0].value); - } - field.onChange(''); - }} - selectedOptions={ - !!indexPattern && - !!field.value && - CUSTOM_METRIC_AGGREGATION_OPTIONS.some((agg) => agg.value === field.value) - ? [ - { - value: field.value, - label: aggValueToLabel(field.value), - }, - ] - : [] - } - onSearchChange={(searchValue: string) => { - setAggregationOptions( - CUSTOM_METRIC_AGGREGATION_OPTIONS.filter(({ value }) => - value.includes(searchValue) - ) - ); - }} - options={aggregationOptions} - /> - )} - /> - - - {watch(`indicator.params.${type}.metrics.${index}.aggregation`) !== 'doc_count' && ( + + + - {metricLabel} {metric.name} {metricTooltip} + {i18n.translate('xpack.slo.sloEdit.customMetric.aggregationLabel', { + defaultMessage: 'Aggregation', + })}{' '} + {metric.name} } > ( metricField.name === field.value) + CUSTOM_METRIC_AGGREGATION_OPTIONS.some( + (agg) => agg.value === field.value + ) ? [ { value: field.value, - label: field.value, + label: aggValueToLabel(field.value), }, ] : [] } onSearchChange={(searchValue: string) => { - setOptions( - createOptionsFromFields(metricFields, ({ value }) => + setAggregationOptions( + CUSTOM_METRIC_AGGREGATION_OPTIONS.filter(({ value }) => value.includes(searchValue) ) ); }} - options={options} + options={aggregationOptions} /> )} /> - )} - - - + {watch(`indicator.params.${type}.metrics.${index}.aggregation`) !== 'doc_count' && ( + + + {metricLabel} {metric.name} {metricTooltip} + + } + > + ( + { + if (selected.length) { + return field.onChange(selected[0].value); + } + field.onChange(''); + }} + selectedOptions={ + !!indexPattern && + !!field.value && + metricFields.some((metricField) => metricField.name === field.value) + ? [ + { + value: field.value, + label: field.value, + }, + ] + : [] + } + onSearchChange={(searchValue: string) => { + setOptions( + createOptionsFromFields(metricFields, ({ value }) => + value.includes(searchValue) + ) + ); + }} + options={options} + /> + )} + /> + + + )} + + + + + + } + /> - - } - /> {index !== arr.length - 1 && }
        ))} diff --git a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/histogram/histogram_indicator.tsx b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/indicator_section/histogram/histogram_indicator.tsx similarity index 98% rename from x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/histogram/histogram_indicator.tsx rename to x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/indicator_section/histogram/histogram_indicator.tsx index 009504e5e6979..3b435fa52494b 100644 --- a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/histogram/histogram_indicator.tsx +++ b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/indicator_section/histogram/histogram_indicator.tsx @@ -19,9 +19,9 @@ import { DataView, FieldSpec } from '@kbn/data-views-plugin/common'; import { i18n } from '@kbn/i18n'; import React, { Fragment, useEffect, useState } from 'react'; import { Controller, useFormContext } from 'react-hook-form'; -import { createOptionsFromFields, Option } from '../../helpers/create_options'; -import { CreateSLOForm } from '../../types'; -import { QueryBuilder } from '../common/query_builder'; +import { createOptionsFromFields, Option } from '../../../helpers/create_options'; +import { CreateSLOForm } from '../../../types'; +import { QueryBuilder } from '../../common/query_builder'; interface HistogramIndicatorProps { type: 'good' | 'total'; diff --git a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/histogram/histogram_indicator_type_form.tsx b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/indicator_section/histogram/histogram_indicator_type_form.tsx similarity index 91% rename from x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/histogram/histogram_indicator_type_form.tsx rename to x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/indicator_section/histogram/histogram_indicator_type_form.tsx index 6bb1918dba3c2..2e934c74d9d0e 100644 --- a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/histogram/histogram_indicator_type_form.tsx +++ b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/indicator_section/histogram/histogram_indicator_type_form.tsx @@ -18,11 +18,11 @@ import { FormattedMessage } from '@kbn/i18n-react'; import React from 'react'; import { useFormContext } from 'react-hook-form'; import { IndexAndTimestampField } from '../custom_common/index_and_timestamp_field'; -import { useCreateDataView } from '../../../../hooks/use_create_data_view'; -import { GroupByField } from '../common/group_by_field'; -import { CreateSLOForm } from '../../types'; -import { DataPreviewChart } from '../common/data_preview_chart'; -import { QueryBuilder } from '../common/query_builder'; +import { useCreateDataView } from '../../../../../hooks/use_create_data_view'; +import { GroupByField } from '../../common/group_by_field'; +import { CreateSLOForm } from '../../../types'; +import { DataPreviewChart } from '../../common/data_preview_chart'; +import { QueryBuilder } from '../../common/query_builder'; import { DATA_VIEW_FIELD } from '../custom_common/index_selection'; import { HistogramIndicator } from './histogram_indicator'; @@ -49,7 +49,7 @@ export function HistogramIndicatorTypeForm() { - + diff --git a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/synthetics_availability/synthetics_availability_indicator_type_form.test.tsx b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/indicator_section/synthetics_availability/synthetics_availability_indicator_type_form.test.tsx similarity index 100% rename from x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/synthetics_availability/synthetics_availability_indicator_type_form.test.tsx rename to x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/indicator_section/synthetics_availability/synthetics_availability_indicator_type_form.test.tsx diff --git a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/synthetics_availability/synthetics_availability_indicator_type_form.tsx b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/indicator_section/synthetics_availability/synthetics_availability_indicator_type_form.tsx similarity index 93% rename from x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/synthetics_availability/synthetics_availability_indicator_type_form.tsx rename to x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/indicator_section/synthetics_availability/synthetics_availability_indicator_type_form.tsx index 07f2f86663292..88dbb16d667b6 100644 --- a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/synthetics_availability/synthetics_availability_indicator_type_form.tsx +++ b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/indicator_section/synthetics_availability/synthetics_availability_indicator_type_form.tsx @@ -17,12 +17,12 @@ import moment from 'moment'; import React, { useEffect, useState } from 'react'; import { useFormContext } from 'react-hook-form'; import { DATA_VIEW_FIELD } from '../custom_common/index_selection'; -import { useCreateDataView } from '../../../../hooks/use_create_data_view'; -import { formatAllFilters } from '../../helpers/format_filters'; -import { CreateSLOForm } from '../../types'; -import { DataPreviewChart } from '../common/data_preview_chart'; -import { GroupByCardinality } from '../common/group_by_cardinality'; -import { QueryBuilder } from '../common/query_builder'; +import { useCreateDataView } from '../../../../../hooks/use_create_data_view'; +import { formatAllFilters } from '../../../helpers/format_filters'; +import { CreateSLOForm } from '../../../types'; +import { DataPreviewChart } from '../../common/data_preview_chart'; +import { GroupByCardinality } from '../../common/group_by_cardinality'; +import { QueryBuilder } from '../../common/query_builder'; import { FieldSelector } from '../synthetics_common/field_selector'; export function SyntheticsAvailabilityIndicatorTypeForm() { @@ -74,8 +74,8 @@ export function SyntheticsAvailabilityIndicatorTypeForm() { }, [currentMonitors, setValue]); return ( - - + + - + {fields?.map((metric, index, arr) => ( - - - - - + + + - + + + + + + } + /> - - } - /> {index !== arr.length - 1 && } ))} diff --git a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/timeslice_metric/metric_input.tsx b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/indicator_section/timeslice_metric/metric_input.tsx similarity index 97% rename from x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/timeslice_metric/metric_input.tsx rename to x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/indicator_section/timeslice_metric/metric_input.tsx index ebb539b97dab2..ef798305b20d6 100644 --- a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/timeslice_metric/metric_input.tsx +++ b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/indicator_section/timeslice_metric/metric_input.tsx @@ -16,9 +16,9 @@ import { FieldSpec } from '@kbn/data-views-plugin/common'; import { i18n } from '@kbn/i18n'; import React, { useEffect, useState } from 'react'; import { Controller, useFormContext } from 'react-hook-form'; -import { AGGREGATION_OPTIONS, aggValueToLabel } from '../../helpers/aggregation_options'; -import { createOptionsFromFields, Option } from '../../helpers/create_options'; -import { CreateSLOForm } from '../../types'; +import { AGGREGATION_OPTIONS, aggValueToLabel } from '../../../helpers/aggregation_options'; +import { createOptionsFromFields, Option } from '../../../helpers/create_options'; +import { CreateSLOForm } from '../../../types'; const fieldLabel = i18n.translate('xpack.slo.sloEdit.sliType.timesliceMetric.fieldLabel', { defaultMessage: 'Field', diff --git a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/timeslice_metric/timeslice_metric_indicator.tsx b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/indicator_section/timeslice_metric/timeslice_metric_indicator.tsx similarity index 88% rename from x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/timeslice_metric/timeslice_metric_indicator.tsx rename to x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/indicator_section/timeslice_metric/timeslice_metric_indicator.tsx index 86eede0ba65e2..73bc3135d91ac 100644 --- a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/timeslice_metric/timeslice_metric_indicator.tsx +++ b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/indicator_section/timeslice_metric/timeslice_metric_indicator.tsx @@ -19,15 +19,15 @@ import { FormattedMessage } from '@kbn/i18n-react'; import React from 'react'; import { useFormContext } from 'react-hook-form'; import { IndexAndTimestampField } from '../custom_common/index_and_timestamp_field'; -import { useKibana } from '../../../../hooks/use_kibana'; -import { GroupByField } from '../common/group_by_field'; -import { CreateSLOForm } from '../../types'; -import { DataPreviewChart } from '../common/data_preview_chart'; -import { QueryBuilder } from '../common/query_builder'; +import { useKibana } from '../../../../../hooks/use_kibana'; +import { GroupByField } from '../../common/group_by_field'; +import { CreateSLOForm } from '../../../types'; +import { DataPreviewChart } from '../../common/data_preview_chart'; +import { QueryBuilder } from '../../common/query_builder'; import { DATA_VIEW_FIELD } from '../custom_common/index_selection'; import { MetricIndicator } from './metric_indicator'; -import { COMPARATOR_MAPPING } from '../../constants'; -import { useCreateDataView } from '../../../../hooks/use_create_data_view'; +import { COMPARATOR_MAPPING } from '../../../constants'; +import { useCreateDataView } from '../../../../../hooks/use_create_data_view'; export { NEW_TIMESLICE_METRIC } from './metric_indicator'; @@ -54,7 +54,7 @@ export function TimesliceMetricIndicatorTypeForm() { - + diff --git a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/slo_edit_form.tsx b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/slo_edit_form.tsx index 7ffc274ffce12..9082d5367670e 100644 --- a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/slo_edit_form.tsx +++ b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/slo_edit_form.tsx @@ -5,43 +5,56 @@ * 2.0. */ -import { EuiFlexGroup, EuiSpacer, EuiSteps } from '@elastic/eui'; +import { EuiFlexGroup, EuiSteps } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import type { GetSLOResponse } from '@kbn/slo-schema'; +import type { CreateSLOInput, GetSLOResponse } from '@kbn/slo-schema'; +import { RecursivePartial } from '@kbn/utility-types'; import React from 'react'; import { FormProvider, useForm } from 'react-hook-form'; -import { RecursivePartial } from '@kbn/utility-types'; -import { SloEditFormFooter } from './slo_edit_form_footer'; import { SLO_EDIT_FORM_DEFAULT_VALUES } from '../constants'; -import { transformSloResponseToCreateSloForm } from '../helpers/process_slo_form_values'; +import { + transformPartialSLOStateToFormState, + transformSloResponseToCreateSloForm, +} from '../helpers/process_slo_form_values'; import { useParseUrlState } from '../hooks/use_parse_url_state'; import { useSectionFormValidation } from '../hooks/use_section_form_validation'; import { useShowSections } from '../hooks/use_show_sections'; import { CreateSLOForm } from '../types'; import { SloEditFormDescriptionSection } from './slo_edit_form_description_section'; +import { SloEditFormFooter } from './slo_edit_form_footer'; import { SloEditFormIndicatorSection } from './slo_edit_form_indicator_section'; import { SloEditFormObjectiveSection } from './slo_edit_form_objective_section'; export interface Props { slo?: GetSLOResponse; - initialValues?: RecursivePartial; + initialValues?: RecursivePartial; onSave?: () => void; } -export const maxWidth = 900; - export function SloEditForm({ slo, initialValues, onSave }: Props) { const isEditMode = slo !== undefined; + const isFlyoutMode = initialValues !== undefined && onSave !== undefined; - const sloFormValuesFromUrlState = useParseUrlState() ?? (initialValues as CreateSLOForm); + const sloFormValuesFromFlyoutState = isFlyoutMode + ? transformPartialSLOStateToFormState(initialValues) + : undefined; + const sloFormValuesFromUrlState = useParseUrlState(); const sloFormValuesFromSloResponse = transformSloResponseToCreateSloForm(slo); - const methods = useForm({ - defaultValues: sloFormValuesFromUrlState ?? SLO_EDIT_FORM_DEFAULT_VALUES, - values: sloFormValuesFromUrlState ? sloFormValuesFromUrlState : sloFormValuesFromSloResponse, + const form = useForm({ + defaultValues: isFlyoutMode + ? sloFormValuesFromFlyoutState + : sloFormValuesFromUrlState + ? sloFormValuesFromUrlState + : sloFormValuesFromSloResponse ?? SLO_EDIT_FORM_DEFAULT_VALUES, + values: isFlyoutMode + ? sloFormValuesFromFlyoutState + : sloFormValuesFromUrlState + ? sloFormValuesFromUrlState + : sloFormValuesFromSloResponse, mode: 'all', }); - const { watch, getFieldState, getValues, formState } = methods; + const { watch, getFieldState, getValues, formState } = form; const { isIndicatorSectionValid, isObjectiveSectionValid, isDescriptionSectionValid } = useSectionFormValidation({ @@ -59,41 +72,37 @@ export function SloEditForm({ slo, initialValues, onSave }: Props) { ); return ( - <> - - - , - status: isIndicatorSectionValid ? 'complete' : 'incomplete', - }, - { - title: i18n.translate('xpack.slo.sloEdit.objectives.title', { - defaultMessage: 'Set objectives', - }), - children: showObjectiveSection ? : null, - status: showObjectiveSection && isObjectiveSectionValid ? 'complete' : 'incomplete', - }, - { - title: i18n.translate('xpack.slo.sloEdit.description.title', { - defaultMessage: 'Describe SLO', - }), - children: showDescriptionSection ? : null, - status: - showDescriptionSection && isDescriptionSectionValid ? 'complete' : 'incomplete', - }, - ]} - /> - - + + + , + status: isIndicatorSectionValid ? 'complete' : 'incomplete', + }, + { + title: i18n.translate('xpack.slo.sloEdit.objectives.title', { + defaultMessage: 'Set objectives', + }), + children: showObjectiveSection ? : null, + status: showObjectiveSection && isObjectiveSectionValid ? 'complete' : 'incomplete', + }, + { + title: i18n.translate('xpack.slo.sloEdit.description.title', { + defaultMessage: 'Describe SLO', + }), + children: showDescriptionSection ? : null, + status: + showDescriptionSection && isDescriptionSectionValid ? 'complete' : 'incomplete', + }, + ]} + /> - - - - + + + ); } diff --git a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/slo_edit_form_description_section.tsx b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/slo_edit_form_description_section.tsx index a210021674f6b..f242669e566d2 100644 --- a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/slo_edit_form_description_section.tsx +++ b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/slo_edit_form_description_section.tsx @@ -9,8 +9,6 @@ import { EuiComboBox, EuiComboBoxOptionOption, EuiFieldText, - EuiFlexGroup, - EuiFlexItem, EuiFormRow, EuiPanel, EuiTextArea, @@ -20,9 +18,9 @@ import { i18n } from '@kbn/i18n'; import React from 'react'; import { Controller, useFormContext } from 'react-hook-form'; import { useFetchSLOSuggestions } from '../hooks/use_fetch_suggestions'; -import { OptionalText } from './common/optional_text'; import { CreateSLOForm } from '../types'; -import { maxWidth } from './slo_edit_form'; +import { OptionalText } from './common/optional_text'; +import { MAX_WIDTH } from '../constants'; export function SloEditFormDescriptionSection() { const { control, getFieldState } = useFormContext(); @@ -37,129 +35,117 @@ export function SloEditFormDescriptionSection() { hasBorder={false} hasShadow={false} paddingSize="none" - style={{ maxWidth }} + style={{ maxWidth: MAX_WIDTH }} data-test-subj="sloEditFormDescriptionSection" > - - - - ( - - )} + + ( + - - + )} + /> +
        - - } - > - ( - + } + > + ( + - - + )} + /> +
        - - - ( - { - if (selected.length) { - return field.onChange(selected.map((opts) => opts.value)); - } + + ( + { + if (selected.length) { + return field.onChange(selected.map((opts) => opts.value)); + } - field.onChange([]); - }} - onCreateOption={( - searchValue: string, - options: EuiComboBoxOptionOption[] = [] - ) => { - const normalizedSearchValue = searchValue.trim().toLowerCase(); + field.onChange([]); + }} + onCreateOption={(searchValue: string, options: EuiComboBoxOptionOption[] = []) => { + const normalizedSearchValue = searchValue.trim().toLowerCase(); - if (!normalizedSearchValue) { - return; - } - const values = field.value ?? []; + if (!normalizedSearchValue) { + return; + } + const values = field.value ?? []; - if ( - values.findIndex( - (tag) => tag.trim().toLowerCase() === normalizedSearchValue - ) === -1 - ) { - field.onChange([...values, searchValue]); - } - }} - isClearable - data-test-subj="sloEditTagsSelector" - /> - )} + if ( + values.findIndex((tag) => tag.trim().toLowerCase() === normalizedSearchValue) === + -1 + ) { + field.onChange([...values, searchValue]); + } + }} + isClearable + data-test-subj="sloEditTagsSelector" /> - - -
        + )} + /> + ); } diff --git a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/slo_edit_form_indicator_section.tsx b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/slo_edit_form_indicator_section.tsx index 156f45c2c982c..4d30bef7ac692 100644 --- a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/slo_edit_form_indicator_section.tsx +++ b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/slo_edit_form_indicator_section.tsx @@ -7,19 +7,20 @@ import { EuiFormRow, EuiPanel, EuiSelect, EuiSpacer } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; +import { assertNever } from '@kbn/std'; import React, { useMemo } from 'react'; import { Controller, useFormContext } from 'react-hook-form'; import { SLI_OPTIONS } from '../constants'; import { useUnregisterFields } from '../hooks/use_unregister_fields'; import { CreateSLOForm } from '../types'; -import { ApmAvailabilityIndicatorTypeForm } from './apm_availability/apm_availability_indicator_type_form'; -import { ApmLatencyIndicatorTypeForm } from './apm_latency/apm_latency_indicator_type_form'; -import { SyntheticsAvailabilityIndicatorTypeForm } from './synthetics_availability/synthetics_availability_indicator_type_form'; -import { CustomKqlIndicatorTypeForm } from './custom_kql/custom_kql_indicator_type_form'; -import { CustomMetricIndicatorTypeForm } from './custom_metric/custom_metric_type_form'; -import { HistogramIndicatorTypeForm } from './histogram/histogram_indicator_type_form'; -import { maxWidth } from './slo_edit_form'; -import { TimesliceMetricIndicatorTypeForm } from './timeslice_metric/timeslice_metric_indicator'; +import { MAX_WIDTH } from '../constants'; +import { ApmAvailabilityIndicatorTypeForm } from './indicator_section/apm_availability/apm_availability_indicator_type_form'; +import { ApmLatencyIndicatorTypeForm } from './indicator_section/apm_latency/apm_latency_indicator_type_form'; +import { CustomKqlIndicatorTypeForm } from './indicator_section/custom_kql/custom_kql_indicator_type_form'; +import { CustomMetricIndicatorTypeForm } from './indicator_section/custom_metric/custom_metric_type_form'; +import { HistogramIndicatorTypeForm } from './indicator_section/histogram/histogram_indicator_type_form'; +import { SyntheticsAvailabilityIndicatorTypeForm } from './indicator_section/synthetics_availability/synthetics_availability_indicator_type_form'; +import { TimesliceMetricIndicatorTypeForm } from './indicator_section/timeslice_metric/timeslice_metric_indicator'; interface SloEditFormIndicatorSectionProps { isEditMode: boolean; @@ -48,7 +49,7 @@ export function SloEditFormIndicatorSection({ isEditMode }: SloEditFormIndicator case 'sli.metric.timeslice': return ; default: - return null; + assertNever(indicatorType); } }, [indicatorType]); @@ -57,7 +58,7 @@ export function SloEditFormIndicatorSection({ isEditMode }: SloEditFormIndicator hasBorder={false} hasShadow={false} paddingSize="none" - style={{ maxWidth }} + style={{ maxWidth: MAX_WIDTH }} data-test-subj="sloEditFormIndicatorSection" > {!isEditMode && ( @@ -78,7 +79,7 @@ export function SloEditFormIndicatorSection({ isEditMode }: SloEditFormIndicator )} /> - + )} {indicatorTypeForm} diff --git a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/slo_edit_form_objective_section.tsx b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/slo_edit_form_objective_section.tsx index 15c51b1b86ce4..65e4a25a86c39 100644 --- a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/slo_edit_form_objective_section.tsx +++ b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/components/slo_edit_form_objective_section.tsx @@ -7,15 +7,14 @@ import { EuiCallOut, - EuiCheckbox, EuiFieldNumber, EuiFlexGrid, + EuiFlexGroup, EuiFlexItem, EuiFormRow, EuiIconTip, EuiPanel, EuiSelect, - EuiSpacer, useGeneratedHtmlId, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; @@ -30,7 +29,8 @@ import { TIMEWINDOW_TYPE_OPTIONS, } from '../constants'; import { CreateSLOForm } from '../types'; -import { maxWidth } from './slo_edit_form'; +import { MAX_WIDTH } from '../constants'; +import { AdvancedSettings } from './indicator_section/advanced_settings/advanced_settings'; import { SloEditFormObjectiveSectionTimeslices } from './slo_edit_form_objective_section_timeslices'; export function SloEditFormObjectiveSection() { @@ -44,7 +44,6 @@ export function SloEditFormObjectiveSection() { const budgetingSelect = useGeneratedHtmlId({ prefix: 'budgetingSelect' }); const timeWindowTypeSelect = useGeneratedHtmlId({ prefix: 'timeWindowTypeSelect' }); const timeWindowSelect = useGeneratedHtmlId({ prefix: 'timeWindowSelect' }); - const preventBackfillCheckbox = useGeneratedHtmlId({ prefix: 'preventBackfill' }); const timeWindowType = watch('timeWindow.type'); const indicator = watch('indicator.type'); @@ -91,237 +90,199 @@ export function SloEditFormObjectiveSection() { hasBorder={false} hasShadow={false} paddingSize="none" - style={{ maxWidth }} + style={{ maxWidth: MAX_WIDTH }} data-test-subj="sloEditFormObjectiveSection" > - - - - {i18n.translate('xpack.slo.sloEdit.timeWindowType.label', { - defaultMessage: 'Time window', - })}{' '} - - - } - > - ( - - )} - /> - - - - - {i18n.translate('xpack.slo.sloEdit.timeWindowDuration.label', { - defaultMessage: 'Duration', - })}{' '} - - - } - > - ( - - )} - /> - - - - - - {indicator === 'sli.metric.timeslice' && ( - - -

        - + + + + {i18n.translate('xpack.slo.sloEdit.timeWindowType.label', { + defaultMessage: 'Time window', + })}{' '} + + + } + > + ( + + )} /> -

        -
        - -
        - )} - - {indicator === 'sli.synthetics.availability' && ( - - -

        - + + + + {i18n.translate('xpack.slo.sloEdit.timeWindowDuration.label', { + defaultMessage: 'Duration', + })}{' '} + + + } + > + ( + + )} /> -

        -
        - -
        - )} + +
        + - - - - {i18n.translate('xpack.slo.sloEdit.budgetingMethod.label', { - defaultMessage: 'Budgeting method', - })}{' '} - - - } - > - ( - + +

        + - )} - /> - - +

        +
        +
        + )} - {watch('budgetingMethod') === 'timeslices' ? ( - - ) : null} -
        + {indicator === 'sli.synthetics.availability' && ( + + +

        + +

        +
        +
        + )} - + + + + {i18n.translate('xpack.slo.sloEdit.budgetingMethod.label', { + defaultMessage: 'Budgeting method', + })}{' '} + + + } + > + ( + + )} + /> + + - - - - {i18n.translate('xpack.slo.sloEdit.targetSlo.label', { - defaultMessage: 'Target / SLO (%)', - })}{' '} - - - } - > - ( - onChange(event.target.value)} - /> - )} - /> - - - + {watch('budgetingMethod') === 'timeslices' ? ( + + ) : null} + - + + + + {i18n.translate('xpack.slo.sloEdit.targetSlo.label', { + defaultMessage: 'Target / SLO (%)', + })}{' '} + + + } + > + ( + onChange(event.target.value)} + /> + )} + /> + + + - - - - ( - - {i18n.translate('xpack.slo.sloEdit.settings.preventInitialBackfill.label', { - defaultMessage: 'Prevent initial backfill of data', - })} - - - } - checked={Boolean(field.value)} - onChange={(event: any) => onChange(event.target.checked)} - /> - )} - /> - - - + +
        ); } diff --git a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/constants.ts b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/constants.ts index 123ebdc660947..55dfec93f8a33 100644 --- a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/constants.ts +++ b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/constants.ts @@ -33,6 +33,8 @@ import { import { SYNTHETICS_DEFAULT_GROUPINGS, SYNTHETICS_INDEX_PATTERN } from '../../../common/constants'; import { CreateSLOForm } from './types'; +export const MAX_WIDTH = 900; + export const SLI_OPTIONS: Array<{ value: IndicatorType; text: string; @@ -205,6 +207,13 @@ export const SYNTHETICS_AVAILABILITY_DEFAULT_VALUES: SyntheticsAvailabilityIndic }, }; +export const SETTINGS_DEFAULT_VALUES = { + frequency: 1, + preventInitialBackfill: false, + syncDelay: 1, + syncField: null, +}; + export const SLO_EDIT_FORM_DEFAULT_VALUES: CreateSLOForm = { name: '', description: '', @@ -219,9 +228,7 @@ export const SLO_EDIT_FORM_DEFAULT_VALUES: CreateSLOForm = { target: 99, }, groupBy: ALL_VALUE, - settings: { - preventInitialBackfill: false, - }, + settings: SETTINGS_DEFAULT_VALUES, }; export const SLO_EDIT_FORM_DEFAULT_VALUES_CUSTOM_METRIC: CreateSLOForm = { @@ -238,9 +245,7 @@ export const SLO_EDIT_FORM_DEFAULT_VALUES_CUSTOM_METRIC: CreateSLOForm = { target: 99, }, groupBy: ALL_VALUE, - settings: { - preventInitialBackfill: false, - }, + settings: SETTINGS_DEFAULT_VALUES, }; export const SLO_EDIT_FORM_DEFAULT_VALUES_SYNTHETICS_AVAILABILITY: CreateSLOForm = { @@ -257,9 +262,7 @@ export const SLO_EDIT_FORM_DEFAULT_VALUES_SYNTHETICS_AVAILABILITY: CreateSLOForm target: 99, }, groupBy: SYNTHETICS_DEFAULT_GROUPINGS, - settings: { - preventInitialBackfill: false, - }, + settings: SETTINGS_DEFAULT_VALUES, }; export const COMPARATOR_GT = i18n.translate('xpack.slo.sloEdit.sliType.timesliceMetric.gtLabel', { diff --git a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/helpers/__snapshots__/process_slo_form_values.test.ts.snap b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/helpers/__snapshots__/process_slo_form_values.test.ts.snap index 3f7ac0ce83beb..78f63a4b8f7bc 100644 --- a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/helpers/__snapshots__/process_slo_form_values.test.ts.snap +++ b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/helpers/__snapshots__/process_slo_form_values.test.ts.snap @@ -26,7 +26,10 @@ Object { "target": 99, }, "settings": Object { + "frequency": 1, "preventInitialBackfill": false, + "syncDelay": 1, + "syncField": null, }, "tags": Array [], "timeWindow": Object { @@ -74,7 +77,10 @@ Object { "target": 99, }, "settings": Object { + "frequency": 1, "preventInitialBackfill": false, + "syncDelay": 1, + "syncField": null, }, "tags": Array [], "timeWindow": Object { @@ -104,7 +110,10 @@ Object { "target": 99, }, "settings": Object { + "frequency": 1, "preventInitialBackfill": false, + "syncDelay": 1, + "syncField": null, }, "tags": Array [], "timeWindow": Object { @@ -146,7 +155,10 @@ Object { "target": 99, }, "settings": Object { + "frequency": 1, "preventInitialBackfill": false, + "syncDelay": 1, + "syncField": null, }, "tags": Array [], "timeWindow": Object { @@ -178,7 +190,10 @@ Object { "timesliceWindow": "2", }, "settings": Object { + "frequency": 1, "preventInitialBackfill": false, + "syncDelay": 1, + "syncField": null, }, "tags": Array [], "timeWindow": Object { @@ -208,7 +223,10 @@ Object { "target": 99, }, "settings": Object { + "frequency": 1, "preventInitialBackfill": false, + "syncDelay": 1, + "syncField": null, }, "tags": Array [], "timeWindow": Object { @@ -218,6 +236,105 @@ Object { } `; +exports[`Transform partial URL state into form state settings handles optional 'syncField' URL state 1`] = ` +Object { + "budgetingMethod": "occurrences", + "description": "", + "groupBy": "*", + "indicator": Object { + "params": Object { + "filter": "", + "good": "", + "index": "", + "timestampField": "", + "total": "", + }, + "type": "sli.kql.custom", + }, + "name": "", + "objective": Object { + "target": 99, + }, + "settings": Object { + "frequency": 1, + "preventInitialBackfill": false, + "syncDelay": 1, + "syncField": "override-field", + }, + "tags": Array [], + "timeWindow": Object { + "duration": "30d", + "type": "rolling", + }, +} +`; + +exports[`Transform partial URL state into form state settings handles partial 'settings' URL state 1`] = ` +Object { + "budgetingMethod": "occurrences", + "description": "", + "groupBy": "*", + "indicator": Object { + "params": Object { + "filter": "", + "good": "", + "index": "", + "timestampField": "", + "total": "", + }, + "type": "sli.kql.custom", + }, + "name": "", + "objective": Object { + "target": 99, + }, + "settings": Object { + "frequency": 1, + "preventInitialBackfill": false, + "syncDelay": 12, + "syncField": null, + }, + "tags": Array [], + "timeWindow": Object { + "duration": "30d", + "type": "rolling", + }, +} +`; + +exports[`Transform partial URL state into form state settings handles the 'settings' URL state 1`] = ` +Object { + "budgetingMethod": "occurrences", + "description": "", + "groupBy": "*", + "indicator": Object { + "params": Object { + "filter": "", + "good": "", + "index": "", + "timestampField": "", + "total": "", + }, + "type": "sli.kql.custom", + }, + "name": "", + "objective": Object { + "target": 99, + }, + "settings": Object { + "frequency": 1, + "preventInitialBackfill": true, + "syncDelay": 180, + "syncField": null, + }, + "tags": Array [], + "timeWindow": Object { + "duration": "30d", + "type": "rolling", + }, +} +`; + exports[`Transform partial URL state into form state with 'indicator' in URL state handles partial APM Availability state 1`] = ` Object { "budgetingMethod": "occurrences", @@ -239,7 +356,10 @@ Object { "target": 99, }, "settings": Object { + "frequency": 1, "preventInitialBackfill": false, + "syncDelay": 1, + "syncField": null, }, "tags": Array [], "timeWindow": Object { @@ -271,7 +391,10 @@ Object { "target": 99, }, "settings": Object { + "frequency": 1, "preventInitialBackfill": false, + "syncDelay": 1, + "syncField": null, }, "tags": Array [], "timeWindow": Object { @@ -301,7 +424,10 @@ Object { "target": 99, }, "settings": Object { + "frequency": 1, "preventInitialBackfill": false, + "syncDelay": 1, + "syncField": null, }, "tags": Array [], "timeWindow": Object { @@ -331,7 +457,10 @@ Object { "target": 99, }, "settings": Object { + "frequency": 1, "preventInitialBackfill": false, + "syncDelay": 1, + "syncField": null, }, "tags": Array [], "timeWindow": Object { diff --git a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/helpers/format_filters.test.ts b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/helpers/format_filters.test.ts index 16ad733619e65..c79571d4ab77b 100644 --- a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/helpers/format_filters.test.ts +++ b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/helpers/format_filters.test.ts @@ -4,7 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { getGroupByCardinalityFilters } from '../components/synthetics_availability/synthetics_availability_indicator_type_form'; +import { getGroupByCardinalityFilters } from '../components/indicator_section/synthetics_availability/synthetics_availability_indicator_type_form'; import { formatAllFilters } from './format_filters'; describe('formatAllFilters', () => { diff --git a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/helpers/process_slo_form_values.test.ts b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/helpers/process_slo_form_values.test.ts index a69cd1152985c..7518e1c679c87 100644 --- a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/helpers/process_slo_form_values.test.ts +++ b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/helpers/process_slo_form_values.test.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { transformPartialUrlStateToFormState as transform } from './process_slo_form_values'; +import { transformPartialSLOStateToFormState as transform } from './process_slo_form_values'; describe('Transform partial URL state into form state', () => { describe("with 'indicator' in URL state", () => { @@ -121,4 +121,20 @@ describe('Transform partial URL state into form state', () => { }) ).toMatchSnapshot(); }); + + describe('settings', () => { + it("handles the 'settings' URL state", () => { + expect( + transform({ settings: { preventInitialBackfill: true, syncDelay: '3h' } }) + ).toMatchSnapshot(); + }); + + it("handles partial 'settings' URL state", () => { + expect(transform({ settings: { syncDelay: '12m' } })).toMatchSnapshot(); + }); + + it("handles optional 'syncField' URL state", () => { + expect(transform({ settings: { syncField: 'override-field' } })).toMatchSnapshot(); + }); + }); }); diff --git a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/helpers/process_slo_form_values.ts b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/helpers/process_slo_form_values.ts index 8bbbcf9d2fee9..81d6714dac2e5 100644 --- a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/helpers/process_slo_form_values.ts +++ b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/helpers/process_slo_form_values.ts @@ -9,13 +9,14 @@ import { CreateSLOInput, GetSLOResponse, Indicator, UpdateSLOInput } from '@kbn/ import { assertNever } from '@kbn/std'; import { RecursivePartial } from '@kbn/utility-types'; import { cloneDeep } from 'lodash'; -import { toDuration } from '../../../utils/slo/duration'; +import { toDuration, toMinutes } from '../../../utils/slo/duration'; import { APM_AVAILABILITY_DEFAULT_VALUES, APM_LATENCY_DEFAULT_VALUES, CUSTOM_KQL_DEFAULT_VALUES, CUSTOM_METRIC_DEFAULT_VALUES, HISTOGRAM_DEFAULT_VALUES, + SETTINGS_DEFAULT_VALUES, SLO_EDIT_FORM_DEFAULT_VALUES, SLO_EDIT_FORM_DEFAULT_VALUES_SYNTHETICS_AVAILABILITY, SYNTHETICS_AVAILABILITY_DEFAULT_VALUES, @@ -52,6 +53,13 @@ export function transformSloResponseToCreateSloForm( tags: values.tags, settings: { preventInitialBackfill: values.settings?.preventInitialBackfill ?? false, + syncDelay: values.settings?.syncDelay + ? toMinutes(toDuration(values.settings.syncDelay)) + : SETTINGS_DEFAULT_VALUES.syncDelay, + frequency: values.settings?.frequency + ? toMinutes(toDuration(values.settings.frequency)) + : SETTINGS_DEFAULT_VALUES.frequency, + syncField: values.settings?.syncField ?? null, }, }; } @@ -80,7 +88,10 @@ export function transformCreateSLOFormToCreateSLOInput(values: CreateSLOForm): C tags: values.tags, groupBy: [values.groupBy].flat(), settings: { - preventInitialBackfill: values.settings?.preventInitialBackfill ?? false, + preventInitialBackfill: values.settings.preventInitialBackfill, + syncDelay: `${values.settings.syncDelay ?? SETTINGS_DEFAULT_VALUES.syncDelay}m`, + frequency: `${values.settings.frequency ?? SETTINGS_DEFAULT_VALUES.frequency}m`, + syncField: values.settings.syncField, }, }; } @@ -109,7 +120,10 @@ export function transformValuesToUpdateSLOInput(values: CreateSLOForm): UpdateSL tags: values.tags, groupBy: [values.groupBy].flat(), settings: { - preventInitialBackfill: values.settings?.preventInitialBackfill ?? false, + preventInitialBackfill: values.settings.preventInitialBackfill, + syncDelay: `${values.settings.syncDelay ?? SETTINGS_DEFAULT_VALUES.syncDelay}m`, + frequency: `${values.settings.frequency ?? SETTINGS_DEFAULT_VALUES.frequency}m`, + syncField: values.settings.syncField, }, }; } @@ -165,7 +179,7 @@ function transformPartialIndicatorState( } } -export function transformPartialUrlStateToFormState( +export function transformPartialSLOStateToFormState( values: RecursivePartial ): CreateSLOForm { let state: CreateSLOForm; @@ -189,8 +203,8 @@ export function transformPartialUrlStateToFormState( if (values.description) { state.description = values.description; } - if (!!values.tags) { - state.tags = values.tags as string[]; + if (values.tags) { + state.tags = [values.tags].flat().filter((tag) => !!tag) as string[]; } if (values.objective) { @@ -220,8 +234,19 @@ export function transformPartialUrlStateToFormState( state.timeWindow = { duration: values.timeWindow.duration, type: values.timeWindow.type }; } - if (!!values.settings?.preventInitialBackfill) { - state.settings = { preventInitialBackfill: values.settings.preventInitialBackfill }; + if (!!values.settings) { + if (values.settings.preventInitialBackfill) { + state.settings.preventInitialBackfill = values.settings.preventInitialBackfill; + } + if (values.settings.syncDelay) { + state.settings.syncDelay = toMinutes(toDuration(values.settings.syncDelay)); + } + if (values.settings.frequency) { + state.settings.frequency = toMinutes(toDuration(values.settings.frequency)); + } + if (values.settings.syncField) { + state.settings.syncField = values.settings.syncField; + } } return state; diff --git a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/hooks/use_parse_url_state.ts b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/hooks/use_parse_url_state.ts index 2c305feda3c06..9ada81ea84387 100644 --- a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/hooks/use_parse_url_state.ts +++ b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/hooks/use_parse_url_state.ts @@ -10,7 +10,7 @@ import { CreateSLOInput } from '@kbn/slo-schema'; import { RecursivePartial } from '@kbn/utility-types'; import { useHistory } from 'react-router-dom'; import { useMemo } from 'react'; -import { transformPartialUrlStateToFormState } from '../helpers/process_slo_form_values'; +import { transformPartialSLOStateToFormState } from '../helpers/process_slo_form_values'; import { CreateSLOForm } from '../types'; export function useParseUrlState(): CreateSLOForm | undefined { @@ -25,6 +25,6 @@ export function useParseUrlState(): CreateSLOForm | undefined { const urlState = urlStateStorage.get>('_a'); - return !!urlState ? transformPartialUrlStateToFormState(urlState) : undefined; + return !!urlState ? transformPartialSLOStateToFormState(urlState) : undefined; }, [history]); } diff --git a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/hooks/use_section_form_validation.ts b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/hooks/use_section_form_validation.ts index 7d75359f4cd40..94ffc92adedb4 100644 --- a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/hooks/use_section_form_validation.ts +++ b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/hooks/use_section_form_validation.ts @@ -220,8 +220,10 @@ export function useSectionFormValidation({ getFieldState, getValues, formState, 'objective.target', 'objective.timesliceTarget', 'objective.timesliceWindow', + 'settings.syncDelay', + 'settings.frequency', ] as const - ).every((field) => getFieldState(field).error === undefined); + ).every((field) => !getFieldState(field).invalid); const isDescriptionSectionValid = !getFieldState('name').invalid && diff --git a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/hooks/use_unregister_fields.ts b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/hooks/use_unregister_fields.ts index 9d7752f190344..eb7a77f822660 100644 --- a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/hooks/use_unregister_fields.ts +++ b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/hooks/use_unregister_fields.ts @@ -19,8 +19,8 @@ import { CUSTOM_METRIC_DEFAULT_VALUES, HISTOGRAM_DEFAULT_VALUES, SLO_EDIT_FORM_DEFAULT_VALUES, - TIMESLICE_METRIC_DEFAULT_VALUES, SLO_EDIT_FORM_DEFAULT_VALUES_SYNTHETICS_AVAILABILITY, + TIMESLICE_METRIC_DEFAULT_VALUES, } from '../constants'; import { CreateSLOForm } from '../types'; diff --git a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/shared_flyout/slo_add_form_flyout.tsx b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/shared_flyout/slo_add_form_flyout.tsx index 98c76b190aa1a..f71d7caa80d17 100644 --- a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/shared_flyout/slo_add_form_flyout.tsx +++ b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/shared_flyout/slo_add_form_flyout.tsx @@ -7,12 +7,11 @@ import { EuiFlyout, EuiFlyoutBody, EuiFlyoutFooter, EuiFlyoutHeader, EuiTitle } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; +import { CreateSLOInput } from '@kbn/slo-schema'; import { RecursivePartial } from '@kbn/utility-types'; -import { merge } from 'lodash'; import React from 'react'; import { OutPortal, createHtmlPortalNode } from 'react-reverse-portal'; import { SloEditForm } from '../components/slo_edit_form'; -import { CreateSLOForm } from '../types'; export const sloEditFormFooterPortal = createHtmlPortalNode(); @@ -22,7 +21,7 @@ export default function SloAddFormFlyout({ initialValues, }: { onClose: () => void; - initialValues?: RecursivePartial; + initialValues?: RecursivePartial; }) { return ( - + diff --git a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/slo_edit.test.tsx b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/slo_edit.test.tsx index abc60d6a00352..8d52ed914302c 100644 --- a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/slo_edit.test.tsx +++ b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/slo_edit.test.tsx @@ -423,11 +423,11 @@ describe('SLO Edit Page', () => { jest.spyOn(Router, 'useParams').mockReturnValue({ sloId: '123' }); history.push( - '/slos/123/edit?_a=(name:%27updated-name%27,indicator:(params:(environment:prod,service:cartService),type:sli.apm.transactionDuration),objective:(target:0.92))' + '/slos/edit/123?_a=(name:%27updated-name%27,indicator:(params:(environment:prod,service:cartService),type:sli.apm.transactionDuration),objective:(target:0.92))' ); jest .spyOn(Router, 'useLocation') - .mockReturnValue({ pathname: '/slos/123/edit', search: '', state: '', hash: '' }); + .mockReturnValue({ pathname: '/slos/edit/123', search: '', state: '', hash: '' }); useFetchSloMock.mockReturnValue({ isLoading: false, data: slo }); @@ -463,8 +463,7 @@ describe('SLO Edit Page', () => { jest.spyOn(Router, 'useParams').mockReturnValue({ sloId: '123' }); jest .spyOn(Router, 'useLocation') - .mockReturnValue({ pathname: '/slos/123/edit', search: '', state: '', hash: '' }); - + .mockReturnValue({ pathname: '/slos/edit/123', search: '', state: '', hash: '' }); useFetchSloMock.mockReturnValue({ isLoading: false, data: slo }); const { getByTestId } = render(); diff --git a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/slo_edit.tsx b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/slo_edit.tsx index b014bdb1d6dec..0a563bbe75b44 100644 --- a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/slo_edit.tsx +++ b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/slo_edit.tsx @@ -12,10 +12,10 @@ import { useParams } from 'react-router-dom'; import { paths } from '../../../common/locators/paths'; import { HeaderMenu } from '../../components/header_menu/header_menu'; import { useFetchSloDetails } from '../../hooks/use_fetch_slo_details'; +import { useKibana } from '../../hooks/use_kibana'; import { useLicense } from '../../hooks/use_license'; import { usePermissions } from '../../hooks/use_permissions'; import { usePluginContext } from '../../hooks/use_plugin_context'; -import { useKibana } from '../../hooks/use_kibana'; import { SloEditForm } from './components/slo_edit_form'; export function SloEditPage() { diff --git a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/types.ts b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/types.ts index 5eef9a2d0e5ba..6584e52404bc5 100644 --- a/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/types.ts +++ b/x-pack/plugins/observability_solution/slo/public/pages/slo_edit/types.ts @@ -25,5 +25,8 @@ export interface CreateSLOForm { groupBy: string[] | string; settings: { preventInitialBackfill: boolean; + syncDelay: number; // in minutes + frequency: number; // in minutes + syncField: string | null; }; } diff --git a/x-pack/plugins/observability_solution/slo/public/utils/slo/remote_slo_urls.test.ts b/x-pack/plugins/observability_solution/slo/public/utils/slo/remote_slo_urls.test.ts index 3c0495fd1bc9b..6f44d13150819 100644 --- a/x-pack/plugins/observability_solution/slo/public/utils/slo/remote_slo_urls.test.ts +++ b/x-pack/plugins/observability_solution/slo/public/utils/slo/remote_slo_urls.test.ts @@ -51,7 +51,7 @@ describe('remote SLO URLs Utils', () => { `"https://cloud.elast.co/app/slos/edit/fixed-id"` ); expect(createRemoteSloCloneUrl(remoteSlo)).toMatchInlineSnapshot( - `"https://cloud.elast.co/app/slos/create?_a=(budgetingMethod:occurrences,createdAt:%272022-12-29T10:11:12.000Z%27,description:%27some%20description%20useful%27,enabled:!t,groupBy:%27*%27,groupings:(),indicator:(params:(filter:%27baz:%20foo%20and%20bar%20%3E%202%27,good:%27http_status:%202xx%27,index:some-index,timestampField:custom_timestamp,total:%27a%20query%27),type:sli.kql.custom),instanceId:%27*%27,meta:(),name:%27[Copy]%20super%20important%20level%20service%27,objective:(target:0.98),remote:(kibanaUrl:%27https:/cloud.elast.co/kibana%27,remoteName:remote_cluster),revision:1,settings:(frequency:%271m%27,preventInitialBackfill:!f,syncDelay:%271m%27),summary:(errorBudget:(consumed:0.064,initial:0.02,isEstimated:!f,remaining:0.936),fiveMinuteBurnRate:0,oneDayBurnRate:0,oneHourBurnRate:0,sliValue:0.99872,status:HEALTHY),tags:!(k8s,production,critical),timeWindow:(duration:%2730d%27,type:rolling),updatedAt:%272022-12-29T10:11:12.000Z%27,version:2)"` + `"https://cloud.elast.co/app/slos/create?_a=(budgetingMethod:occurrences,createdAt:%272022-12-29T10:11:12.000Z%27,description:%27some%20description%20useful%27,enabled:!t,groupBy:%27*%27,groupings:(),indicator:(params:(dataViewId:some-data-view-id,filter:%27baz:%20foo%20and%20bar%20%3E%202%27,good:%27http_status:%202xx%27,index:some-index,timestampField:custom_timestamp,total:%27a%20query%27),type:sli.kql.custom),instanceId:%27*%27,meta:(),name:%27[Copy]%20super%20important%20level%20service%27,objective:(target:0.98),remote:(kibanaUrl:%27https:/cloud.elast.co/kibana%27,remoteName:remote_cluster),revision:1,settings:(frequency:%271m%27,preventInitialBackfill:!f,syncDelay:%271m%27),summary:(errorBudget:(consumed:0.064,initial:0.02,isEstimated:!f,remaining:0.936),fiveMinuteBurnRate:0,oneDayBurnRate:0,oneHourBurnRate:0,sliValue:0.99872,status:HEALTHY),tags:!(k8s,production,critical),timeWindow:(duration:%2730d%27,type:rolling),updatedAt:%272022-12-29T10:11:12.000Z%27,version:2)"` ); }); @@ -71,7 +71,7 @@ describe('remote SLO URLs Utils', () => { `"https://cloud.elast.co/s/my-custom-space/app/slos/edit/fixed-id"` ); expect(createRemoteSloCloneUrl(remoteSlo, 'my-custom-space')).toMatchInlineSnapshot( - `"https://cloud.elast.co/s/my-custom-space/app/slos/create?_a=(budgetingMethod:occurrences,createdAt:%272022-12-29T10:11:12.000Z%27,description:%27some%20description%20useful%27,enabled:!t,groupBy:%27*%27,groupings:(),indicator:(params:(filter:%27baz:%20foo%20and%20bar%20%3E%202%27,good:%27http_status:%202xx%27,index:some-index,timestampField:custom_timestamp,total:%27a%20query%27),type:sli.kql.custom),instanceId:%27*%27,meta:(),name:%27[Copy]%20super%20important%20level%20service%27,objective:(target:0.98),remote:(kibanaUrl:%27https:/cloud.elast.co/kibana%27,remoteName:remote_cluster),revision:1,settings:(frequency:%271m%27,preventInitialBackfill:!f,syncDelay:%271m%27),summary:(errorBudget:(consumed:0.064,initial:0.02,isEstimated:!f,remaining:0.936),fiveMinuteBurnRate:0,oneDayBurnRate:0,oneHourBurnRate:0,sliValue:0.99872,status:HEALTHY),tags:!(k8s,production,critical),timeWindow:(duration:%2730d%27,type:rolling),updatedAt:%272022-12-29T10:11:12.000Z%27,version:2)"` + `"https://cloud.elast.co/s/my-custom-space/app/slos/create?_a=(budgetingMethod:occurrences,createdAt:%272022-12-29T10:11:12.000Z%27,description:%27some%20description%20useful%27,enabled:!t,groupBy:%27*%27,groupings:(),indicator:(params:(dataViewId:some-data-view-id,filter:%27baz:%20foo%20and%20bar%20%3E%202%27,good:%27http_status:%202xx%27,index:some-index,timestampField:custom_timestamp,total:%27a%20query%27),type:sli.kql.custom),instanceId:%27*%27,meta:(),name:%27[Copy]%20super%20important%20level%20service%27,objective:(target:0.98),remote:(kibanaUrl:%27https:/cloud.elast.co/kibana%27,remoteName:remote_cluster),revision:1,settings:(frequency:%271m%27,preventInitialBackfill:!f,syncDelay:%271m%27),summary:(errorBudget:(consumed:0.064,initial:0.02,isEstimated:!f,remaining:0.936),fiveMinuteBurnRate:0,oneDayBurnRate:0,oneHourBurnRate:0,sliValue:0.99872,status:HEALTHY),tags:!(k8s,production,critical),timeWindow:(duration:%2730d%27,type:rolling),updatedAt:%272022-12-29T10:11:12.000Z%27,version:2)"` ); }); }); diff --git a/x-pack/plugins/observability_solution/slo/server/lib/rules/register_burn_rate_rule.ts b/x-pack/plugins/observability_solution/slo/server/lib/rules/register_burn_rate_rule.ts index d432dc5c52d34..ace1a1318ce29 100644 --- a/x-pack/plugins/observability_solution/slo/server/lib/rules/register_burn_rate_rule.ts +++ b/x-pack/plugins/observability_solution/slo/server/lib/rules/register_burn_rate_rule.ts @@ -5,14 +5,14 @@ * 2.0. */ -import { PluginSetupContract } from '@kbn/alerting-plugin/server'; +import type { AlertingServerSetup } from '@kbn/alerting-plugin/server'; import { IBasePath, Logger } from '@kbn/core/server'; import { IRuleDataService } from '@kbn/rule-registry-plugin/server'; import { CustomThresholdLocators } from '@kbn/observability-plugin/server'; import { sloBurnRateRuleType } from './slo_burn_rate'; export function registerBurnRateRule( - alertingPlugin: PluginSetupContract, + alertingPlugin: AlertingServerSetup, basePath: IBasePath, logger: Logger, ruleDataService: IRuleDataService, diff --git a/x-pack/plugins/observability_solution/slo/server/plugin.ts b/x-pack/plugins/observability_solution/slo/server/plugin.ts index 7699cbe5f1404..99cd4a2230a94 100644 --- a/x-pack/plugins/observability_solution/slo/server/plugin.ts +++ b/x-pack/plugins/observability_solution/slo/server/plugin.ts @@ -14,10 +14,11 @@ import { PluginInitializerContext, SavedObjectsClient, } from '@kbn/core/server'; -import { KibanaFeatureScope } from '@kbn/features-plugin/common'; -import { i18n } from '@kbn/i18n'; import { AlertsLocatorDefinition, sloFeatureId } from '@kbn/observability-plugin/common'; import { SLO_BURN_RATE_RULE_TYPE_ID } from '@kbn/rule-data-utils'; +import { ALERTING_FEATURE_ID } from '@kbn/alerting-plugin/common'; +import { KibanaFeatureScope } from '@kbn/features-plugin/common'; +import { i18n } from '@kbn/i18n'; import { mapValues } from 'lodash'; import { registerSloUsageCollector } from './lib/collectors/register'; import { registerBurnRateRule } from './lib/rules/register_burn_rate_rule'; @@ -61,6 +62,11 @@ export class SLOPlugin const savedObjectTypes = [SO_SLO_TYPE, SO_SLO_SETTINGS_TYPE]; + const alertingFeatures = sloRuleTypes.map((ruleTypeId) => ({ + ruleTypeId, + consumers: [sloFeatureId, ALERTING_FEATURE_ID], + })); + plugins.features.registerKibanaFeature({ id: sloFeatureId, name: i18n.translate('xpack.slo.featureRegistry.linkSloTitle', { @@ -71,7 +77,7 @@ export class SLOPlugin scope: [KibanaFeatureScope.Spaces, KibanaFeatureScope.Security], app: [sloFeatureId, 'kibana'], catalogue: [sloFeatureId, 'observability'], - alerting: sloRuleTypes, + alerting: alertingFeatures, privileges: { all: { app: [sloFeatureId, 'kibana'], @@ -83,10 +89,10 @@ export class SLOPlugin }, alerting: { rule: { - all: sloRuleTypes, + all: alertingFeatures, }, alert: { - all: sloRuleTypes, + all: alertingFeatures, }, }, ui: ['read', 'write'], @@ -101,10 +107,10 @@ export class SLOPlugin }, alerting: { rule: { - read: sloRuleTypes, + read: alertingFeatures, }, alert: { - read: sloRuleTypes, + read: alertingFeatures, }, }, ui: ['read'], diff --git a/x-pack/plugins/observability_solution/slo/server/services/create_slo.ts b/x-pack/plugins/observability_solution/slo/server/services/create_slo.ts index e7c09c352bd66..a8e01fb4681f4 100644 --- a/x-pack/plugins/observability_solution/slo/server/services/create_slo.ts +++ b/x-pack/plugins/observability_solution/slo/server/services/create_slo.ts @@ -9,6 +9,7 @@ import { TransformPutTransformRequest } from '@elastic/elasticsearch/lib/api/typ import { ElasticsearchClient, IBasePath, IScopedClusterClient, Logger } from '@kbn/core/server'; import { ALL_VALUE, CreateSLOParams, CreateSLOResponse } from '@kbn/slo-schema'; import { asyncForEach } from '@kbn/std'; +import { merge } from 'lodash'; import { v4 as uuidv4 } from 'uuid'; import { SLO_MODEL_VERSION, @@ -46,8 +47,10 @@ export class CreateSLO { const slo = this.toSLO(params); validateSLO(slo); - await this.assertSLOInexistant(slo); - await assertExpectedIndicatorSourceIndexPrivileges(slo, this.esClient); + await Promise.all([ + this.assertSLOInexistant(slo), + assertExpectedIndicatorSourceIndexPrivileges(slo, this.esClient), + ]); const rollbackOperations = []; const createPromise = this.repository.create(slo); @@ -201,11 +204,14 @@ export class CreateSLO { return { ...params, id: params.id ?? uuidv4(), - settings: { - syncDelay: params.settings?.syncDelay ?? new Duration(1, DurationUnit.Minute), - frequency: params.settings?.frequency ?? new Duration(1, DurationUnit.Minute), - preventInitialBackfill: params.settings?.preventInitialBackfill ?? false, - }, + settings: merge( + { + syncDelay: new Duration(1, DurationUnit.Minute), + frequency: new Duration(1, DurationUnit.Minute), + preventInitialBackfill: false, + }, + params.settings + ), revision: params.revision ?? 1, enabled: true, tags: params.tags ?? [], diff --git a/x-pack/plugins/observability_solution/slo/server/services/get_slos_overview.ts b/x-pack/plugins/observability_solution/slo/server/services/get_slos_overview.ts index 32660b68f4693..fb2be7bcbf74d 100644 --- a/x-pack/plugins/observability_solution/slo/server/services/get_slos_overview.ts +++ b/x-pack/plugins/observability_solution/slo/server/services/get_slos_overview.ts @@ -15,7 +15,7 @@ import { import { RulesClientApi } from '@kbn/alerting-plugin/server/types'; import { AlertsClient } from '@kbn/rule-registry-plugin/server'; import moment from 'moment'; -import { observabilityAlertFeatureIds } from '@kbn/observability-plugin/common'; +import { AlertConsumers, SLO_RULE_TYPE_IDS } from '@kbn/rule-data-utils'; import { typedSearch } from '../utils/queries'; import { getElasticsearchQueryOrThrow, parseStringFilters } from './transform_generators'; import { getListOfSummaryIndices, getSloSettings } from './slo_settings'; @@ -108,21 +108,16 @@ export class GetSLOsOverview { const [rules, alerts] = await Promise.all([ this.rulesClient.find({ options: { - search: 'alert.attributes.alertTypeId:("slo.rules.burnRate")', + ruleTypeIds: SLO_RULE_TYPE_IDS, + consumers: [AlertConsumers.SLO, AlertConsumers.ALERTS, AlertConsumers.OBSERVABILITY], }, }), this.racClient.getAlertSummary({ - featureIds: observabilityAlertFeatureIds, + ruleTypeIds: SLO_RULE_TYPE_IDS, + consumers: [AlertConsumers.SLO, AlertConsumers.ALERTS, AlertConsumers.OBSERVABILITY], gte: moment().subtract(24, 'hours').toISOString(), lte: moment().toISOString(), - filter: [ - { - term: { - 'kibana.alert.rule.rule_type_id': 'slo.rules.burnRate', - }, - }, - ], }), ]); diff --git a/x-pack/plugins/observability_solution/slo/server/services/slo_repository.ts b/x-pack/plugins/observability_solution/slo/server/services/slo_repository.ts index 4f9cf439e8ed1..afbdb999fc064 100644 --- a/x-pack/plugins/observability_solution/slo/server/services/slo_repository.ts +++ b/x-pack/plugins/observability_solution/slo/server/services/slo_repository.ts @@ -9,6 +9,7 @@ import { SavedObjectsClientContract } from '@kbn/core-saved-objects-api-server'; import { Logger } from '@kbn/core/server'; import { ALL_VALUE, Paginated, Pagination, sloDefinitionSchema } from '@kbn/slo-schema'; import { isLeft } from 'fp-ts/lib/Either'; +import { merge } from 'lodash'; import { SLO_MODEL_VERSION } from '../../common/constants'; import { SLODefinition, StoredSLODefinition } from '../domain/models'; import { SLONotFound } from '../errors'; @@ -155,10 +156,10 @@ export class KibanaSavedObjectsSLORepository implements SLORepository { // We would need to call the _reset api on this SLO. version: storedSLO.version ?? 1, // settings.preventInitialBackfill was added in 8.15.0 - settings: { - ...storedSLO.settings, - preventInitialBackfill: storedSLO.settings?.preventInitialBackfill ?? false, - }, + settings: merge( + { preventInitialBackfill: false, syncDelay: '1m', frequency: '1m' }, + storedSLO.settings + ), }); if (isLeft(result)) { diff --git a/x-pack/plugins/observability_solution/slo/server/services/transform_generators/__snapshots__/transform_generator.test.ts.snap b/x-pack/plugins/observability_solution/slo/server/services/transform_generators/__snapshots__/transform_generator.test.ts.snap index 7d8e989c1140d..f49785cf936c5 100644 --- a/x-pack/plugins/observability_solution/slo/server/services/transform_generators/__snapshots__/transform_generator.test.ts.snap +++ b/x-pack/plugins/observability_solution/slo/server/services/transform_generators/__snapshots__/transform_generator.test.ts.snap @@ -63,3 +63,11 @@ Object { }, } `; + +exports[`Transform Generator settings builds the transform settings 1`] = ` +Object { + "frequency": "2m", + "sync_delay": "10m", + "sync_field": "my_timestamp_sync_field", +} +`; diff --git a/x-pack/plugins/observability_solution/slo/server/services/transform_generators/apm_transaction_duration.ts b/x-pack/plugins/observability_solution/slo/server/services/transform_generators/apm_transaction_duration.ts index d1f05605dab36..99361fa776789 100644 --- a/x-pack/plugins/observability_solution/slo/server/services/transform_generators/apm_transaction_duration.ts +++ b/x-pack/plugins/observability_solution/slo/server/services/transform_generators/apm_transaction_duration.ts @@ -42,7 +42,7 @@ export class ApmTransactionDurationTransformGenerator extends TransformGenerator this.buildDestination(slo), this.buildGroupBy(slo, slo.indicator), this.buildAggregations(slo, slo.indicator), - this.buildSettings(slo), + this.buildSettings(slo, '@timestamp'), slo ); } diff --git a/x-pack/plugins/observability_solution/slo/server/services/transform_generators/apm_transaction_error_rate.ts b/x-pack/plugins/observability_solution/slo/server/services/transform_generators/apm_transaction_error_rate.ts index 6adbd1d3eae9f..a65e4ae1d50dd 100644 --- a/x-pack/plugins/observability_solution/slo/server/services/transform_generators/apm_transaction_error_rate.ts +++ b/x-pack/plugins/observability_solution/slo/server/services/transform_generators/apm_transaction_error_rate.ts @@ -41,7 +41,7 @@ export class ApmTransactionErrorRateTransformGenerator extends TransformGenerato this.buildDestination(slo), this.buildGroupBy(slo, slo.indicator), this.buildAggregations(slo), - this.buildSettings(slo), + this.buildSettings(slo, '@timestamp'), slo ); } diff --git a/x-pack/plugins/observability_solution/slo/server/services/transform_generators/transform_generator.test.ts b/x-pack/plugins/observability_solution/slo/server/services/transform_generators/transform_generator.test.ts index e70d406d75396..2df8a1e40eebb 100644 --- a/x-pack/plugins/observability_solution/slo/server/services/transform_generators/transform_generator.test.ts +++ b/x-pack/plugins/observability_solution/slo/server/services/transform_generators/transform_generator.test.ts @@ -5,6 +5,7 @@ * 2.0. */ +import { Duration, DurationUnit } from '../../domain/models'; import { createAPMTransactionErrorRateIndicator, createSLO } from '../fixtures/slo'; import { ApmTransactionErrorRateTransformGenerator } from './apm_transaction_error_rate'; import { dataViewsService } from '@kbn/data-views-plugin/server/mocks'; @@ -45,4 +46,46 @@ describe('Transform Generator', () => { expect(runtimeMappings).toEqual({}); }); }); + + describe('settings', () => { + const defaultSettings = { + syncDelay: new Duration(10, DurationUnit.Minute), + frequency: new Duration(2, DurationUnit.Minute), + preventInitialBackfill: true, + }; + + it('builds the transform settings', async () => { + const slo = createSLO({ + settings: { + ...defaultSettings, + syncField: 'my_timestamp_sync_field', + }, + }); + const settings = generator.buildSettings(slo); + expect(settings).toMatchSnapshot(); + }); + + it('builds the transform settings using the provided settings.syncField', async () => { + const slo = createSLO({ + settings: { + ...defaultSettings, + syncField: 'my_timestamp_sync_field', + }, + }); + const settings = generator.buildSettings(slo, '@timestamp'); + expect(settings.sync_field).toEqual('my_timestamp_sync_field'); + }); + + it('builds the transform settings using provided fallback when no settings.syncField is configured', async () => { + const slo = createSLO({ settings: defaultSettings }); + const settings = generator.buildSettings(slo, '@timestamp2'); + expect(settings.sync_field).toEqual('@timestamp2'); + }); + + it("builds the transform settings using '@timestamp' default fallback when no settings.syncField is configured", async () => { + const slo = createSLO({ settings: defaultSettings }); + const settings = generator.buildSettings(slo); + expect(settings.sync_field).toEqual('@timestamp'); + }); + }); }); diff --git a/x-pack/plugins/observability_solution/slo/server/services/transform_generators/transform_generator.ts b/x-pack/plugins/observability_solution/slo/server/services/transform_generators/transform_generator.ts index 6c44471fd6566..ea27ebbc7aa38 100644 --- a/x-pack/plugins/observability_solution/slo/server/services/transform_generators/transform_generator.ts +++ b/x-pack/plugins/observability_solution/slo/server/services/transform_generators/transform_generator.ts @@ -88,8 +88,9 @@ export abstract class TransformGenerator { ): TransformSettings { return { frequency: slo.settings.frequency.format(), - sync_field: sourceIndexTimestampField, // timestamp field defined in the source index sync_delay: slo.settings.syncDelay.format(), + // 8.17: use settings.syncField if truthy or default to sourceIndexTimestampField which is the indicator timestampField + sync_field: !!slo.settings.syncField ? slo.settings.syncField : sourceIndexTimestampField, }; } } diff --git a/x-pack/plugins/observability_solution/slo/server/services/update_slo.ts b/x-pack/plugins/observability_solution/slo/server/services/update_slo.ts index d1dfb2e70e00c..402ca82acecd4 100644 --- a/x-pack/plugins/observability_solution/slo/server/services/update_slo.ts +++ b/x-pack/plugins/observability_solution/slo/server/services/update_slo.ts @@ -43,9 +43,10 @@ export class UpdateSLO { public async execute(sloId: string, params: UpdateSLOParams): Promise { const originalSlo = await this.repository.findById(sloId); - let updatedSlo: SLODefinition = Object.assign({}, originalSlo, params, { + let updatedSlo: SLODefinition = Object.assign({}, originalSlo, { + ...params, groupBy: !!params.groupBy ? params.groupBy : originalSlo.groupBy, - settings: mergePartialSettings(originalSlo.settings, params.settings), + settings: Object.assign({}, originalSlo.settings, params.settings), }); if (isEqual(originalSlo, updatedSlo)) { @@ -263,13 +264,3 @@ export class UpdateSLO { return updateSLOResponseSchema.encode(slo); } } - -/** - * Settings are merged by overwriting the original settings with the optional new partial settings. - */ -function mergePartialSettings( - originalSettings: SLODefinition['settings'], - newPartialSettings: UpdateSLOParams['settings'] -) { - return Object.assign({}, originalSettings, newPartialSettings); -} diff --git a/x-pack/plugins/observability_solution/slo/server/types.ts b/x-pack/plugins/observability_solution/slo/server/types.ts index b9269f49c4d9f..9a40547820182 100644 --- a/x-pack/plugins/observability_solution/slo/server/types.ts +++ b/x-pack/plugins/observability_solution/slo/server/types.ts @@ -5,7 +5,7 @@ * 2.0. */ -import type { PluginSetupContract, PluginStartContract } from '@kbn/alerting-plugin/server'; +import type { AlertingServerSetup, AlertingServerStart } from '@kbn/alerting-plugin/server'; import { CloudSetup } from '@kbn/cloud-plugin/server'; import { DataViewsServerPluginStart } from '@kbn/data-views-plugin/server'; import { FeaturesPluginSetup } from '@kbn/features-plugin/server'; @@ -31,7 +31,7 @@ export interface SLOServerSetup {} export interface SLOServerStart {} export interface SLOPluginSetupDependencies { - alerting: PluginSetupContract; + alerting: AlertingServerSetup; ruleRegistry: RuleRegistryPluginSetupContract; share: SharePluginSetup; features: FeaturesPluginSetup; @@ -44,7 +44,7 @@ export interface SLOPluginSetupDependencies { } export interface SLOPluginStartDependencies { - alerting: PluginStartContract; + alerting: AlertingServerStart; taskManager: TaskManagerStartContract; spaces?: SpacesPluginStart; ruleRegistry: RuleRegistryPluginStartContract; diff --git a/x-pack/plugins/observability_solution/synthetics/common/constants/synthetics_alerts.ts b/x-pack/plugins/observability_solution/synthetics/common/constants/synthetics_alerts.ts index 4f525bda17564..8a5812f46c6cb 100644 --- a/x-pack/plugins/observability_solution/synthetics/common/constants/synthetics_alerts.ts +++ b/x-pack/plugins/observability_solution/synthetics/common/constants/synthetics_alerts.ts @@ -8,6 +8,8 @@ import type { ActionGroup } from '@kbn/alerting-plugin/common'; import { i18n } from '@kbn/i18n'; +export { SYNTHETICS_STATUS_RULE, SYNTHETICS_TLS_RULE } from '@kbn/rule-data-utils'; + export type MonitorStatusActionGroup = | ActionGroup<'xpack.synthetics.alerts.actionGroups.monitorStatus'> | ActionGroup<'xpack.synthetics.alerts.actionGroups.tls'>; @@ -34,14 +36,6 @@ export const ACTION_GROUP_DEFINITIONS: { TLS_CERTIFICATE, }; -export const SYNTHETICS_STATUS_RULE = 'xpack.synthetics.alerts.monitorStatus'; -export const SYNTHETICS_TLS_RULE = 'xpack.synthetics.alerts.tls'; - -export const SYNTHETICS_ALERT_RULE_TYPES = { - MONITOR_STATUS: SYNTHETICS_STATUS_RULE, - TLS: SYNTHETICS_TLS_RULE, -}; - -export const SYNTHETICS_RULE_TYPES = [SYNTHETICS_STATUS_RULE, SYNTHETICS_TLS_RULE]; - export const SYNTHETICS_RULE_TYPES_ALERT_CONTEXT = 'observability.uptime'; + +export { SYNTHETICS_RULE_TYPE_IDS as SYNTHETICS_RULE_TYPES } from '@kbn/rule-data-utils'; diff --git a/x-pack/plugins/observability_solution/synthetics/common/rules/alert_actions.test.ts b/x-pack/plugins/observability_solution/synthetics/common/rules/alert_actions.test.ts index dd7ad03b9ac32..3bb2c9a4f5aef 100644 --- a/x-pack/plugins/observability_solution/synthetics/common/rules/alert_actions.test.ts +++ b/x-pack/plugins/observability_solution/synthetics/common/rules/alert_actions.test.ts @@ -291,4 +291,77 @@ describe('Alert Actions factory', () => { }, ]); }); + + it('generate expected action for email opsgenie connector', async () => { + const resp = populateAlertActions({ + groupId: SYNTHETICS_MONITOR_STATUS.id, + defaultActions: [ + { + frequency: { + notifyWhen: 'onActionGroupChange', + summary: false, + throttle: null, + }, + actionTypeId: '.opsgenie', + group: 'xpack.synthetics.alerts.actionGroups.monitorStatus', + params: {}, + id: 'f2a3b195-ed76-499a-805d-82d24d4eeba9', + }, + ] as unknown as ActionConnector[], + defaultEmail: { + to: ['test@email.com'], + }, + translations: { + defaultActionMessage: SyntheticsMonitorStatusTranslations.defaultActionMessage, + defaultRecoveryMessage: SyntheticsMonitorStatusTranslations.defaultRecoveryMessage, + defaultSubjectMessage: SyntheticsMonitorStatusTranslations.defaultSubjectMessage, + defaultRecoverySubjectMessage: + SyntheticsMonitorStatusTranslations.defaultRecoverySubjectMessage, + }, + }); + expect(resp).toEqual([ + { + frequency: { + notifyWhen: 'onActionGroupChange', + summary: false, + throttle: null, + }, + group: 'recovered', + id: 'f2a3b195-ed76-499a-805d-82d24d4eeba9', + params: { + subAction: 'closeAlert', + subActionParams: { + alias: '{{rule.id}}:{{alert.id}}', + description: + 'The alert for monitor "{{context.monitorName}}" from {{context.locationNames}} is no longer active: {{context.recoveryReason}}. - Elastic Synthetics\n\nDetails:\n\n- Monitor name: {{context.monitorName}} \n- {{context.monitorUrlLabel}}: {{{context.monitorUrl}}} \n- Monitor type: {{context.monitorType}} \n- From: {{context.locationNames}} \n- Last error received: {{{context.lastErrorMessage}}} \n{{{context.linkMessage}}}', + message: + 'Monitor "{{context.monitorName}}" ({{context.locationNames}}) {{context.recoveryStatus}} - Elastic Synthetics', + priority: 'P2', + tags: ['{{rule.tags}}'], + }, + }, + }, + { + frequency: { + notifyWhen: 'onActionGroupChange', + summary: false, + throttle: null, + }, + group: 'xpack.synthetics.alerts.actionGroups.monitorStatus', + id: 'f2a3b195-ed76-499a-805d-82d24d4eeba9', + params: { + subAction: 'createAlert', + subActionParams: { + alias: '{{rule.id}}:{{alert.id}}', + description: + 'Monitor "{{context.monitorName}}" is {{{context.status}}} from {{context.locationNames}}.{{{context.pendingLastRunAt}}} - Elastic Synthetics\n\nDetails:\n\n- Monitor name: {{context.monitorName}} \n- {{context.monitorUrlLabel}}: {{{context.monitorUrl}}} \n- Monitor type: {{context.monitorType}} \n- Checked at: {{context.checkedAt}} \n- From: {{context.locationNames}} \n- Reason: {{{context.reason}}} \n- Error received: {{{context.lastErrorMessage}}} \n{{{context.linkMessage}}}', + message: + 'Monitor "{{context.monitorName}}" ({{context.locationNames}}) is down - Elastic Synthetics', + priority: 'P2', + tags: ['{{rule.tags}}'], + }, + }, + }, + ]); + }); }); diff --git a/x-pack/plugins/observability_solution/synthetics/common/rules/alert_actions.ts b/x-pack/plugins/observability_solution/synthetics/common/rules/alert_actions.ts index 9b6d9d0992baa..a9981cd257ee6 100644 --- a/x-pack/plugins/observability_solution/synthetics/common/rules/alert_actions.ts +++ b/x-pack/plugins/observability_solution/synthetics/common/rules/alert_actions.ts @@ -14,10 +14,12 @@ import type { WebhookActionParams, EmailActionParams, SlackApiActionParams, + OpsgenieActionParams, } from '@kbn/stack-connectors-plugin/server/connector_types'; import { RuleAction as RuleActionOrig } from '@kbn/alerting-plugin/common'; import { v4 as uuidv4 } from 'uuid'; +import { OpsgenieSubActions } from '@kbn/stack-connectors-plugin/common'; import { ActionConnector, ActionTypeId } from './types'; import { DefaultEmail } from '../runtime_types'; @@ -31,6 +33,7 @@ export const SERVICE_NOW_ACTION_ID: ActionTypeId = '.servicenow'; export const JIRA_ACTION_ID: ActionTypeId = '.jira'; export const WEBHOOK_ACTION_ID: ActionTypeId = '.webhook'; export const EMAIL_ACTION_ID: ActionTypeId = '.email'; +export const OPSGENIE_ACTION_ID: ActionTypeId = '.opsgenie'; export type RuleAction = Omit; @@ -128,6 +131,14 @@ export function populateAlertActions({ actions.push(recoveredAction); } break; + case OPSGENIE_ACTION_ID: + // @ts-expect-error + action.params = getOpsgenieActionParams(translations); + // @ts-expect-error + recoveredAction.params = getOpsgenieActionParams(translations, true); + actions.push(recoveredAction); + break; + default: action.params = { message: translations.defaultActionMessage, @@ -293,3 +304,24 @@ function getEmailActionParams( }, }; } + +function getOpsgenieActionParams( + { + defaultActionMessage, + defaultSubjectMessage, + defaultRecoverySubjectMessage, + defaultRecoveryMessage, + }: Translations, + isRecovery?: boolean +): OpsgenieActionParams { + return { + subAction: isRecovery ? OpsgenieSubActions.CloseAlert : OpsgenieSubActions.CreateAlert, + subActionParams: { + alias: '{{rule.id}}:{{alert.id}}', + tags: ['{{rule.tags}}'], + message: isRecovery ? defaultRecoverySubjectMessage : defaultSubjectMessage, + description: isRecovery ? defaultRecoveryMessage : defaultActionMessage, + priority: 'P2', + }, + } as OpsgenieActionParams; +} diff --git a/x-pack/plugins/observability_solution/synthetics/common/rules/types.ts b/x-pack/plugins/observability_solution/synthetics/common/rules/types.ts index a1888a100c178..0186bc8dc5252 100644 --- a/x-pack/plugins/observability_solution/synthetics/common/rules/types.ts +++ b/x-pack/plugins/observability_solution/synthetics/common/rules/types.ts @@ -16,6 +16,7 @@ import type { TeamsConnectorTypeId, WebhookConnectorTypeId, EmailConnectorTypeId, + OpsgenieConnectorTypeId, } from '@kbn/stack-connectors-plugin/server/connector_types'; import type { ActionConnector as RawActionConnector } from '@kbn/triggers-actions-ui-plugin/public'; @@ -31,6 +32,7 @@ export type ActionTypeId = | typeof ServiceNowConnectorTypeId | typeof JiraConnectorTypeId | typeof WebhookConnectorTypeId - | typeof EmailConnectorTypeId; + | typeof EmailConnectorTypeId + | typeof OpsgenieConnectorTypeId; export type ActionConnector = Omit & { config?: SlackApiConfig }; diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/alerts/tls_rule_ui.tsx b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/alerts/tls_rule_ui.tsx index a4e653bb1ddb0..eb97a0d5f3962 100644 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/alerts/tls_rule_ui.tsx +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/alerts/tls_rule_ui.tsx @@ -9,8 +9,7 @@ import { useDispatch, useSelector } from 'react-redux'; import React, { useEffect } from 'react'; import { RuleTypeParamsExpressionProps } from '@kbn/triggers-actions-ui-plugin/public'; import { AlertTlsComponent } from './alert_tls'; -import { getDynamicSettings } from '../../state/settings/api'; -import { selectDynamicSettings } from '../../state/settings'; +import { getDynamicSettingsAction, selectDynamicSettings } from '../../state/settings'; import { TLSParams } from '../../../../../common/runtime_types/alerts/tls'; import { DYNAMIC_SETTINGS_DEFAULTS } from '../../../../../common/constants'; @@ -24,7 +23,7 @@ export const TLSRuleComponent: React.FC<{ useEffect(() => { if (typeof settings === 'undefined') { - dispatch(getDynamicSettings()); + dispatch(getDynamicSettingsAction.get()); } }, [dispatch, settings]); diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/common/components/permissions.tsx b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/common/components/permissions.tsx index 65b9732e217e9..4bc09bc9884d0 100644 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/common/components/permissions.tsx +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/common/components/permissions.tsx @@ -33,15 +33,21 @@ export const FleetPermissionsCallout = () => { export const NoPermissionsTooltip = ({ canEditSynthetics = true, canUsePublicLocations = true, + canManagePrivateLocations = true, children, }: { canEditSynthetics?: boolean; canUsePublicLocations?: boolean; + canManagePrivateLocations?: boolean; children: ReactNode; }) => { const { isServiceAllowed } = useEnablement(); - const disabledMessage = getRestrictionReasonLabel(canEditSynthetics, canUsePublicLocations); + const disabledMessage = getRestrictionReasonLabel( + canEditSynthetics, + canUsePublicLocations, + canManagePrivateLocations + ); if (!isServiceAllowed) { return ( @@ -64,13 +70,18 @@ export const NoPermissionsTooltip = ({ function getRestrictionReasonLabel( canEditSynthetics = true, - canUsePublicLocations = true + canUsePublicLocations = true, + canManagePrivateLocations = true ): string | undefined { const message = !canEditSynthetics ? CANNOT_PERFORM_ACTION_SYNTHETICS : undefined; if (message) { return message; } + if (!canManagePrivateLocations) { + return NEED_PERMISSIONS_PRIVATE_LOCATIONS; + } + return !canUsePublicLocations ? CANNOT_PERFORM_ACTION_PUBLIC_LOCATIONS : undefined; } diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitor_details/hooks/use_fetch_active_alerts.ts b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitor_details/hooks/use_fetch_active_alerts.ts index f81601e3ed413..ee00905ec7bd7 100644 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitor_details/hooks/use_fetch_active_alerts.ts +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitor_details/hooks/use_fetch_active_alerts.ts @@ -6,7 +6,10 @@ */ import { BASE_RAC_ALERTS_API_PATH } from '@kbn/rule-registry-plugin/common'; -import { AlertConsumers } from '@kbn/rule-registry-plugin/common/technical_rule_data_field_names'; +import { + AlertConsumers, + SYNTHETICS_RULE_TYPE_IDS, +} from '@kbn/rule-registry-plugin/common/technical_rule_data_field_names'; import { useFetcher } from '@kbn/observability-shared-plugin/public'; import { useKibana } from '@kbn/kibana-react-plugin/public'; import { useParams } from 'react-router-dom'; @@ -25,7 +28,8 @@ export function useFetchActiveAlerts() { const { loading, data } = useFetcher(async () => { return await http.post(`${BASE_RAC_ALERTS_API_PATH}/find`, { body: JSON.stringify({ - feature_ids: [AlertConsumers.UPTIME], + rule_type_ids: SYNTHETICS_RULE_TYPE_IDS, + consumers: [AlertConsumers.UPTIME, AlertConsumers.ALERTS, AlertConsumers.OBSERVABILITY], size: 0, track_total_hits: true, query: { diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitor_details/monitor_alerts/monitor_detail_alerts.tsx b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitor_details/monitor_alerts/monitor_detail_alerts.tsx index 1737aa21b27d2..cb071a877d6ee 100644 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitor_details/monitor_alerts/monitor_detail_alerts.tsx +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitor_details/monitor_alerts/monitor_detail_alerts.tsx @@ -6,7 +6,7 @@ */ import { EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiLoadingSpinner } from '@elastic/eui'; import React from 'react'; -import { AlertConsumers } from '@kbn/rule-data-utils'; +import { AlertConsumers, SYNTHETICS_RULE_TYPE_IDS } from '@kbn/rule-data-utils'; import { useKibana } from '@kbn/kibana-react-plugin/public'; import { useParams } from 'react-router-dom'; import { useRefreshedRangeFromUrl } from '../../../hooks'; @@ -44,7 +44,8 @@ export function MonitorDetailsAlerts() { configurationId={AlertConsumers.OBSERVABILITY} id={MONITOR_ALERTS_TABLE_ID} data-test-subj="monitorAlertsTable" - featureIds={[AlertConsumers.UPTIME]} + ruleTypeIds={SYNTHETICS_RULE_TYPE_IDS} + consumers={[AlertConsumers.UPTIME, AlertConsumers.ALERTS, AlertConsumers.OBSERVABILITY]} query={{ bool: { filter: [ diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitors_page/hooks/use_create_slo.ts b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitors_page/hooks/use_create_slo.ts index c75bc5e489208..03c2c2ace9210 100644 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitors_page/hooks/use_create_slo.ts +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitors_page/hooks/use_create_slo.ts @@ -41,10 +41,6 @@ export function useCreateSLO({ tags: [], }, }, - budgetingMethod: 'occurrences', - objective: { - target: 0.99, - }, tags: tags || [], groupBy: ['monitor.name', 'observer.geo.name', 'monitor.id'], }, diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/settings/private_locations/locations_table.tsx b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/settings/private_locations/locations_table.tsx index 8f8fe31a638cf..ac6b471c9046f 100644 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/settings/private_locations/locations_table.tsx +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/settings/private_locations/locations_table.tsx @@ -52,7 +52,7 @@ export const PrivateLocationsTable = ({ const { locationMonitors, loading } = useLocationMonitors(); - const { canSave } = useSyntheticsSettingsContext(); + const { canSave, canManagePrivateLocations } = useSyntheticsSettingsContext(); const tagsList = privateLocations.reduce((acc, item) => { const tags = item.tags || []; @@ -128,13 +128,16 @@ export const PrivateLocationsTable = ({ const renderToolRight = () => { return [ - + setIsAddingNew(true)} iconType="plusInCircle" > diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/settings/private_locations/manage_private_locations.test.tsx b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/settings/private_locations/manage_private_locations.test.tsx index 24c32569f1f2a..5cabd6cf13742 100644 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/settings/private_locations/manage_private_locations.test.tsx +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/settings/private_locations/manage_private_locations.test.tsx @@ -119,6 +119,7 @@ describe('', () => { const privateLocationName = 'Test private location'; jest.spyOn(settingsHooks, 'useSyntheticsSettingsContext').mockReturnValue({ canSave, + canManagePrivateLocations: true, } as SyntheticsSettingsContextValues); jest.spyOn(locationHooks, 'usePrivateLocationsAPI').mockReturnValue({ diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/contexts/synthetics_settings_context.tsx b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/contexts/synthetics_settings_context.tsx index d380d95c90aa4..518920ee0fd52 100644 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/contexts/synthetics_settings_context.tsx +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/contexts/synthetics_settings_context.tsx @@ -45,6 +45,7 @@ export interface SyntheticsAppProps { export interface SyntheticsSettingsContextValues { canSave: boolean; + canManagePrivateLocations: boolean; basePath: string; dateRangeStart: string; dateRangeEnd: string; @@ -74,6 +75,7 @@ const defaultContext: SyntheticsSettingsContextValues = { isLogsAvailable: true, isDev: false, canSave: false, + canManagePrivateLocations: false, }; export const SyntheticsSettingsContext = createContext(defaultContext); @@ -96,6 +98,8 @@ export const SyntheticsSettingsContextProvider: React.FC { return { @@ -109,6 +113,7 @@ export const SyntheticsSettingsContextProvider: React.FC; diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/hooks/use_breadcrumbs.test.tsx b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/hooks/use_breadcrumbs.test.tsx index c97cefc194069..687c2e833151d 100644 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/hooks/use_breadcrumbs.test.tsx +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/hooks/use_breadcrumbs.test.tsx @@ -63,6 +63,7 @@ describe('useBreadcrumbs', () => { setBreadcrumbs: core.chrome.setBreadcrumbs, isInfraAvailable: false, isLogsAvailable: false, + canManagePrivateLocations: false, }} > diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/lib/alert_types/monitor_status.tsx b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/lib/alert_types/monitor_status.tsx index 794747853642c..7c8824a8d56c9 100644 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/lib/alert_types/monitor_status.tsx +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/lib/alert_types/monitor_status.tsx @@ -7,7 +7,7 @@ import React from 'react'; -import { ALERT_REASON } from '@kbn/rule-data-utils'; +import { ALERT_REASON, SYNTHETICS_ALERT_RULE_TYPES } from '@kbn/rule-data-utils'; import type { ObservabilityRuleTypeModel } from '@kbn/observability-plugin/public'; import type { RuleTypeParamsExpressionProps } from '@kbn/triggers-actions-ui-plugin/public'; @@ -15,7 +15,6 @@ import { getSyntheticsErrorRouteFromMonitorId } from '../../../../../common/util import { STATE_ID } from '../../../../../common/field_names'; import { SyntheticsMonitorStatusTranslations } from '../../../../../common/rules/synthetics/translations'; import type { StatusRuleParams } from '../../../../../common/rules/status_rule'; -import { SYNTHETICS_ALERT_RULE_TYPES } from '../../../../../common/constants/synthetics_alerts'; import type { AlertTypeInitializer } from './types'; const { defaultActionMessage, defaultRecoveryMessage, description } = diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/lib/alert_types/tls.tsx b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/lib/alert_types/tls.tsx index 896a84cd1688c..10c45ece27a9f 100644 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/lib/alert_types/tls.tsx +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/lib/alert_types/tls.tsx @@ -6,13 +6,12 @@ */ import React from 'react'; -import { ALERT_REASON } from '@kbn/rule-data-utils'; +import { ALERT_REASON, SYNTHETICS_ALERT_RULE_TYPES } from '@kbn/rule-data-utils'; import { ObservabilityRuleTypeModel } from '@kbn/observability-plugin/public'; import type { RuleTypeParamsExpressionProps } from '@kbn/triggers-actions-ui-plugin/public'; import { ValidationResult } from '@kbn/triggers-actions-ui-plugin/public'; import { TlsTranslations } from '../../../../../common/rules/synthetics/translations'; import { CERTIFICATES_ROUTE } from '../../../../../common/constants/ui'; -import { SYNTHETICS_ALERT_RULE_TYPES } from '../../../../../common/constants/synthetics_alerts'; import type { TLSParams } from '../../../../../common/runtime_types/alerts/tls'; import type { AlertTypeInitializer } from './types'; diff --git a/x-pack/plugins/observability_solution/synthetics/server/alert_rules/status_rule/monitor_status_rule.ts b/x-pack/plugins/observability_solution/synthetics/server/alert_rules/status_rule/monitor_status_rule.ts index ff4516a861225..1e3f8bf35e06b 100644 --- a/x-pack/plugins/observability_solution/synthetics/server/alert_rules/status_rule/monitor_status_rule.ts +++ b/x-pack/plugins/observability_solution/synthetics/server/alert_rules/status_rule/monitor_status_rule.ts @@ -10,16 +10,14 @@ import { isEmpty } from 'lodash'; import { GetViewInAppRelativeUrlFnOpts, AlertsClientError } from '@kbn/alerting-plugin/server'; import { observabilityPaths } from '@kbn/observability-plugin/common'; import apm from 'elastic-apm-node'; +import { SYNTHETICS_ALERT_RULE_TYPES } from '@kbn/rule-data-utils'; import { AlertOverviewStatus } from '../../../common/runtime_types/alert_rules/common'; import { StatusRuleExecutorOptions } from './types'; import { syntheticsRuleFieldMap } from '../../../common/rules/synthetics_rule_field_map'; import { SyntheticsPluginsSetupDependencies, SyntheticsServerSetup } from '../../types'; import { StatusRuleExecutor } from './status_rule_executor'; import { StatusRulePramsSchema } from '../../../common/rules/status_rule'; -import { - MONITOR_STATUS, - SYNTHETICS_ALERT_RULE_TYPES, -} from '../../../common/constants/synthetics_alerts'; +import { MONITOR_STATUS } from '../../../common/constants/synthetics_alerts'; import { setRecoveredAlertsContext, updateState, diff --git a/x-pack/plugins/observability_solution/synthetics/server/alert_rules/tls_rule/tls_rule.ts b/x-pack/plugins/observability_solution/synthetics/server/alert_rules/tls_rule/tls_rule.ts index 5f8fc43c5d91c..111d590a4fd76 100644 --- a/x-pack/plugins/observability_solution/synthetics/server/alert_rules/tls_rule/tls_rule.ts +++ b/x-pack/plugins/observability_solution/synthetics/server/alert_rules/tls_rule/tls_rule.ts @@ -14,6 +14,7 @@ import { AlertsClientError, } from '@kbn/alerting-plugin/server'; import { asyncForEach } from '@kbn/std'; +import { SYNTHETICS_ALERT_RULE_TYPES } from '@kbn/rule-data-utils'; import { getAlertDetailsUrl, observabilityPaths } from '@kbn/observability-plugin/common'; import { schema } from '@kbn/config-schema'; import { ObservabilityUptimeAlert } from '@kbn/alerts-as-data-utils'; @@ -22,10 +23,7 @@ import { SyntheticsPluginsSetupDependencies, SyntheticsServerSetup } from '../.. import { getCertSummary, getTLSAlertDocument, setTLSRecoveredAlertsContext } from './message_utils'; import { SyntheticsCommonState } from '../../../common/runtime_types/alert_rules/common'; import { TLSRuleExecutor } from './tls_rule_executor'; -import { - SYNTHETICS_ALERT_RULE_TYPES, - TLS_CERTIFICATE, -} from '../../../common/constants/synthetics_alerts'; +import { TLS_CERTIFICATE } from '../../../common/constants/synthetics_alerts'; import { SyntheticsRuleTypeAlertDefinition, updateState } from '../common'; import { ALERT_DETAILS_URL, getActionVariables } from '../action_variables'; import { SyntheticsMonitorClient } from '../../synthetics_service/synthetics_monitor/synthetics_monitor_client'; diff --git a/x-pack/plugins/observability_solution/synthetics/server/feature.ts b/x-pack/plugins/observability_solution/synthetics/server/feature.ts index 5a4c4d508853b..0e8a08e8aed13 100644 --- a/x-pack/plugins/observability_solution/synthetics/server/feature.ts +++ b/x-pack/plugins/observability_solution/synthetics/server/feature.ts @@ -11,9 +11,10 @@ import { SubFeaturePrivilegeGroupConfig, SubFeaturePrivilegeGroupType, } from '@kbn/features-plugin/common'; +import { ALERTING_FEATURE_ID } from '@kbn/alerting-plugin/common'; +import { UPTIME_RULE_TYPE_IDS, SYNTHETICS_RULE_TYPE_IDS } from '@kbn/rule-data-utils'; import { KibanaFeatureScope } from '@kbn/features-plugin/common'; import { syntheticsMonitorType, syntheticsParamType } from '../common/types/saved_objects'; -import { SYNTHETICS_RULE_TYPES } from '../common/constants/synthetics_alerts'; import { legacyPrivateLocationsSavedObjectName, privateLocationSavedObjectName, @@ -25,22 +26,22 @@ import { } from './saved_objects/synthetics_settings'; import { syntheticsApiKeyObjectType } from './saved_objects/service_api_key'; -const UPTIME_RULE_TYPES = [ - 'xpack.uptime.alerts.tls', - 'xpack.uptime.alerts.tlsCertificate', - 'xpack.uptime.alerts.monitorStatus', - 'xpack.uptime.alerts.durationAnomaly', -]; +export const PRIVATE_LOCATION_WRITE_API = 'private-location-write'; -const ruleTypes = [...UPTIME_RULE_TYPES, ...SYNTHETICS_RULE_TYPES]; +const ruleTypes = [...UPTIME_RULE_TYPE_IDS, ...SYNTHETICS_RULE_TYPE_IDS]; + +const alertingFeatures = ruleTypes.map((ruleTypeId) => ({ + ruleTypeId, + consumers: [PLUGIN.ID, ALERTING_FEATURE_ID], +})); const elasticManagedLocationsEnabledPrivilege: SubFeaturePrivilegeGroupConfig = { groupType: 'independent' as SubFeaturePrivilegeGroupType, privileges: [ { id: 'elastic_managed_locations_enabled', - name: i18n.translate('xpack.synthetics.features.elasticManagedLocations', { - defaultMessage: 'Elastic managed locations enabled', + name: i18n.translate('xpack.synthetics.features.elasticManagedLocations.label', { + defaultMessage: 'Enabled', }), includeIn: 'all', savedObject: { @@ -52,6 +53,25 @@ const elasticManagedLocationsEnabledPrivilege: SubFeaturePrivilegeGroupConfig = ], }; +const canManagePrivateLocationsPrivilege: SubFeaturePrivilegeGroupConfig = { + groupType: 'independent' as SubFeaturePrivilegeGroupType, + privileges: [ + { + id: 'can_manage_private_locations', + name: i18n.translate('xpack.synthetics.features.canManagePrivateLocations', { + defaultMessage: 'Can manage', + }), + includeIn: 'all', + api: [PRIVATE_LOCATION_WRITE_API], + savedObject: { + all: [privateLocationSavedObjectName, legacyPrivateLocationsSavedObjectName], + read: [], + }, + ui: ['canManagePrivateLocations'], + }, + ], +}; + export const syntheticsFeature = { id: PLUGIN.ID, name: PLUGIN.NAME, @@ -63,7 +83,7 @@ export const syntheticsFeature = { management: { insightsAndAlerting: ['triggersActions'], }, - alerting: ruleTypes, + alerting: alertingFeatures, privileges: { all: { app: ['uptime', 'kibana', 'synthetics'], @@ -74,20 +94,19 @@ export const syntheticsFeature = { syntheticsSettingsObjectType, syntheticsMonitorType, syntheticsApiKeyObjectType, - privateLocationSavedObjectName, - legacyPrivateLocationsSavedObjectName, syntheticsParamType, + // uptime settings object is also registered here since feature is shared between synthetics and uptime uptimeSettingsObjectType, ], - read: [], + read: [privateLocationSavedObjectName, legacyPrivateLocationsSavedObjectName], }, alerting: { rule: { - all: ruleTypes, + all: alertingFeatures, }, alert: { - all: ruleTypes, + all: alertingFeatures, }, }, management: { @@ -114,10 +133,10 @@ export const syntheticsFeature = { }, alerting: { rule: { - read: ruleTypes, + read: alertingFeatures, }, alert: { - read: ruleTypes, + read: alertingFeatures, }, }, management: { @@ -128,10 +147,24 @@ export const syntheticsFeature = { }, subFeatures: [ { - name: i18n.translate('xpack.synthetics.features.app', { - defaultMessage: 'Synthetics', + name: i18n.translate('xpack.synthetics.features.app.elastic', { + defaultMessage: 'Elastic managed locations', + }), + description: i18n.translate('xpack.synthetics.features.app.elasticDescription', { + defaultMessage: + 'This feature enables users to create monitors that execute tests from Elastic managed infrastructure around the globe. There is an additional charge to use Elastic Managed testing locations. See the Elastic Cloud Pricing https://www.elastic.co/pricing page for current prices.', }), privilegeGroups: [elasticManagedLocationsEnabledPrivilege], }, + { + name: i18n.translate('xpack.synthetics.features.app.private', { + defaultMessage: 'Private locations', + }), + description: i18n.translate('xpack.synthetics.features.app.private,description', { + defaultMessage: + 'This feature allows you to manage your private locations, for example adding, or deleting them.', + }), + privilegeGroups: [canManagePrivateLocationsPrivilege], + }, ], }; diff --git a/x-pack/plugins/observability_solution/synthetics/server/lib.ts b/x-pack/plugins/observability_solution/synthetics/server/lib.ts index 94150c0fb8ee5..8a703e1c051e8 100644 --- a/x-pack/plugins/observability_solution/synthetics/server/lib.ts +++ b/x-pack/plugins/observability_solution/synthetics/server/lib.ts @@ -158,7 +158,7 @@ export class SyntheticsEsClient { esError, esRequestParams: { index: SYNTHETICS_INDEX_PATTERN, ...request }, esRequestStatus: RequestStatus.OK, - esResponse: res.body.responses[index], + esResponse: res?.body.responses[index], kibanaRequest: this.request!, operationName: operationName ?? '', startTime: startTimeNow, @@ -168,9 +168,10 @@ export class SyntheticsEsClient { } return { - responses: res.body?.responses as unknown as Array< - InferSearchResponseOf - >, + responses: + (res?.body?.responses as unknown as Array< + InferSearchResponseOf + >) ?? [], }; } diff --git a/x-pack/plugins/observability_solution/synthetics/server/routes/default_alerts/default_alert_service.ts b/x-pack/plugins/observability_solution/synthetics/server/routes/default_alerts/default_alert_service.ts index 2e2263f6e3965..d13395a42ca1a 100644 --- a/x-pack/plugins/observability_solution/synthetics/server/routes/default_alerts/default_alert_service.ts +++ b/x-pack/plugins/observability_solution/synthetics/server/routes/default_alerts/default_alert_service.ts @@ -99,7 +99,7 @@ export class DefaultAlertService { } async getExistingAlert(ruleType: DefaultRuleType) { - const rulesClient = (await this.context.alerting)?.getRulesClient(); + const rulesClient = await (await this.context.alerting)?.getRulesClient(); const { data } = await rulesClient.find({ options: { @@ -123,7 +123,7 @@ export class DefaultAlertService { } const actions = await this.getAlertActions(ruleType); - const rulesClient = (await this.context.alerting)?.getRulesClient(); + const rulesClient = await (await this.context.alerting)?.getRulesClient(); const { actions: actionsFromRules = [], systemActions = [], @@ -158,7 +158,7 @@ export class DefaultAlertService { minimumRuleInterval ); } else { - const rulesClient = (await this.context.alerting)?.getRulesClient(); + const rulesClient = await (await this.context.alerting)?.getRulesClient(); await rulesClient.bulkDeleteRules({ filter: `alert.attributes.alertTypeId:"${SYNTHETICS_STATUS_RULE}" AND alert.attributes.tags:"SYNTHETICS_DEFAULT_ALERT"`, }); @@ -174,7 +174,7 @@ export class DefaultAlertService { minimumRuleInterval ); } else { - const rulesClient = (await this.context.alerting)?.getRulesClient(); + const rulesClient = await (await this.context.alerting)?.getRulesClient(); await rulesClient.bulkDeleteRules({ filter: `alert.attributes.alertTypeId:"${SYNTHETICS_TLS_RULE}" AND alert.attributes.tags:"SYNTHETICS_DEFAULT_ALERT"`, }); @@ -182,7 +182,7 @@ export class DefaultAlertService { } async upsertDefaultAlert(ruleType: DefaultRuleType, name: string, interval: string) { - const rulesClient = (await this.context.alerting)?.getRulesClient(); + const rulesClient = await (await this.context.alerting)?.getRulesClient(); const alert = await this.getExistingAlert(ruleType); if (alert) { diff --git a/x-pack/plugins/observability_solution/synthetics/server/routes/monitor_cruds/add_monitor_project.ts b/x-pack/plugins/observability_solution/synthetics/server/routes/monitor_cruds/add_monitor_project.ts index 8311a6407bf6a..bc55c950a2e81 100644 --- a/x-pack/plugins/observability_solution/synthetics/server/routes/monitor_cruds/add_monitor_project.ts +++ b/x-pack/plugins/observability_solution/synthetics/server/routes/monitor_cruds/add_monitor_project.ts @@ -14,7 +14,7 @@ import { ProjectMonitor } from '../../../common/runtime_types'; import { SYNTHETICS_API_URLS } from '../../../common/constants'; import { ProjectMonitorFormatter } from '../../synthetics_service/project_monitor/project_monitor_formatter'; -const MAX_PAYLOAD_SIZE = 1048576 * 50; // 20MiB +const MAX_PAYLOAD_SIZE = 1048576 * 100; // 20MiB export const addSyntheticsProjectMonitorRoute: SyntheticsRestApiRouteFactory = () => ({ method: 'PUT', diff --git a/x-pack/plugins/observability_solution/synthetics/server/routes/monitor_cruds/edit_monitor.ts b/x-pack/plugins/observability_solution/synthetics/server/routes/monitor_cruds/edit_monitor.ts index d460b71037950..2b815313c79c9 100644 --- a/x-pack/plugins/observability_solution/synthetics/server/routes/monitor_cruds/edit_monitor.ts +++ b/x-pack/plugins/observability_solution/synthetics/server/routes/monitor_cruds/edit_monitor.ts @@ -305,7 +305,7 @@ export const syncEditedMonitor = async ({ }; export const validatePermissions = async ( - { server, response, request }: RouteContext, + routeContext: RouteContext, monitorLocations: MonitorLocations ) => { const hasPublicLocations = monitorLocations?.some((loc) => loc.isServiceManaged); @@ -313,19 +313,26 @@ export const validatePermissions = async ( return; } - const elasticManagedLocationsEnabled = - Boolean( - ( - await server.coreStart?.capabilities.resolveCapabilities(request, { - capabilityPath: 'uptime.*', - }) - ).uptime.elasticManagedLocationsEnabled - ) ?? true; + const { elasticManagedLocationsEnabled } = await validateLocationPermissions(routeContext); if (!elasticManagedLocationsEnabled) { return ELASTIC_MANAGED_LOCATIONS_DISABLED; } }; +export const validateLocationPermissions = async ({ server, request }: RouteContext) => { + const uptimeFeature = await server.coreStart?.capabilities.resolveCapabilities(request, { + capabilityPath: 'uptime.*', + }); + const elasticManagedLocationsEnabled = + Boolean(uptimeFeature.uptime.elasticManagedLocationsEnabled) ?? true; + const canManagePrivateLocations = Boolean(uptimeFeature.uptime.canManagePrivateLocations) ?? true; + + return { + canManagePrivateLocations, + elasticManagedLocationsEnabled, + }; +}; + const getInvalidOriginError = (monitor: SyntheticsMonitor) => { return { body: { diff --git a/x-pack/plugins/observability_solution/synthetics/server/routes/settings/private_locations/add_private_location.ts b/x-pack/plugins/observability_solution/synthetics/server/routes/settings/private_locations/add_private_location.ts index 1feb120b2ea14..fa88de31e3ec8 100644 --- a/x-pack/plugins/observability_solution/synthetics/server/routes/settings/private_locations/add_private_location.ts +++ b/x-pack/plugins/observability_solution/synthetics/server/routes/settings/private_locations/add_private_location.ts @@ -6,6 +6,7 @@ */ import { schema, TypeOf } from '@kbn/config-schema'; +import { PRIVATE_LOCATION_WRITE_API } from '../../../feature'; import { migrateLegacyPrivateLocations } from './migrate_legacy_private_locations'; import { SyntheticsRestApiRouteFactory } from '../../types'; import { getPrivateLocationsAndAgentPolicies } from './get_private_locations'; @@ -38,10 +39,12 @@ export const addPrivateLocationRoute: SyntheticsRestApiRouteFactory { - await migrateLegacyPrivateLocations(routeContext); + const { response, request, savedObjectsClient, syntheticsMonitorClient, server } = routeContext; + const internalSOClient = server.coreStart.savedObjects.createInternalRepository(); - const { response, request, savedObjectsClient, syntheticsMonitorClient } = routeContext; + await migrateLegacyPrivateLocations(internalSOClient, server.logger); const location = request.body as PrivateLocationObject; diff --git a/x-pack/plugins/observability_solution/synthetics/server/routes/settings/private_locations/delete_private_location.ts b/x-pack/plugins/observability_solution/synthetics/server/routes/settings/private_locations/delete_private_location.ts index bac3907eac871..d01b255dd2b32 100644 --- a/x-pack/plugins/observability_solution/synthetics/server/routes/settings/private_locations/delete_private_location.ts +++ b/x-pack/plugins/observability_solution/synthetics/server/routes/settings/private_locations/delete_private_location.ts @@ -7,6 +7,7 @@ import { schema } from '@kbn/config-schema'; import { isEmpty } from 'lodash'; +import { PRIVATE_LOCATION_WRITE_API } from '../../../feature'; import { migrateLegacyPrivateLocations } from './migrate_legacy_private_locations'; import { getMonitorsByLocation } from './get_location_monitors'; import { getPrivateLocationsAndAgentPolicies } from './get_private_locations'; @@ -25,10 +26,13 @@ export const deletePrivateLocationRoute: SyntheticsRestApiRouteFactory { - await migrateLegacyPrivateLocations(routeContext); - const { savedObjectsClient, syntheticsMonitorClient, request, response, server } = routeContext; + const internalSOClient = server.coreStart.savedObjects.createInternalRepository(); + + await migrateLegacyPrivateLocations(internalSOClient, server.logger); + const { locationId } = request.params as { locationId: string }; const { locations } = await getPrivateLocationsAndAgentPolicies( diff --git a/x-pack/plugins/observability_solution/synthetics/server/routes/settings/private_locations/get_private_locations.ts b/x-pack/plugins/observability_solution/synthetics/server/routes/settings/private_locations/get_private_locations.ts index d884bba5c2b0a..90d2e861379ad 100644 --- a/x-pack/plugins/observability_solution/synthetics/server/routes/settings/private_locations/get_private_locations.ts +++ b/x-pack/plugins/observability_solution/synthetics/server/routes/settings/private_locations/get_private_locations.ts @@ -31,9 +31,11 @@ export const getPrivateLocationsRoute: SyntheticsRestApiRouteFactory< }, }, handler: async (routeContext) => { - await migrateLegacyPrivateLocations(routeContext); + const { savedObjectsClient, syntheticsMonitorClient, request, response, server } = routeContext; + + const internalSOClient = server.coreStart.savedObjects.createInternalRepository(); + await migrateLegacyPrivateLocations(internalSOClient, server.logger); - const { savedObjectsClient, syntheticsMonitorClient, request, response } = routeContext; const { id } = request.params as { id?: string }; const { locations, agentPolicies } = await getPrivateLocationsAndAgentPolicies( diff --git a/x-pack/plugins/observability_solution/synthetics/server/routes/settings/private_locations/migrate_legacy_private_locations.test.ts b/x-pack/plugins/observability_solution/synthetics/server/routes/settings/private_locations/migrate_legacy_private_locations.test.ts index 2305853aab3f1..f1e3101523c23 100644 --- a/x-pack/plugins/observability_solution/synthetics/server/routes/settings/private_locations/migrate_legacy_private_locations.test.ts +++ b/x-pack/plugins/observability_solution/synthetics/server/routes/settings/private_locations/migrate_legacy_private_locations.test.ts @@ -6,42 +6,28 @@ */ import { migrateLegacyPrivateLocations } from './migrate_legacy_private_locations'; -import { SyntheticsServerSetup } from '../../../types'; -import { coreMock, savedObjectsClientMock } from '@kbn/core/server/mocks'; +import { savedObjectsRepositoryMock } from '@kbn/core/server/mocks'; import { loggerMock } from '@kbn/logging-mocks'; -import { - type ISavedObjectsRepository, - SavedObjectsClientContract, -} from '@kbn/core-saved-objects-api-server'; +import { type ISavedObjectsRepository } from '@kbn/core-saved-objects-api-server'; +import { Logger } from '@kbn/logging'; describe('migrateLegacyPrivateLocations', () => { - let serverMock: SyntheticsServerSetup; - let savedObjectsClient: jest.Mocked; - let repositoryMock: ISavedObjectsRepository; + let loggerMockVal: Logger; + let repositoryMock: jest.Mocked; beforeEach(() => { - const coreStartMock = coreMock.createStart(); - serverMock = { - coreStart: coreStartMock, - logger: loggerMock.create(), - } as any; - savedObjectsClient = savedObjectsClientMock.create(); - repositoryMock = coreMock.createStart().savedObjects.createInternalRepository(); - - coreStartMock.savedObjects.createInternalRepository.mockReturnValue(repositoryMock); + repositoryMock = savedObjectsRepositoryMock.create(); + loggerMockVal = loggerMock.create(); }); it('should get the legacy private locations', async () => { - savedObjectsClient.get.mockResolvedValueOnce({ + repositoryMock.get.mockResolvedValueOnce({ attributes: { locations: [{ id: '1', label: 'Location 1' }] }, } as any); - savedObjectsClient.find.mockResolvedValueOnce({ total: 1 } as any); + repositoryMock.find.mockResolvedValueOnce({ total: 1 } as any); - await migrateLegacyPrivateLocations({ - server: serverMock, - savedObjectsClient, - } as any); + await migrateLegacyPrivateLocations(repositoryMock, loggerMockVal); - expect(savedObjectsClient.get).toHaveBeenCalledWith( + expect(repositoryMock.get).toHaveBeenCalledWith( 'synthetics-privates-locations', 'synthetics-privates-locations-singleton' ); @@ -49,43 +35,36 @@ describe('migrateLegacyPrivateLocations', () => { it('should log and return if an error occurs while getting legacy private locations', async () => { const error = new Error('Get error'); - savedObjectsClient.get.mockRejectedValueOnce(error); - - await migrateLegacyPrivateLocations({ - server: serverMock, - savedObjectsClient, + repositoryMock.get.mockResolvedValueOnce({ + attributes: { locations: [{ id: '1', label: 'Location 1' }] }, } as any); + repositoryMock.bulkCreate.mockRejectedValueOnce(error); + + await migrateLegacyPrivateLocations(repositoryMock, loggerMockVal); - expect(serverMock.logger.error).toHaveBeenCalledWith( - `Error getting legacy private locations: ${error}` + expect(loggerMockVal.error).toHaveBeenCalledWith( + 'Error migrating legacy private locations: Error: Get error' ); - expect(repositoryMock.bulkCreate).not.toHaveBeenCalled(); }); it('should return if there are no legacy locations', async () => { - savedObjectsClient.get.mockResolvedValueOnce({ + repositoryMock.get.mockResolvedValueOnce({ attributes: { locations: [] }, } as any); - await migrateLegacyPrivateLocations({ - server: serverMock, - savedObjectsClient: savedObjectsClientMock, - } as any); + await migrateLegacyPrivateLocations(repositoryMock, loggerMockVal); expect(repositoryMock.bulkCreate).not.toHaveBeenCalled(); }); it('should bulk create new private locations if there are legacy locations', async () => { const legacyLocations = [{ id: '1', label: 'Location 1' }]; - savedObjectsClient.get.mockResolvedValueOnce({ + repositoryMock.get.mockResolvedValueOnce({ attributes: { locations: legacyLocations }, } as any); - savedObjectsClient.find.mockResolvedValueOnce({ total: 1 } as any); + repositoryMock.find.mockResolvedValueOnce({ total: 1 } as any); - await migrateLegacyPrivateLocations({ - server: serverMock, - savedObjectsClient, - } as any); + await migrateLegacyPrivateLocations(repositoryMock, loggerMockVal); expect(repositoryMock.bulkCreate).toHaveBeenCalledWith( legacyLocations.map((location) => ({ @@ -100,17 +79,14 @@ describe('migrateLegacyPrivateLocations', () => { it('should delete legacy private locations if bulk create count matches', async () => { const legacyLocations = [{ id: '1', label: 'Location 1' }]; - savedObjectsClient.get.mockResolvedValueOnce({ + repositoryMock.get.mockResolvedValueOnce({ attributes: { locations: legacyLocations }, } as any); - savedObjectsClient.find.mockResolvedValueOnce({ total: 1 } as any); + repositoryMock.find.mockResolvedValueOnce({ total: 1 } as any); - await migrateLegacyPrivateLocations({ - server: serverMock, - savedObjectsClient, - } as any); + await migrateLegacyPrivateLocations(repositoryMock, loggerMockVal); - expect(savedObjectsClient.delete).toHaveBeenCalledWith( + expect(repositoryMock.delete).toHaveBeenCalledWith( 'synthetics-privates-locations', 'synthetics-privates-locations-singleton', {} diff --git a/x-pack/plugins/observability_solution/synthetics/server/routes/settings/private_locations/migrate_legacy_private_locations.ts b/x-pack/plugins/observability_solution/synthetics/server/routes/settings/private_locations/migrate_legacy_private_locations.ts index cd73e27b950e3..e823e7764f540 100644 --- a/x-pack/plugins/observability_solution/synthetics/server/routes/settings/private_locations/migrate_legacy_private_locations.ts +++ b/x-pack/plugins/observability_solution/synthetics/server/routes/settings/private_locations/migrate_legacy_private_locations.ts @@ -6,6 +6,8 @@ */ import { SavedObject } from '@kbn/core-saved-objects-server'; +import type { ISavedObjectsRepository } from '@kbn/core-saved-objects-api-server'; +import { Logger } from '@kbn/logging'; import { type PrivateLocationAttributes, SyntheticsPrivateLocationsAttributes, @@ -15,21 +17,20 @@ import { legacyPrivateLocationsSavedObjectName, privateLocationSavedObjectName, } from '../../../../common/saved_objects/private_locations'; -import { RouteContext } from '../../types'; -export const migrateLegacyPrivateLocations = async ({ - server, - savedObjectsClient, -}: RouteContext) => { +export const migrateLegacyPrivateLocations = async ( + soClient: ISavedObjectsRepository, + logger: Logger +) => { try { let obj: SavedObject | undefined; try { - obj = await savedObjectsClient.get( + obj = await soClient.get( legacyPrivateLocationsSavedObjectName, legacyPrivateLocationsSavedObjectId ); } catch (e) { - server.logger.error(`Error getting legacy private locations: ${e}`); + // we don't need to do anything if the legacy object doesn't exist return; } const legacyLocations = obj?.attributes.locations ?? []; @@ -37,8 +38,6 @@ export const migrateLegacyPrivateLocations = async ({ return; } - const soClient = server.coreStart.savedObjects.createInternalRepository(); - await soClient.bulkCreate( legacyLocations.map((location) => ({ id: location.id, @@ -51,20 +50,21 @@ export const migrateLegacyPrivateLocations = async ({ } ); - const { total } = await savedObjectsClient.find({ + const { total } = await soClient.find({ type: privateLocationSavedObjectName, fields: [], perPage: 0, + namespaces: ['*'], }); if (total === legacyLocations.length) { - await savedObjectsClient.delete( + await soClient.delete( legacyPrivateLocationsSavedObjectName, legacyPrivateLocationsSavedObjectId, {} ); } } catch (e) { - server.logger.error(`Error migrating legacy private locations: ${e}`); + logger.error(`Error migrating legacy private locations: ${e}`); } }; diff --git a/x-pack/plugins/observability_solution/synthetics/server/routes/types.ts b/x-pack/plugins/observability_solution/synthetics/server/routes/types.ts index fa481d16b92bf..837197d72d23a 100644 --- a/x-pack/plugins/observability_solution/synthetics/server/routes/types.ts +++ b/x-pack/plugins/observability_solution/synthetics/server/routes/types.ts @@ -38,6 +38,7 @@ export type SupportedMethod = 'GET' | 'POST' | 'PUT' | 'DELETE'; export interface UMServerRoute { method: SupportedMethod; writeAccess?: boolean; + requiredPrivileges?: string[]; handler: T; validation?: VersionedRouteValidation; streamHandler?: ( diff --git a/x-pack/plugins/observability_solution/synthetics/server/runtime_types/private_locations.ts b/x-pack/plugins/observability_solution/synthetics/server/runtime_types/private_locations.ts index f695662e811e3..b7eaea482db92 100644 --- a/x-pack/plugins/observability_solution/synthetics/server/runtime_types/private_locations.ts +++ b/x-pack/plugins/observability_solution/synthetics/server/runtime_types/private_locations.ts @@ -21,6 +21,7 @@ export const PrivateLocationAttributesCodec = t.intersection([ lon: t.number, }), namespace: t.string, + spaces: t.array(t.string), }), ]); diff --git a/x-pack/plugins/observability_solution/synthetics/server/synthetics_route_wrapper.ts b/x-pack/plugins/observability_solution/synthetics/server/synthetics_route_wrapper.ts index 697cf93d74213..da3887ac94d56 100644 --- a/x-pack/plugins/observability_solution/synthetics/server/synthetics_route_wrapper.ts +++ b/x-pack/plugins/observability_solution/synthetics/server/synthetics_route_wrapper.ts @@ -24,7 +24,11 @@ export const syntheticsRouteWrapper: SyntheticsRouteWrapper = ( }, security: { authz: { - requiredPrivileges: ['uptime-read', ...(uptimeRoute?.writeAccess ? ['uptime-write'] : [])], + requiredPrivileges: [ + 'uptime-read', + ...(uptimeRoute.requiredPrivileges ?? []), + ...(uptimeRoute?.writeAccess ? ['uptime-write'] : []), + ], }, }, handler: async (context, request, response) => { diff --git a/x-pack/plugins/observability_solution/synthetics/server/synthetics_service/service_api_client.test.ts b/x-pack/plugins/observability_solution/synthetics/server/synthetics_service/service_api_client.test.ts index 93b3ca2fb3742..cab8157ca3567 100644 --- a/x-pack/plugins/observability_solution/synthetics/server/synthetics_service/service_api_client.test.ts +++ b/x-pack/plugins/observability_solution/synthetics/server/synthetics_service/service_api_client.test.ts @@ -470,6 +470,61 @@ describe('callAPI', () => { url: 'https://service.dev/monitors/sync', }); }); + + it('splits the payload into multiple requests if the payload is too large', async () => { + const requests: number[] = []; + const axiosSpy = (axios as jest.MockedFunction).mockImplementation((req: any) => { + requests.push(req.data.monitors.length); + if (req.data.monitors.length > 100) { + // throw 413 error + return Promise.reject({ response: { status: 413 } }); + } + + return Promise.resolve({} as any); + }); + + const apiClient = new ServiceAPIClient( + logger, + { + manifestUrl: 'http://localhost:8080/api/manifest', + tls: { certificate: 'test-certificate', key: 'test-key' } as any, + }, + { + isDev: true, + stackVersion: '8.7.0', + cloud: { cloudId: 'test-id', deploymentId: 'deployment-id' }, + } as SyntheticsServerSetup + ); + + apiClient.locations = testLocations; + + const output = { hosts: ['https://localhost:9200'], api_key: '12345' }; + + const monitors = new Array(250).fill({ + ...request1[0], + locations: [ + { + id: 'us_central', + isServiceManaged: true, + }, + ], + }); + + await apiClient.syncMonitors({ + monitors, + output, + license: licenseMock.license, + location: { + id: 'us_central', + url: 'https://service.dev', + label: 'Test location', + isServiceManaged: true, + }, + }); + + expect(axiosSpy).toHaveBeenCalledTimes(7); + expect(requests).toEqual([250, 125, 125, 63, 62, 63, 62]); + }); }); const testLocations: PublicLocations = [ diff --git a/x-pack/plugins/observability_solution/synthetics/server/synthetics_service/service_api_client.ts b/x-pack/plugins/observability_solution/synthetics/server/synthetics_service/service_api_client.ts index 73f286e40d310..3f9959440b3e9 100644 --- a/x-pack/plugins/observability_solution/synthetics/server/synthetics_service/service_api_client.ts +++ b/x-pack/plugins/observability_solution/synthetics/server/synthetics_service/service_api_client.ts @@ -6,7 +6,7 @@ */ import axios, { AxiosError, AxiosRequestConfig, AxiosResponse } from 'axios'; -import { forkJoin, from as rxjsFrom, Observable, of } from 'rxjs'; +import { concat, forkJoin, from as rxjsFrom, Observable, of } from 'rxjs'; import { catchError, tap } from 'rxjs'; import * as https from 'https'; import { SslConfig } from '@kbn/server-http-tools'; @@ -215,21 +215,47 @@ export class ServiceAPIClient { const monitorsByLocation = this.processServiceData(serviceData); - monitorsByLocation.forEach(({ location: { url, id }, monitors, data }) => { - const promise = this.callServiceEndpoint(data, method, url, endpoint); - promises.push( - rxjsFrom(promise).pipe( + monitorsByLocation.forEach(({ location: { url, id }, data }) => { + const sendRequest = (payload: ServicePayload): Observable => { + const promise = this.callServiceEndpoint(payload, method, url, endpoint); + return rxjsFrom(promise).pipe( tap((result) => { - this.logSuccessMessage(url, method, monitors.length, result); + this.logSuccessMessage(url, method, payload.monitors.length, result); }), catchError((err: AxiosError<{ reason: string; status: number }>) => { + if (err.response?.status === 413 && payload.monitors.length > 1) { + // If payload is too large, split it and retry + const mid = Math.ceil(payload.monitors.length / 2); + const firstHalfMonitors = payload.monitors.slice(0, mid); + const secondHalfMonitors = payload.monitors.slice(mid); + + this.logger.debug( + `Payload of ${payload.monitors.length} monitors is too large for location ${id}, splitting in half, in chunks of ${mid}` + ); + + return concat( + sendRequest({ + ...payload, + monitors: firstHalfMonitors, + }), // Retry with the first half + sendRequest({ + ...payload, + monitors: secondHalfMonitors, + }) // Retry with the second half + ); + } + pushErrors.push({ locationId: id, error: err.response?.data! }); - this.logServiceError(err, url, method, monitors.length); - // we don't want to throw an unhandled exception here + this.logServiceError(err, url, method, payload.monitors.length); + + // Return an empty observable to prevent unhandled exceptions return of(true); }) - ) - ); + ); + }; + + // Start with the initial data payload + promises.push(sendRequest(data)); }); const result = await forkJoin(promises).toPromise(); diff --git a/x-pack/plugins/observability_solution/synthetics/server/synthetics_service/synthetics_service.ts b/x-pack/plugins/observability_solution/synthetics/server/synthetics_service/synthetics_service.ts index be72ca4d9a496..c223de84c42dc 100644 --- a/x-pack/plugins/observability_solution/synthetics/server/synthetics_service/synthetics_service.ts +++ b/x-pack/plugins/observability_solution/synthetics/server/synthetics_service/synthetics_service.ts @@ -152,7 +152,9 @@ export class SyntheticsService { service.locations = result.locations; service.apiClient.locations = result.locations; this.logger.debug( - `Fetched ${service.locations} Synthetics service locations from manifest: ${this.config.manifestUrl}` + `Fetched ${service.locations + .map((loc) => loc.id) + .join(',')} Synthetics service locations from manifest: ${this.config.manifestUrl}` ); } catch (e) { this.logger.error(e); @@ -167,7 +169,7 @@ export class SyntheticsService { [SYNTHETICS_SERVICE_SYNC_MONITORS_TASK_TYPE]: { title: 'Synthetics Service - Sync Saved Monitors', description: 'This task periodically pushes saved monitors to Synthetics Service.', - timeout: '1m', + timeout: '2m', maxAttempts: 3, createTaskRunner: ({ taskInstance }: { taskInstance: ConcreteTaskInstance }) => { @@ -670,10 +672,10 @@ export class SyntheticsService { if (lastRunAt) { // log if it has missed last schedule - const diff = moment(lastRunAt).diff(current, 'minutes'); + const diff = moment(current).diff(lastRunAt, 'minutes'); const syncInterval = Number((this.config.syncInterval ?? '5m').split('m')[0]); if (diff > syncInterval) { - const message = `Synthetics monitor sync task has missed its schedule, it last ran ${diff} ago.`; + const message = `Synthetics monitor sync task has missed its schedule, it last ran ${diff} minutes ago.`; this.logger.warn(message); sendErrorTelemetryEvents(this.logger, this.server.telemetry, { message, @@ -681,11 +683,8 @@ export class SyntheticsService { type: 'syncTaskMissedSchedule', stackVersion: this.server.stackVersion, }); - } else { - this.logger.debug( - `Synthetics monitor sync task is running as expected, it last ran ${diff} minutes ago.` - ); } + this.logger.debug(`Synthetics monitor sync task last ran ${diff} minutes ago.`); } state.lastRunAt = current.toISOString(); } catch (e) { diff --git a/x-pack/plugins/observability_solution/synthetics/server/types.ts b/x-pack/plugins/observability_solution/synthetics/server/types.ts index e024721101d1f..1a8016830c085 100644 --- a/x-pack/plugins/observability_solution/synthetics/server/types.ts +++ b/x-pack/plugins/observability_solution/synthetics/server/types.ts @@ -17,10 +17,7 @@ import { Logger, SavedObjectsClientContract, } from '@kbn/core/server'; -import { - PluginStartContract as AlertingPluginStart, - PluginSetupContract as AlertingPluginSetup, -} from '@kbn/alerting-plugin/server'; +import { AlertingServerSetup, AlertingServerStart } from '@kbn/alerting-plugin/server'; import { SharePluginSetup } from '@kbn/share-plugin/server'; import { ObservabilityPluginSetup } from '@kbn/observability-plugin/server'; import { UsageCollectionSetup } from '@kbn/usage-collection-plugin/server'; @@ -62,14 +59,14 @@ export interface SyntheticsServerSetup { basePath: IBasePath; isDev?: boolean; coreStart: CoreStart; - alerting: AlertingPluginSetup; + alerting: AlertingServerSetup; pluginsStart: SyntheticsPluginsStartDependencies; isElasticsearchServerless: boolean; } export interface SyntheticsPluginsSetupDependencies { features: FeaturesPluginSetup; - alerting: AlertingPluginSetup; + alerting: AlertingServerSetup; observability: ObservabilityPluginSetup; usageCollection: UsageCollectionSetup; ml: MlSetup; @@ -90,7 +87,7 @@ export interface SyntheticsPluginsStartDependencies { taskManager: TaskManagerStartContract; telemetry: TelemetryPluginStart; spaces?: SpacesPluginStart; - alerting: AlertingPluginStart; + alerting: AlertingServerStart; } export type UptimeRequestHandlerContext = CustomRequestHandlerContext<{ diff --git a/x-pack/plugins/observability_solution/uptime/common/constants/synthetics_alerts.ts b/x-pack/plugins/observability_solution/uptime/common/constants/synthetics_alerts.ts index 223b8909de96e..5de01b708ea2c 100644 --- a/x-pack/plugins/observability_solution/uptime/common/constants/synthetics_alerts.ts +++ b/x-pack/plugins/observability_solution/uptime/common/constants/synthetics_alerts.ts @@ -42,6 +42,4 @@ export const SYNTHETICS_ALERT_RULE_TYPES = { TLS: SYNTHETICS_TLS_RULE, }; -export const SYNTHETICS_RULE_TYPES = [SYNTHETICS_STATUS_RULE, SYNTHETICS_TLS_RULE]; - export const SYNTHETICS_RULE_TYPES_ALERT_CONTEXT = 'observability.uptime'; diff --git a/x-pack/plugins/observability_solution/uptime/common/constants/uptime_alerts.ts b/x-pack/plugins/observability_solution/uptime/common/constants/uptime_alerts.ts index 71f6bd1b183fb..1a84cf461b3e4 100644 --- a/x-pack/plugins/observability_solution/uptime/common/constants/uptime_alerts.ts +++ b/x-pack/plugins/observability_solution/uptime/common/constants/uptime_alerts.ts @@ -41,9 +41,4 @@ export const CLIENT_ALERT_TYPES = { DURATION_ANOMALY: 'xpack.uptime.alerts.durationAnomaly', }; -export const UPTIME_RULE_TYPES = [ - 'xpack.uptime.alerts.tls', - 'xpack.uptime.alerts.tlsCertificate', - 'xpack.uptime.alerts.monitorStatus', - 'xpack.uptime.alerts.durationAnomaly', -]; +export { UPTIME_RULE_TYPE_IDS as UPTIME_RULE_TYPES } from '@kbn/rule-data-utils'; diff --git a/x-pack/plugins/observability_solution/uptime/server/legacy_uptime/routes/monitors/monitors_details.ts b/x-pack/plugins/observability_solution/uptime/server/legacy_uptime/routes/monitors/monitors_details.ts index 357d008c4b901..9cfc38b8730cc 100644 --- a/x-pack/plugins/observability_solution/uptime/server/legacy_uptime/routes/monitors/monitors_details.ts +++ b/x-pack/plugins/observability_solution/uptime/server/legacy_uptime/routes/monitors/monitors_details.ts @@ -23,7 +23,7 @@ export const createGetMonitorDetailsRoute: UMRestApiRouteFactory = (libs: UMServ handler: async ({ uptimeEsClient, context, request }): Promise => { const { monitorId, dateStart, dateEnd } = request.query; - const rulesClient = (await context.alerting)?.getRulesClient(); + const rulesClient = await (await context.alerting)?.getRulesClient(); return await libs.requests.getMonitorDetails({ uptimeEsClient, diff --git a/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.mock.ts b/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.mock.ts index 66ef6a73013f4..d58d5398f907c 100644 --- a/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.mock.ts +++ b/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.mock.ts @@ -20,7 +20,6 @@ const createAlertsClientMock = () => { bulkUpdateCases: jest.fn(), find: jest.fn(), getGroupAggregations: jest.fn(), - getFeatureIdsByRegistrationContexts: jest.fn(), getBrowserFields: jest.fn(), getAlertSummary: jest.fn(), ensureAllAlertsAuthorizedRead: jest.fn(), diff --git a/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.test.ts b/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.test.ts new file mode 100644 index 0000000000000..77215955277dc --- /dev/null +++ b/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.test.ts @@ -0,0 +1,244 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor 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 { coreMock, loggingSystemMock } from '@kbn/core/server/mocks'; +import { alertingAuthorizationMock } from '@kbn/alerting-plugin/server/authorization/alerting_authorization.mock'; +import { ruleDataServiceMock } from '../rule_data_plugin_service/rule_data_plugin_service.mock'; +import { AlertsClient, ConstructorOptions } from './alerts_client'; +import { fromKueryExpression } from '@kbn/es-query'; + +describe('AlertsClient', () => { + const alertingAuthMock = alertingAuthorizationMock.create(); + const ruleDataService = ruleDataServiceMock.create(); + const requestHandlerContext = coreMock.createRequestHandlerContext(); + const esClientMock = requestHandlerContext.elasticsearch.client.asCurrentUser; + + let alertsClient: AlertsClient; + + beforeEach(() => { + jest.clearAllMocks(); + alertingAuthMock.getSpaceId.mockReturnValue('space-1'); + alertingAuthMock.getAllAuthorizedRuleTypesFindOperation.mockResolvedValue( + new Map([ + [ + 'test-rule-type-1', + { + id: 'test-rule-type-1', + authorizedConsumers: { foo: { all: true, read: true } }, + }, + ], + ]) + ); + + alertingAuthMock.getAuthorizationFilter.mockResolvedValue({ + filter: fromKueryExpression( + 'alert.attributes.alertTypeId: test-rule-type-1 AND alert.attributes.consumer: foo' + ), + ensureRuleTypeIsAuthorized: jest.fn(), + }); + + const alertsClientParams: ConstructorOptions = { + logger: loggingSystemMock.create().get(), + authorization: alertingAuthMock, + esClient: esClientMock, + ruleDataService, + getRuleType: jest.fn(), + getRuleList: jest.fn(), + getAlertIndicesAlias: jest.fn(), + }; + + alertsClient = new AlertsClient(alertsClientParams); + }); + + describe('find', () => { + it('creates the ruleTypeIds filter correctly', async () => { + await alertsClient.find({ ruleTypeIds: ['test-rule-type-1', 'test-rule-type-2'] }); + + expect(esClientMock.search.mock.calls[0][0]).toMatchInlineSnapshot(` + Object { + "body": Object { + "_source": undefined, + "aggs": undefined, + "fields": Array [ + "kibana.alert.rule.rule_type_id", + "kibana.alert.rule.consumer", + "kibana.alert.workflow_status", + "kibana.space_ids", + ], + "query": Object { + "bool": Object { + "filter": Array [ + Object { + "arguments": Array [ + Object { + "arguments": Array [ + Object { + "isQuoted": false, + "type": "literal", + "value": "alert.attributes.alertTypeId", + }, + Object { + "isQuoted": false, + "type": "literal", + "value": "test-rule-type-1", + }, + ], + "function": "is", + "type": "function", + }, + Object { + "arguments": Array [ + Object { + "isQuoted": false, + "type": "literal", + "value": "alert.attributes.consumer", + }, + Object { + "isQuoted": false, + "type": "literal", + "value": "foo", + }, + ], + "function": "is", + "type": "function", + }, + ], + "function": "and", + "type": "function", + }, + Object { + "term": Object { + "kibana.space_ids": "space-1", + }, + }, + Object { + "terms": Object { + "kibana.alert.rule.rule_type_id": Array [ + "test-rule-type-1", + "test-rule-type-2", + ], + }, + }, + ], + "must": Array [], + "must_not": Array [], + "should": Array [], + }, + }, + "runtime_mappings": undefined, + "size": undefined, + "sort": Array [ + Object { + "@timestamp": Object { + "order": "asc", + "unmapped_type": "date", + }, + }, + ], + "track_total_hits": undefined, + }, + "ignore_unavailable": true, + "index": ".alerts-*", + "seq_no_primary_term": true, + } + `); + }); + + it('creates the consumers filter correctly', async () => { + await alertsClient.find({ consumers: ['test-consumer-1', 'test-consumer-2'] }); + + expect(esClientMock.search.mock.calls[0][0]).toMatchInlineSnapshot(` + Object { + "body": Object { + "_source": undefined, + "aggs": undefined, + "fields": Array [ + "kibana.alert.rule.rule_type_id", + "kibana.alert.rule.consumer", + "kibana.alert.workflow_status", + "kibana.space_ids", + ], + "query": Object { + "bool": Object { + "filter": Array [ + Object { + "arguments": Array [ + Object { + "arguments": Array [ + Object { + "isQuoted": false, + "type": "literal", + "value": "alert.attributes.alertTypeId", + }, + Object { + "isQuoted": false, + "type": "literal", + "value": "test-rule-type-1", + }, + ], + "function": "is", + "type": "function", + }, + Object { + "arguments": Array [ + Object { + "isQuoted": false, + "type": "literal", + "value": "alert.attributes.consumer", + }, + Object { + "isQuoted": false, + "type": "literal", + "value": "foo", + }, + ], + "function": "is", + "type": "function", + }, + ], + "function": "and", + "type": "function", + }, + Object { + "term": Object { + "kibana.space_ids": "space-1", + }, + }, + Object { + "terms": Object { + "kibana.alert.rule.consumer": Array [ + "test-consumer-1", + "test-consumer-2", + ], + }, + }, + ], + "must": Array [], + "must_not": Array [], + "should": Array [], + }, + }, + "runtime_mappings": undefined, + "size": undefined, + "sort": Array [ + Object { + "@timestamp": Object { + "order": "asc", + "unmapped_type": "date", + }, + }, + ], + "track_total_hits": undefined, + }, + "ignore_unavailable": true, + "index": ".alerts-*", + "seq_no_primary_term": true, + } + `); + }); + }); +}); 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 ea80a365ccd95..3a898b07fb461 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 @@ -15,29 +15,23 @@ import { ALERT_STATUS, getEsQueryConfig, getSafeSortIds, - isValidFeatureId, STATUS_VALUES, - ValidFeatureId, ALERT_STATUS_RECOVERED, ALERT_END, ALERT_STATUS_ACTIVE, ALERT_CASE_IDS, MAX_CASES_PER_ALERT, - AlertConsumers, + isSiemRuleType, } from '@kbn/rule-data-utils'; import { AggregateName, AggregationsAggregate, - AggregationsMultiBucketAggregateBase, MappingRuntimeFields, QueryDslQueryContainer, SortCombinations, } from '@elastic/elasticsearch/lib/api/types'; -import type { - RuleTypeParams, - PluginStartContract as AlertingStart, -} from '@kbn/alerting-plugin/server'; +import type { RuleTypeParams, AlertingServerStart } from '@kbn/alerting-plugin/server'; import { ReadOperations, AlertingAuthorization, @@ -68,6 +62,8 @@ import { MAX_ALERTS_PAGES, MAX_PAGINATED_ALERTS, } from './constants'; +import { getRuleTypeIdsFilter } from '../lib/get_rule_type_ids_filter'; +import { getConsumersFilter } from '../lib/get_consumers_filter'; // TODO: Fix typings https://github.com/elastic/kibana/issues/101776 type NonNullableProps = Omit & { @@ -97,7 +93,7 @@ export interface ConstructorOptions { ruleDataService: IRuleDataService; getRuleType: RuleTypeRegistry['get']; getRuleList: RuleTypeRegistry['list']; - getAlertIndicesAlias: AlertingStart['getAlertIndicesAlias']; + getAlertIndicesAlias: AlertingServerStart['getAlertIndicesAlias']; } export interface UpdateOptions { @@ -138,7 +134,8 @@ interface GetAlertSummaryParams { id?: string; gte: string; lte: string; - featureIds: string[]; + ruleTypeIds: string[]; + consumers?: string[]; filter?: estypes.QueryDslQueryContainer[]; fixedInterval?: string; } @@ -154,7 +151,8 @@ interface SearchAlertsParams { operation: WriteOperations.Update | ReadOperations.Find | ReadOperations.Get; sort?: estypes.SortOptions[]; lastSortIds?: Array; - featureIds?: string[]; + ruleTypeIds?: string[]; + consumers?: string[]; runtimeMappings?: MappingRuntimeFields; } @@ -172,7 +170,7 @@ export class AlertsClient { private readonly ruleDataService: IRuleDataService; private readonly getRuleType: RuleTypeRegistry['get']; private readonly getRuleList: RuleTypeRegistry['list']; - private getAlertIndicesAlias!: AlertingStart['getAlertIndicesAlias']; + private getAlertIndicesAlias!: AlertingServerStart['getAlertIndicesAlias']; constructor(options: ConstructorOptions) { this.logger = options.logger; @@ -295,7 +293,8 @@ export class AlertsClient { operation, sort, lastSortIds = [], - featureIds, + ruleTypeIds, + consumers, runtimeMappings, }: SearchAlertsParams) { try { @@ -316,7 +315,8 @@ export class AlertsClient { alertSpaceId, operation, config, - featureIds ? new Set(featureIds) : undefined + ruleTypeIds, + consumers ), aggs, _source, @@ -372,7 +372,9 @@ export class AlertsClient { return result; } catch (error) { - const errorMessage = `Unable to retrieve alert details for alert with id of "${id}" or with query "${query}" and operation ${operation} \nError: ${error}`; + const errorMessage = `Unable to retrieve alert details for alert with id of "${id}" or with query "${JSON.stringify( + query + )}" and operation ${operation} \nError: ${error}`; this.logger.error(errorMessage); throw Boom.notFound(errorMessage); } @@ -457,16 +459,17 @@ export class AlertsClient { alertSpaceId: string, operation: WriteOperations.Update | ReadOperations.Get | ReadOperations.Find, config: EsQueryConfig, - featuresIds?: Set + ruleTypeIds?: string[], + consumers?: string[] ) { try { - const authzFilter = (await getAuthzFilter( - this.authorization, - operation, - featuresIds - )) as Filter; + const authzFilter = (await getAuthzFilter(this.authorization, operation)) as Filter; const spacesFilter = getSpacesFilter(alertSpaceId) as unknown as Filter; + const ruleTypeIdsFilter = getRuleTypeIdsFilter(ruleTypeIds) as unknown as Filter; + const consumersFilter = getConsumersFilter(consumers) as unknown as Filter; + let esQuery; + if (id != null) { esQuery = { query: `_id:${id}`, language: 'kuery' }; } else if (typeof query === 'string') { @@ -474,12 +477,14 @@ export class AlertsClient { } else if (query != null && typeof query === 'object') { esQuery = []; } + const builtQuery = buildEsQuery( undefined, esQuery == null ? { query: ``, language: 'kuery' } : esQuery, - [authzFilter, spacesFilter], + [authzFilter, spacesFilter, ruleTypeIdsFilter, consumersFilter], config ); + if (query != null && typeof query === 'object') { return { ...builtQuery, @@ -639,15 +644,16 @@ export class AlertsClient { public async getAlertSummary({ gte, lte, - featureIds, + ruleTypeIds, + consumers, filter, fixedInterval = '1m', }: GetAlertSummaryParams) { try { - const indexToUse = await this.getAuthorizedAlertsIndices(featureIds); + const indexToUse = await this.getAuthorizedAlertsIndices(ruleTypeIds); if (isEmpty(indexToUse)) { - throw Boom.badRequest('no featureIds were provided for getting alert summary'); + throw Boom.badRequest('no ruleTypeIds were provided for getting alert summary'); } // first search for the alert by id, then use the alert info to check if user has access to it @@ -710,7 +716,8 @@ export class AlertsClient { }, }, size: 0, - featureIds, + ruleTypeIds, + consumers, }); let activeAlertCount = 0; @@ -981,7 +988,8 @@ export class AlertsClient { TAggregations = Record >({ aggs, - featureIds, + ruleTypeIds, + consumers, index, query, search_after: searchAfter, @@ -992,7 +1000,8 @@ export class AlertsClient { runtimeMappings, }: { aggs?: object; - featureIds?: string[]; + ruleTypeIds?: string[]; + consumers?: string[]; index?: string; query?: object; search_after?: Array; @@ -1004,15 +1013,16 @@ export class AlertsClient { }) { try { let indexToUse = index; - if (featureIds && !isEmpty(featureIds)) { - const tempIndexToUse = await this.getAuthorizedAlertsIndices(featureIds); + if (ruleTypeIds && !isEmpty(ruleTypeIds)) { + const tempIndexToUse = await this.getAuthorizedAlertsIndices(ruleTypeIds); if (!isEmpty(tempIndexToUse)) { indexToUse = (tempIndexToUse ?? []).join(); } } const alertsSearchResponse = await this.searchAlerts({ - featureIds, + ruleTypeIds, + consumers, query, aggs, _source, @@ -1042,7 +1052,8 @@ export class AlertsClient { * Performs a `find` query to extract aggregations on alert groups */ public async getGroupAggregations({ - featureIds, + ruleTypeIds, + consumers, groupByField, aggregations, filters, @@ -1051,9 +1062,15 @@ export class AlertsClient { sort = [{ unitsCount: { order: 'desc' } }], }: { /** - * The feature ids the alerts belong to, used for authorization + * The rule type IDs the alerts belong to. + * Used for filtering. + */ + ruleTypeIds: string[]; + /** + * The consumers the alerts belong to. + * Used for filtering. */ - featureIds: string[]; + consumers?: string[]; /** * The field to group by * @example "kibana.alert.rule.name" @@ -1093,9 +1110,10 @@ export class AlertsClient { } const searchResult = await this.find< never, - { groupByFields: AggregationsMultiBucketAggregateBase<{ key: string }> } + { groupByFields: estypes.AggregationsMultiBucketAggregateBase<{ key: string }> } >({ - featureIds, + ruleTypeIds, + consumers, aggs: { groupByFields: { terms: { @@ -1163,14 +1181,15 @@ export class AlertsClient { return searchResult; } - public async getAuthorizedAlertsIndices(featureIds: string[]): Promise { + public async getAuthorizedAlertsIndices(ruleTypeIds?: string[]): Promise { try { - const authorizedRuleTypes = await this.authorization.getAuthorizedRuleTypes( - AlertingAuthorizationEntity.Alert, - new Set(featureIds) - ); + const authorizedRuleTypes = await this.authorization.getAllAuthorizedRuleTypesFindOperation({ + authorizationEntity: AlertingAuthorizationEntity.Alert, + ruleTypeIds, + }); + const indices = this.getAlertIndicesAlias( - authorizedRuleTypes.map((art: { id: any }) => art.id), + Array.from(authorizedRuleTypes.keys()).map((id) => id), this.spaceId ); @@ -1182,48 +1201,13 @@ export class AlertsClient { } } - public async getFeatureIdsByRegistrationContexts( - RegistrationContexts: string[] - ): Promise { - try { - const featureIds = - this.ruleDataService.findFeatureIdsByRegistrationContexts(RegistrationContexts); - if (featureIds.length > 0) { - // ATTENTION FUTURE DEVELOPER when you are a super user the augmentedRuleTypes.authorizedRuleTypes will - // return all of the features that you can access and does not care about your featureIds - const augmentedRuleTypes = await this.authorization.getAugmentedRuleTypesWithAuthorization( - featureIds, - [ReadOperations.Find, ReadOperations.Get, WriteOperations.Update], - AlertingAuthorizationEntity.Alert - ); - // As long as the user can read a minimum of one type of rule type produced by the provided feature, - // the user should be provided that features' alerts index. - // Limiting which alerts that user can read on that index will be done via the findAuthorizationFilter - const authorizedFeatures = new Set(); - for (const ruleType of augmentedRuleTypes.authorizedRuleTypes) { - authorizedFeatures.add(ruleType.producer); - } - const validAuthorizedFeatures = Array.from(authorizedFeatures).filter( - (feature): feature is ValidFeatureId => - featureIds.includes(feature) && isValidFeatureId(feature) - ); - return validAuthorizedFeatures; - } - return featureIds; - } catch (exc) { - const errMessage = `getFeatureIdsByRegistrationContexts failed to get feature ids: ${exc}`; - this.logger.error(errMessage); - throw Boom.failedDependency(errMessage); - } - } - public async getBrowserFields({ - featureIds, + ruleTypeIds, indices, metaFields, allowNoIndex, }: { - featureIds: string[]; + ruleTypeIds: string[]; indices: string[]; metaFields: string[]; allowNoIndex: boolean; @@ -1231,13 +1215,15 @@ export class AlertsClient { 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) { + + for (const rule of ruleTypeList.values()) { + if (ruleTypeIds.includes(rule.id) && rule.hasFieldsForAAD) { (rule.fieldsForAAD ?? []).forEach((f) => { fieldsForAAD.add(f); }); } } + const { fields } = await indexPatternsFetcherAsInternalUser.getFieldsForWildcard({ pattern: indices, metaFields, @@ -1252,11 +1238,12 @@ export class AlertsClient { } public async getAADFields({ ruleTypeId }: { ruleTypeId: string }) { - const { producer, fieldsForAAD = [] } = this.getRuleType(ruleTypeId); - if (producer === AlertConsumers.SIEM) { + const { fieldsForAAD = [] } = this.getRuleType(ruleTypeId); + if (isSiemRuleType(ruleTypeId)) { throw Boom.badRequest(`Security solution rule type is not supported`); } - const indices = await this.getAuthorizedAlertsIndices([producer]); + + const indices = await this.getAuthorizedAlertsIndices([ruleTypeId]); const indexPatternsFetcherAsInternalUser = new IndexPatternsFetcher(this.esClient); const { fields = [] } = await indexPatternsFetcherAsInternalUser.getFieldsForWildcard({ pattern: indices ?? [], 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 367ead5744d55..8613f6135d30a 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 @@ -21,7 +21,7 @@ const alertingAuthMock = alertingAuthorizationMock.create(); const alertsClientFactoryParams: AlertsClientFactoryProps = { logger: loggingSystemMock.create().get(), - getAlertingAuthorization: (_: KibanaRequest) => alertingAuthMock, + getAlertingAuthorization: (_: KibanaRequest) => Promise.resolve(alertingAuthMock), securityPluginSetup, esClient: {} as ElasticsearchClient, ruleDataService: ruleDataServiceMock.create(), 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 934074cc4a2ed..91449954db61c 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 @@ -8,10 +8,7 @@ import { PublicMethodsOf } from '@kbn/utility-types'; import { ElasticsearchClient, KibanaRequest, Logger } from '@kbn/core/server'; import type { RuleTypeRegistry } from '@kbn/alerting-plugin/server/types'; -import { - AlertingAuthorization, - PluginStartContract as AlertingStart, -} from '@kbn/alerting-plugin/server'; +import { AlertingAuthorization, AlertingServerStart } from '@kbn/alerting-plugin/server'; import { SecurityPluginSetup } from '@kbn/security-plugin/server'; import { IRuleDataService } from '../rule_data_plugin_service'; import { AlertsClient } from './alerts_client'; @@ -19,12 +16,14 @@ import { AlertsClient } from './alerts_client'; export interface AlertsClientFactoryProps { logger: Logger; esClient: ElasticsearchClient; - getAlertingAuthorization: (request: KibanaRequest) => PublicMethodsOf; + getAlertingAuthorization: ( + request: KibanaRequest + ) => Promise>; securityPluginSetup: SecurityPluginSetup | undefined; ruleDataService: IRuleDataService | null; getRuleType: RuleTypeRegistry['get']; getRuleList: RuleTypeRegistry['list']; - getAlertIndicesAlias: AlertingStart['getAlertIndicesAlias']; + getAlertIndicesAlias: AlertingServerStart['getAlertIndicesAlias']; } export class AlertsClientFactory { @@ -33,12 +32,12 @@ export class AlertsClientFactory { private esClient!: ElasticsearchClient; private getAlertingAuthorization!: ( request: KibanaRequest - ) => PublicMethodsOf; + ) => Promise>; private securityPluginSetup!: SecurityPluginSetup | undefined; private ruleDataService!: IRuleDataService | null; private getRuleType!: RuleTypeRegistry['get']; private getRuleList!: RuleTypeRegistry['list']; - private getAlertIndicesAlias!: AlertingStart['getAlertIndicesAlias']; + private getAlertIndicesAlias!: AlertingServerStart['getAlertIndicesAlias']; public initialize(options: AlertsClientFactoryProps) { /** @@ -61,10 +60,11 @@ export class AlertsClientFactory { public async create(request: KibanaRequest): Promise { const { securityPluginSetup, getAlertingAuthorization, logger } = this; + const authorization = await getAlertingAuthorization(request); return new AlertsClient({ logger, - authorization: getAlertingAuthorization(request), + authorization, auditLogger: securityPluginSetup?.audit.asScoped(request), esClient: this.esClient, ruleDataService: this.ruleDataService!, 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 28cd76ca6dffe..8d2e6cffa0cc5 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 @@ -17,7 +17,6 @@ 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 { AlertingAuthorizationEntity } from '@kbn/alerting-plugin/server'; import { ruleDataServiceMock } from '../../rule_data_plugin_service/rule_data_plugin_service.mock'; const alertingAuthMock = alertingAuthorizationMock.create(); @@ -36,39 +35,38 @@ const alertsClientParams: jest.Mocked = { }; const DEFAULT_SPACE = 'test_default_space_id'; +const authorizedRuleTypes = new Map([ + [ + 'apm.error_rate', + { + producer: 'apm', + id: 'apm.error_rate', + alerts: { + context: 'observability.apm', + }, + authorizedConsumers: {}, + }, + ], +]); beforeEach(() => { jest.resetAllMocks(); - alertingAuthMock.getSpaceId.mockImplementation(() => 'test_default_space_id'); - // @ts-expect-error - alertingAuthMock.getAuthorizationFilter.mockImplementation(async () => - Promise.resolve({ filter: [] }) - ); - // @ts-expect-error - alertingAuthMock.getAugmentedRuleTypesWithAuthorization.mockImplementation(async () => { - const authorizedRuleTypes = new Set(); - authorizedRuleTypes.add({ producer: 'apm' }); - return Promise.resolve({ authorizedRuleTypes }); + alertingAuthMock.getSpaceId.mockImplementation(() => DEFAULT_SPACE); + alertingAuthMock.getAuthorizationFilter.mockResolvedValue({ + filter: undefined, + ensureRuleTypeIsAuthorized: jest.fn(), }); - alertingAuthMock.ensureAuthorized.mockImplementation( - // @ts-expect-error - async ({ - ruleTypeId, - consumer, - operation, - entity, - }: { - ruleTypeId: string; - consumer: string; - operation: string; - entity: typeof AlertingAuthorizationEntity.Alert; - }) => { - if (ruleTypeId === 'apm.error_rate' && consumer === 'apm') { - return Promise.resolve(); - } - return Promise.reject(new Error(`Unauthorized for ${ruleTypeId} and ${consumer}`)); + alertingAuthMock.getAllAuthorizedRuleTypes.mockResolvedValue({ + hasAllRequested: true, + authorizedRuleTypes, + }); + + alertingAuthMock.ensureAuthorized.mockImplementation(async ({ ruleTypeId, consumer }) => { + if (ruleTypeId === 'apm.error_rate' && consumer === 'apm') { + return Promise.resolve(); } - ); + return Promise.reject(new Error(`Unauthorized for ${ruleTypeId} and ${consumer}`)); + }); }); const fakeAlertId = 'myfakeid1'; @@ -337,7 +335,7 @@ describe('bulkUpdate()', () => { }) ).rejects.toThrowErrorMatchingInlineSnapshot(` "queryAndAuditAllAlerts threw an error: Unable to retrieve alerts with query \\"kibana.alert.status: active\\" and operation update - Error: Unable to retrieve alert details for alert with id of \\"null\\" or with query \\"kibana.alert.status: active\\" and operation update + Error: Unable to retrieve alert details for alert with id of \\"null\\" or with query \\"\\"kibana.alert.status: active\\"\\" and operation update Error: Error: Unauthorized for fake.rule and apm" `); @@ -404,7 +402,7 @@ describe('bulkUpdate()', () => { }) ).rejects.toThrowErrorMatchingInlineSnapshot(` "queryAndAuditAllAlerts threw an error: Unable to retrieve alerts with query \\"kibana.alert.status: active\\" and operation update - Error: Unable to retrieve alert details for alert with id of \\"null\\" or with query \\"kibana.alert.status: active\\" and operation update + Error: Unable to retrieve alert details for alert with id of \\"null\\" or with query \\"\\"kibana.alert.status: active\\"\\" and operation update Error: Error: Unauthorized for fake.rule and apm" `); 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 57e877f568cd9..c554ee4d61f99 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 @@ -16,62 +16,107 @@ 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 { AlertingAuthorizationEntity } from '@kbn/alerting-plugin/server'; import { ruleDataServiceMock } from '../../rule_data_plugin_service/rule_data_plugin_service.mock'; +import { JsonObject } from '@kbn/utility-types'; -const alertingAuthMock = alertingAuthorizationMock.create(); -const esClientMock = elasticsearchClientMock.createElasticsearchClient(); -const auditLogger = auditLoggerMock.create(); +describe('find()', () => { + const alertingAuthMock = alertingAuthorizationMock.create(); + const esClientMock = elasticsearchClientMock.createElasticsearchClient(); + const auditLogger = auditLoggerMock.create(); -const alertsClientParams: jest.Mocked = { - logger: loggingSystemMock.create().get(), - authorization: alertingAuthMock, - esClient: esClientMock, - auditLogger, - ruleDataService: ruleDataServiceMock.create(), - getRuleType: jest.fn(), - getRuleList: jest.fn(), - getAlertIndicesAlias: jest.fn(), -}; + const alertsClientParams: jest.Mocked = { + logger: loggingSystemMock.create().get(), + authorization: alertingAuthMock, + esClient: esClientMock, + auditLogger, + ruleDataService: ruleDataServiceMock.create(), + getRuleType: jest.fn(), + getRuleList: jest.fn(), + getAlertIndicesAlias: jest.fn(), + }; -const DEFAULT_SPACE = 'test_default_space_id'; + const DEFAULT_SPACE = 'test_default_space_id'; + const authorizedRuleTypes = new Map([ + [ + 'apm.error_rate', + { + producer: 'apm', + id: 'apm.error_rate', + alerts: { + context: 'observability.apm', + }, + authorizedConsumers: {}, + }, + ], + ]); -beforeEach(() => { - jest.resetAllMocks(); - alertingAuthMock.getSpaceId.mockImplementation(() => DEFAULT_SPACE); - // @ts-expect-error - alertingAuthMock.getAuthorizationFilter.mockImplementation(async () => - Promise.resolve({ filter: [] }) - ); - // @ts-expect-error - alertingAuthMock.getAugmentedRuleTypesWithAuthorization.mockImplementation(async () => { - const authorizedRuleTypes = new Set(); - authorizedRuleTypes.add({ producer: 'apm' }); - return Promise.resolve({ authorizedRuleTypes }); - }); + const filter = { + bool: { + filter: [ + { + bool: { + should: [ + { + bool: { + filter: [ + { + bool: { + should: [{ match: { 'kibana.alert.rule.rule_type_id': '.es-query' } }], + minimum_should_match: 1, + }, + }, + { + bool: { + should: [ + { + bool: { + should: [{ match: { 'kibana.alert.rule.consumer': 'stackAlerts' } }], + minimum_should_match: 1, + }, + }, + { + bool: { + should: [{ match: { 'kibana.alert.rule.consumer': 'alerts' } }], + minimum_should_match: 1, + }, + }, + ], + minimum_should_match: 1, + }, + }, + ], + }, + }, + ], + minimum_should_match: 1, + }, + }, + { term: { 'kibana.space_ids': 'default' } }, + { terms: { 'kibana.alert.rule.rule_type_id': ['.es-query'] } }, + ], + }, + }; - alertingAuthMock.ensureAuthorized.mockImplementation( - // @ts-expect-error - async ({ - ruleTypeId, - consumer, - operation, - entity, - }: { - ruleTypeId: string; - consumer: string; - operation: string; - entity: typeof AlertingAuthorizationEntity.Alert; - }) => { + beforeEach(() => { + jest.resetAllMocks(); + alertingAuthMock.getSpaceId.mockImplementation(() => DEFAULT_SPACE); + alertingAuthMock.getAuthorizationFilter.mockResolvedValue({ + filter: filter as unknown as JsonObject, + ensureRuleTypeIsAuthorized: jest.fn(), + }); + alertingAuthMock.getAllAuthorizedRuleTypes.mockResolvedValue({ + hasAllRequested: true, + authorizedRuleTypes, + }); + + alertingAuthMock.ensureAuthorized.mockImplementation(async ({ ruleTypeId, consumer }) => { if (ruleTypeId === 'apm.error_rate' && consumer === 'apm') { return Promise.resolve(); } return Promise.reject(new Error(`Unauthorized for ${ruleTypeId} and ${consumer}`)); - } - ); -}); + }); + }); -describe('find()', () => { test('calls ES client with given params', async () => { const alertsClient = new AlertsClient(alertsClientParams); const searchAlertsSpy = jest.spyOn(alertsClient as any, 'searchAlerts'); @@ -111,19 +156,25 @@ describe('find()', () => { }); const query = { match: { [ALERT_WORKFLOW_STATUS]: 'open' } }; const index = '.alerts-observability.apm.alerts'; - const featureIds = ['siem']; + const ruleTypeIds = ['siem.esqlRule', 'siem.eqlRule']; + const consumers = ['siem']; + const result = await alertsClient.find({ query, index, - featureIds, + ruleTypeIds, + consumers, }); + expect(searchAlertsSpy).toHaveBeenCalledWith( expect.objectContaining({ query, index, - featureIds, + ruleTypeIds, + consumers, }) ); + expect(result).toMatchInlineSnapshot(` Object { "_shards": Object { @@ -176,12 +227,100 @@ describe('find()', () => { "query": Object { "bool": Object { "filter": Array [ - Object {}, + Object { + "bool": Object { + "filter": Array [ + Object { + "bool": Object { + "minimum_should_match": 1, + "should": Array [ + Object { + "bool": Object { + "filter": Array [ + Object { + "bool": Object { + "minimum_should_match": 1, + "should": Array [ + Object { + "match": Object { + "kibana.alert.rule.rule_type_id": ".es-query", + }, + }, + ], + }, + }, + Object { + "bool": Object { + "minimum_should_match": 1, + "should": Array [ + Object { + "bool": Object { + "minimum_should_match": 1, + "should": Array [ + Object { + "match": Object { + "kibana.alert.rule.consumer": "stackAlerts", + }, + }, + ], + }, + }, + Object { + "bool": Object { + "minimum_should_match": 1, + "should": Array [ + Object { + "match": Object { + "kibana.alert.rule.consumer": "alerts", + }, + }, + ], + }, + }, + ], + }, + }, + ], + }, + }, + ], + }, + }, + Object { + "term": Object { + "kibana.space_ids": "default", + }, + }, + Object { + "terms": Object { + "kibana.alert.rule.rule_type_id": Array [ + ".es-query", + ], + }, + }, + ], + }, + }, Object { "term": Object { "kibana.space_ids": "test_default_space_id", }, }, + Object { + "terms": Object { + "kibana.alert.rule.rule_type_id": Array [ + "siem.esqlRule", + "siem.eqlRule", + ], + }, + }, + Object { + "terms": Object { + "kibana.alert.rule.consumer": Array [ + "siem", + ], + }, + }, ], "must": Array [ Object { @@ -310,7 +449,80 @@ describe('find()', () => { "query": Object { "bool": Object { "filter": Array [ - Object {}, + Object { + "bool": Object { + "filter": Array [ + Object { + "bool": Object { + "minimum_should_match": 1, + "should": Array [ + Object { + "bool": Object { + "filter": Array [ + Object { + "bool": Object { + "minimum_should_match": 1, + "should": Array [ + Object { + "match": Object { + "kibana.alert.rule.rule_type_id": ".es-query", + }, + }, + ], + }, + }, + Object { + "bool": Object { + "minimum_should_match": 1, + "should": Array [ + Object { + "bool": Object { + "minimum_should_match": 1, + "should": Array [ + Object { + "match": Object { + "kibana.alert.rule.consumer": "stackAlerts", + }, + }, + ], + }, + }, + Object { + "bool": Object { + "minimum_should_match": 1, + "should": Array [ + Object { + "match": Object { + "kibana.alert.rule.consumer": "alerts", + }, + }, + ], + }, + }, + ], + }, + }, + ], + }, + }, + ], + }, + }, + Object { + "term": Object { + "kibana.space_ids": "default", + }, + }, + Object { + "terms": Object { + "kibana.alert.rule.rule_type_id": Array [ + ".es-query", + ], + }, + }, + ], + }, + }, Object { "term": Object { "kibana.space_ids": "test_default_space_id", @@ -437,7 +649,7 @@ describe('find()', () => { index: '.alerts-observability.apm.alerts', }) ).rejects.toThrowErrorMatchingInlineSnapshot(` - "Unable to retrieve alert details for alert with id of \\"undefined\\" or with query \\"[object Object]\\" and operation find + "Unable to retrieve alert details for alert with id of \\"undefined\\" or with query \\"{\\"match\\":{\\"kibana.alert.workflow_status\\":\\"open\\"}}\\" and operation find Error: Error: Unauthorized for fake.rule and apm" `); @@ -467,7 +679,7 @@ describe('find()', () => { index: '.alerts-observability.apm.alerts', }) ).rejects.toThrowErrorMatchingInlineSnapshot(` - "Unable to retrieve alert details for alert with id of \\"undefined\\" or with query \\"[object Object]\\" and operation find + "Unable to retrieve alert details for alert with id of \\"undefined\\" or with query \\"{\\"match\\":{\\"kibana.alert.workflow_status\\":\\"open\\"}}\\" and operation find Error: Error: something went wrong" `); }); 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 b48e68c3bf255..b0fcb505d95b6 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 @@ -17,7 +17,6 @@ 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 { AlertingAuthorizationEntity } from '@kbn/alerting-plugin/server'; import { ruleDataServiceMock } from '../../rule_data_plugin_service/rule_data_plugin_service.mock'; const alertingAuthMock = alertingAuthorizationMock.create(); @@ -36,41 +35,38 @@ const alertsClientParams: jest.Mocked = { }; const DEFAULT_SPACE = 'test_default_space_id'; +const authorizedRuleTypes = new Map([ + [ + 'apm.error_rate', + { + producer: 'apm', + id: 'apm.error_rate', + alerts: { + context: 'observability.apm', + }, + authorizedConsumers: {}, + }, + ], +]); beforeEach(() => { jest.resetAllMocks(); alertingAuthMock.getSpaceId.mockImplementation(() => DEFAULT_SPACE); - // @ts-expect-error - alertingAuthMock.getAuthorizationFilter.mockImplementation(async () => - Promise.resolve({ filter: [] }) - ); - - // @ts-expect-error - alertingAuthMock.getAugmentedRuleTypesWithAuthorization.mockImplementation(async () => { - const authorizedRuleTypes = new Set(); - authorizedRuleTypes.add({ producer: 'apm' }); - return Promise.resolve({ authorizedRuleTypes }); + alertingAuthMock.getAuthorizationFilter.mockResolvedValue({ + filter: undefined, + ensureRuleTypeIsAuthorized: jest.fn(), + }); + alertingAuthMock.getAllAuthorizedRuleTypes.mockResolvedValue({ + hasAllRequested: true, + authorizedRuleTypes, }); - alertingAuthMock.ensureAuthorized.mockImplementation( - // @ts-expect-error - async ({ - ruleTypeId, - consumer, - operation, - entity, - }: { - ruleTypeId: string; - consumer: string; - operation: string; - entity: typeof AlertingAuthorizationEntity.Alert; - }) => { - if (ruleTypeId === 'apm.error_rate' && consumer === 'apm') { - return Promise.resolve(); - } - return Promise.reject(new Error(`Unauthorized for ${ruleTypeId} and ${consumer}`)); + alertingAuthMock.ensureAuthorized.mockImplementation(async ({ ruleTypeId, consumer }) => { + if (ruleTypeId === 'apm.error_rate' && consumer === 'apm') { + return Promise.resolve(); } - ); + return Promise.reject(new Error(`Unauthorized for ${ruleTypeId} and ${consumer}`)); + }); }); describe('get()', () => { @@ -150,7 +146,6 @@ describe('get()', () => { ], }, }, - Object {}, Object { "term": Object { "kibana.space_ids": "test_default_space_id", 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 index 777b3d3e26742..0a7b11e2be9b0 100644 --- 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 @@ -5,7 +5,6 @@ * 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'; @@ -38,13 +37,12 @@ beforeEach(() => { 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' }) + alertsClient.getAADFields({ ruleTypeId: 'siem.esqlRule' }) ).rejects.toThrowErrorMatchingInlineSnapshot(`"Security solution rule type is not supported"`); }); }); diff --git a/x-pack/plugins/rule_registry/server/alert_data_client/tests/get_alerts_group_aggregations.test.ts b/x-pack/plugins/rule_registry/server/alert_data_client/tests/get_alerts_group_aggregations.test.ts index c351de1283c2b..2bcafffdeebab 100644 --- a/x-pack/plugins/rule_registry/server/alert_data_client/tests/get_alerts_group_aggregations.test.ts +++ b/x-pack/plugins/rule_registry/server/alert_data_client/tests/get_alerts_group_aggregations.test.ts @@ -5,13 +5,11 @@ * 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 { AlertingAuthorizationEntity } from '@kbn/alerting-plugin/server'; import { ruleDataServiceMock } from '../../rule_data_plugin_service/rule_data_plugin_service.mock'; import { DEFAULT_ALERTS_GROUP_BY_FIELD_SIZE, MAX_ALERTS_GROUPING_QUERY_SIZE } from '../constants'; @@ -33,40 +31,38 @@ const alertsClientParams: jest.Mocked = { }; const DEFAULT_SPACE = 'test_default_space_id'; +const authorizedRuleTypes = new Map([ + [ + 'apm.error_rate', + { + producer: 'apm', + id: 'apm.error_rate', + alerts: { + context: 'observability.apm', + }, + authorizedConsumers: {}, + }, + ], +]); beforeEach(() => { jest.resetAllMocks(); alertingAuthMock.getSpaceId.mockImplementation(() => DEFAULT_SPACE); - // @ts-expect-error - alertingAuthMock.getAuthorizationFilter.mockImplementation(async () => - Promise.resolve({ filter: [] }) - ); - // @ts-expect-error - alertingAuthMock.getAugmentedRuleTypesWithAuthorization.mockImplementation(async () => { - const authorizedRuleTypes = new Set(); - authorizedRuleTypes.add({ producer: 'apm' }); - return Promise.resolve({ authorizedRuleTypes }); + alertingAuthMock.getAuthorizationFilter.mockResolvedValue({ + filter: undefined, + ensureRuleTypeIsAuthorized: jest.fn(), + }); + alertingAuthMock.getAllAuthorizedRuleTypes.mockResolvedValue({ + hasAllRequested: true, + authorizedRuleTypes, }); - alertingAuthMock.ensureAuthorized.mockImplementation( - // @ts-expect-error - async ({ - ruleTypeId, - consumer, - operation, - entity, - }: { - ruleTypeId: string; - consumer: string; - operation: string; - entity: typeof AlertingAuthorizationEntity.Alert; - }) => { - if (ruleTypeId === 'apm.error_rate' && consumer === 'apm') { - return Promise.resolve(); - } - return Promise.reject(new Error(`Unauthorized for ${ruleTypeId} and ${consumer}`)); + alertingAuthMock.ensureAuthorized.mockImplementation(async ({ ruleTypeId, consumer }) => { + if (ruleTypeId === 'apm.error_rate' && consumer === 'apm') { + return Promise.resolve(); } - ); + return Promise.reject(new Error(`Unauthorized for ${ruleTypeId} and ${consumer}`)); + }); }); describe('getGroupAggregations()', () => { @@ -74,7 +70,9 @@ describe('getGroupAggregations()', () => { const alertsClient = new AlertsClient(alertsClientParams); alertsClient.find = jest.fn().mockResolvedValue({ aggregations: {} }); - const featureIds = [AlertConsumers.STACK_ALERTS]; + const ruleTypeIds = ['.es-query']; + const consumers = ['stackAlerts']; + const groupByField = 'kibana.alert.rule.name'; const aggregations = { usersCount: { @@ -86,7 +84,8 @@ describe('getGroupAggregations()', () => { const filters = [{ range: { '@timestamp': { gte: 'now-1d/d', lte: 'now/d' } } }]; await alertsClient.getGroupAggregations({ - featureIds, + ruleTypeIds, + consumers, groupByField, aggregations, filters, @@ -95,7 +94,8 @@ describe('getGroupAggregations()', () => { }); expect(alertsClient.find).toHaveBeenCalledWith({ - featureIds, + ruleTypeIds, + consumers, aggs: { groupByFields: { terms: { @@ -157,7 +157,7 @@ describe('getGroupAggregations()', () => { }); const result = await alertsClient.getGroupAggregations({ - featureIds: [AlertConsumers.STACK_ALERTS], + ruleTypeIds: ['.es-query'], groupByField: 'kibana.alert.rule.name', aggregations: {}, filters: [], @@ -176,7 +176,7 @@ describe('getGroupAggregations()', () => { await expect(() => alertsClient.getGroupAggregations({ - featureIds: ['apm', 'infrastructure', 'logs', 'observability', 'slo', 'uptime'], + ruleTypeIds: ['apm', 'infrastructure', 'logs', 'observability', 'slo', 'uptime'], groupByField: 'kibana.alert.rule.name', pageIndex: 101, pageSize: 50, @@ -186,7 +186,7 @@ describe('getGroupAggregations()', () => { ); await expect(() => alertsClient.getGroupAggregations({ - featureIds: ['apm', 'infrastructure', 'logs', 'observability', 'slo', 'uptime'], + ruleTypeIds: ['apm', 'infrastructure', 'logs', 'observability', 'slo', 'uptime'], groupByField: 'kibana.alert.rule.name', pageIndex: 10, pageSize: 5000, diff --git a/x-pack/plugins/rule_registry/server/alert_data_client/tests/get_alerts_summary.test.ts b/x-pack/plugins/rule_registry/server/alert_data_client/tests/get_alerts_summary.test.ts new file mode 100644 index 0000000000000..deb3b82058843 --- /dev/null +++ b/x-pack/plugins/rule_registry/server/alert_data_client/tests/get_alerts_summary.test.ts @@ -0,0 +1,311 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor 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 { 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'; +import { JsonObject } from '@kbn/utility-types'; + +jest.mock('uuid', () => ({ v4: () => 'unique-value' })); + +const alertingAuthMock = alertingAuthorizationMock.create(); +const esClientMock = elasticsearchClientMock.createElasticsearchClient(); +const auditLogger = auditLoggerMock.create(); + +const alertsClientParams: jest.Mocked = { + logger: loggingSystemMock.create().get(), + authorization: alertingAuthMock, + esClient: esClientMock, + auditLogger, + ruleDataService: ruleDataServiceMock.create(), + getRuleType: jest.fn(), + getRuleList: jest.fn(), + getAlertIndicesAlias: jest.fn().mockReturnValue(['stack-index']), +}; + +const DEFAULT_SPACE = 'test_default_space_id'; +const authorizedRuleTypes = new Map([ + [ + '.es-query', + { + producer: 'stackAlerts', + id: '.es-query', + alerts: { + context: 'stack', + }, + authorizedConsumers: {}, + }, + ], +]); + +const filter = { + bool: { + filter: [ + { + bool: { + should: [ + { + bool: { + filter: [ + { + bool: { + should: [{ match: { 'kibana.alert.rule.rule_type_id': '.es-query' } }], + minimum_should_match: 1, + }, + }, + { + bool: { + should: [ + { + bool: { + should: [{ match: { 'kibana.alert.rule.consumer': 'stackAlerts' } }], + minimum_should_match: 1, + }, + }, + { + bool: { + should: [{ match: { 'kibana.alert.rule.consumer': 'alerts' } }], + minimum_should_match: 1, + }, + }, + ], + minimum_should_match: 1, + }, + }, + ], + }, + }, + ], + minimum_should_match: 1, + }, + }, + { term: { 'kibana.space_ids': 'default' } }, + { terms: { 'kibana.alert.rule.rule_type_id': ['.es-query'] } }, + ], + }, +}; + +describe('getAlertSummary()', () => { + beforeEach(() => { + jest.clearAllMocks(); + alertingAuthMock.getSpaceId.mockImplementation(() => DEFAULT_SPACE); + alertingAuthMock.getAllAuthorizedRuleTypesFindOperation.mockResolvedValue(authorizedRuleTypes); + alertingAuthMock.getAuthorizationFilter.mockResolvedValue({ + filter: filter as unknown as JsonObject, + ensureRuleTypeIsAuthorized: jest.fn(), + }); + }); + + test('calls find() with the correct params', async () => { + const alertsClient = new AlertsClient(alertsClientParams) as jest.Mocked; + alertsClient.find = jest.fn().mockResolvedValue({ aggregations: {} }); + + const ruleTypeIds = ['.es-query']; + const consumers = ['stackAlerts']; + + await alertsClient.getAlertSummary({ + gte: 'now-1d/d', + lte: 'now/d', + ruleTypeIds, + consumers, + }); + + expect(esClientMock.search.mock.calls).toMatchInlineSnapshot(` + Array [ + Array [ + Object { + "body": Object { + "_source": undefined, + "aggs": Object { + "active_alerts_bucket": Object { + "date_histogram": Object { + "extended_bounds": Object { + "max": "now/d", + "min": "now-1d/d", + }, + "field": "kibana.alert.time_range", + "fixed_interval": "1m", + "hard_bounds": Object { + "max": "now/d", + "min": "now-1d/d", + }, + "min_doc_count": 0, + }, + }, + "count": Object { + "terms": Object { + "field": "kibana.alert.status", + }, + }, + "recovered_alerts": Object { + "aggs": Object { + "container": Object { + "date_histogram": Object { + "extended_bounds": Object { + "max": "now/d", + "min": "now-1d/d", + }, + "field": "kibana.alert.end", + "fixed_interval": "1m", + "min_doc_count": 0, + }, + }, + }, + "filter": Object { + "term": Object { + "kibana.alert.status": "recovered", + }, + }, + }, + }, + "fields": Array [ + "kibana.alert.rule.rule_type_id", + "kibana.alert.rule.consumer", + "kibana.alert.workflow_status", + "kibana.space_ids", + ], + "query": Object { + "bool": Object { + "filter": Array [ + Object { + "bool": Object { + "filter": Array [ + Object { + "bool": Object { + "minimum_should_match": 1, + "should": Array [ + Object { + "bool": Object { + "filter": Array [ + Object { + "bool": Object { + "minimum_should_match": 1, + "should": Array [ + Object { + "match": Object { + "kibana.alert.rule.rule_type_id": ".es-query", + }, + }, + ], + }, + }, + Object { + "bool": Object { + "minimum_should_match": 1, + "should": Array [ + Object { + "bool": Object { + "minimum_should_match": 1, + "should": Array [ + Object { + "match": Object { + "kibana.alert.rule.consumer": "stackAlerts", + }, + }, + ], + }, + }, + Object { + "bool": Object { + "minimum_should_match": 1, + "should": Array [ + Object { + "match": Object { + "kibana.alert.rule.consumer": "alerts", + }, + }, + ], + }, + }, + ], + }, + }, + ], + }, + }, + ], + }, + }, + Object { + "term": Object { + "kibana.space_ids": "default", + }, + }, + Object { + "terms": Object { + "kibana.alert.rule.rule_type_id": Array [ + ".es-query", + ], + }, + }, + ], + }, + }, + Object { + "term": Object { + "kibana.space_ids": "test_default_space_id", + }, + }, + Object { + "terms": Object { + "kibana.alert.rule.rule_type_id": Array [ + ".es-query", + ], + }, + }, + Object { + "terms": Object { + "kibana.alert.rule.consumer": Array [ + "stackAlerts", + ], + }, + }, + ], + "must": Array [ + Object { + "bool": Object { + "filter": Array [ + Object { + "range": Object { + "kibana.alert.time_range": Object { + "gt": "now-1d/d", + "lt": "now/d", + }, + }, + }, + ], + }, + }, + ], + "must_not": Array [], + "should": Array [], + }, + }, + "runtime_mappings": undefined, + "size": 0, + "sort": Array [ + Object { + "@timestamp": Object { + "order": "asc", + "unmapped_type": "date", + }, + }, + ], + "track_total_hits": undefined, + }, + "ignore_unavailable": true, + "index": "stack-index", + "seq_no_primary_term": true, + }, + ], + ] + `); + }); +}); 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 bd6a1b2695cd1..4b9587b8e0ca1 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 @@ -16,7 +16,6 @@ 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 { AlertingAuthorizationEntity } from '@kbn/alerting-plugin/server'; import { ruleDataServiceMock } from '../../rule_data_plugin_service/rule_data_plugin_service.mock'; const alertingAuthMock = alertingAuthorizationMock.create(); @@ -35,41 +34,38 @@ const alertsClientParams: jest.Mocked = { }; const DEFAULT_SPACE = 'test_default_space_id'; +const authorizedRuleTypes = new Map([ + [ + 'apm.error_rate', + { + producer: 'apm', + id: 'apm.error_rate', + alerts: { + context: 'observability.apm', + }, + authorizedConsumers: {}, + }, + ], +]); beforeEach(() => { jest.resetAllMocks(); alertingAuthMock.getSpaceId.mockImplementation(() => DEFAULT_SPACE); - // @ts-expect-error - alertingAuthMock.getAuthorizationFilter.mockImplementation(async () => - Promise.resolve({ filter: [] }) - ); - - // @ts-expect-error - alertingAuthMock.getAugmentedRuleTypesWithAuthorization.mockImplementation(async () => { - const authorizedRuleTypes = new Set(); - authorizedRuleTypes.add({ producer: 'apm' }); - return Promise.resolve({ authorizedRuleTypes }); + alertingAuthMock.getAuthorizationFilter.mockResolvedValue({ + filter: undefined, + ensureRuleTypeIsAuthorized: jest.fn(), + }); + alertingAuthMock.getAllAuthorizedRuleTypes.mockResolvedValue({ + hasAllRequested: true, + authorizedRuleTypes, }); - alertingAuthMock.ensureAuthorized.mockImplementation( - // @ts-expect-error - async ({ - ruleTypeId, - consumer, - operation, - entity, - }: { - ruleTypeId: string; - consumer: string; - operation: string; - entity: typeof AlertingAuthorizationEntity.Alert; - }) => { - if (ruleTypeId === 'apm.error_rate' && consumer === 'apm') { - return Promise.resolve(); - } - return Promise.reject(new Error(`Unauthorized for ${ruleTypeId} and ${consumer}`)); + alertingAuthMock.ensureAuthorized.mockImplementation(async ({ ruleTypeId, consumer }) => { + if (ruleTypeId === 'apm.error_rate' && consumer === 'apm') { + return Promise.resolve(); } - ); + return Promise.reject(new Error(`Unauthorized for ${ruleTypeId} and ${consumer}`)); + }); }); describe('update()', () => { diff --git a/x-pack/plugins/rule_registry/server/lib/get_authz_filter.ts b/x-pack/plugins/rule_registry/server/lib/get_authz_filter.ts index e1524b99f88d9..58ea503aa6ed4 100644 --- a/x-pack/plugins/rule_registry/server/lib/get_authz_filter.ts +++ b/x-pack/plugins/rule_registry/server/lib/get_authz_filter.ts @@ -19,17 +19,15 @@ import { export async function getAuthzFilter( authorization: PublicMethodsOf, - operation: WriteOperations.Update | ReadOperations.Get | ReadOperations.Find, - featuresIds?: Set + operation: WriteOperations.Update | ReadOperations.Get | ReadOperations.Find ) { - const { filter } = await authorization.getAuthorizationFilter( - AlertingAuthorizationEntity.Alert, - { + const { filter } = await authorization.getAuthorizationFilter({ + authorizationEntity: AlertingAuthorizationEntity.Alert, + filterOpts: { type: AlertingAuthorizationFilterType.ESDSL, fieldNames: { consumer: ALERT_RULE_CONSUMER, ruleTypeId: ALERT_RULE_TYPE_ID }, }, operation, - featuresIds - ); + }); return filter; } diff --git a/x-pack/plugins/rule_registry/server/lib/get_consumers_filter.test.tsx b/x-pack/plugins/rule_registry/server/lib/get_consumers_filter.test.tsx new file mode 100644 index 0000000000000..600177e1c33ea --- /dev/null +++ b/x-pack/plugins/rule_registry/server/lib/get_consumers_filter.test.tsx @@ -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 { getConsumersFilter } from './get_consumers_filter'; + +describe('getConsumersFilter()', () => { + it('should return a consumers filter', () => { + expect(getConsumersFilter(['foo', 'bar'])).toStrictEqual({ + terms: { + 'kibana.alert.rule.consumer': ['foo', 'bar'], + }, + }); + }); + + it('should return undefined if no consumers are provided', () => { + expect(getConsumersFilter()).toBeUndefined(); + }); + + it('should return undefined if an empty array is provided', () => { + expect(getConsumersFilter([])).toBeUndefined(); + }); +}); diff --git a/x-pack/plugins/rule_registry/server/lib/get_consumers_filter.tsx b/x-pack/plugins/rule_registry/server/lib/get_consumers_filter.tsx new file mode 100644 index 0000000000000..c5089416b7ef5 --- /dev/null +++ b/x-pack/plugins/rule_registry/server/lib/get_consumers_filter.tsx @@ -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. + */ +import { ALERT_RULE_CONSUMER } from '../../common/technical_rule_data_field_names'; + +export function getConsumersFilter(consumers?: string[]) { + return consumers && consumers.length > 0 + ? { terms: { [ALERT_RULE_CONSUMER]: consumers } } + : undefined; +} diff --git a/x-pack/plugins/rule_registry/server/lib/get_rule_type_ids_filter.test.tsx b/x-pack/plugins/rule_registry/server/lib/get_rule_type_ids_filter.test.tsx new file mode 100644 index 0000000000000..7254f25256c2f --- /dev/null +++ b/x-pack/plugins/rule_registry/server/lib/get_rule_type_ids_filter.test.tsx @@ -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 { getRuleTypeIdsFilter } from './get_rule_type_ids_filter'; + +describe('getRuleTypeIdsFilter()', () => { + it('should return a rule type ids filter', () => { + expect(getRuleTypeIdsFilter(['foo', 'bar'])).toStrictEqual({ + terms: { + 'kibana.alert.rule.rule_type_id': ['foo', 'bar'], + }, + }); + }); + + it('should return undefined if no rule type ids are provided', () => { + expect(getRuleTypeIdsFilter()).toBeUndefined(); + }); + + it('should return undefined if an empty array is provided', () => { + expect(getRuleTypeIdsFilter([])).toBeUndefined(); + }); +}); diff --git a/x-pack/plugins/rule_registry/server/lib/get_rule_type_ids_filter.tsx b/x-pack/plugins/rule_registry/server/lib/get_rule_type_ids_filter.tsx new file mode 100644 index 0000000000000..f204d6d17acff --- /dev/null +++ b/x-pack/plugins/rule_registry/server/lib/get_rule_type_ids_filter.tsx @@ -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. + */ +import { ALERT_RULE_TYPE_ID } from '../../common/technical_rule_data_field_names'; + +export function getRuleTypeIdsFilter(ruleTypeIds?: string[]) { + return ruleTypeIds && ruleTypeIds.length > 0 + ? { terms: { [ALERT_RULE_TYPE_ID]: ruleTypeIds } } + : undefined; +} diff --git a/x-pack/plugins/rule_registry/server/plugin.ts b/x-pack/plugins/rule_registry/server/plugin.ts index 60ee2256ae377..ae1159843b170 100644 --- a/x-pack/plugins/rule_registry/server/plugin.ts +++ b/x-pack/plugins/rule_registry/server/plugin.ts @@ -18,10 +18,7 @@ import { ServiceStatusLevels, } from '@kbn/core/server'; -import type { - PluginSetupContract as AlertingSetup, - PluginStartContract as AlertingStart, -} from '@kbn/alerting-plugin/server'; +import type { AlertingServerSetup, AlertingServerStart } from '@kbn/alerting-plugin/server'; import type { SecurityPluginSetup } from '@kbn/security-plugin/server'; import type { SpacesPluginStart } from '@kbn/spaces-plugin/server'; import type { @@ -40,11 +37,11 @@ import { ruleRegistrySearchStrategyProvider, RULE_SEARCH_STRATEGY_NAME } from '. export interface RuleRegistryPluginSetupDependencies { security?: SecurityPluginSetup; data: DataPluginSetup; - alerting: AlertingSetup; + alerting: AlertingServerSetup; } export interface RuleRegistryPluginStartDependencies { - alerting: AlertingStart; + alerting: AlertingServerStart; data: DataPluginStart; spaces?: SpacesPluginStart; } @@ -56,7 +53,7 @@ export interface RuleRegistryPluginSetupContract { export interface RuleRegistryPluginStartContract { getRacClientWithRequest: (req: KibanaRequest) => Promise; - alerting: AlertingStart; + alerting: AlertingServerStart; } export class RuleRegistryPlugin @@ -165,7 +162,7 @@ export class RuleRegistryPlugin logger, esClient: core.elasticsearch.client.asInternalUser, // NOTE: Alerts share the authorization client with the alerting plugin - getAlertingAuthorization(request: KibanaRequest) { + async getAlertingAuthorization(request: KibanaRequest) { return plugins.alerting.getAlertingAuthorizationWithRequest(request); }, securityPluginSetup: security, @@ -175,7 +172,7 @@ export class RuleRegistryPlugin getAlertIndicesAlias: plugins.alerting.getAlertIndicesAlias, }); - const getRacClientWithRequest = (request: KibanaRequest) => { + const getRacClientWithRequest = async (request: KibanaRequest) => { return alertsClientFactory.create(request); }; @@ -190,7 +187,7 @@ export class RuleRegistryPlugin return function alertsRouteHandlerContext(context, request): RacApiRequestHandlerContext { return { getAlertsClient: async () => { - const createdClient = alertsClientFactory.create(request); + const createdClient = await alertsClientFactory.create(request); return createdClient; }, }; diff --git a/x-pack/plugins/rule_registry/server/routes/__mocks__/request_responses.ts b/x-pack/plugins/rule_registry/server/routes/__mocks__/request_responses.ts index d3857c4c49f17..7f214c95b0fcc 100644 --- a/x-pack/plugins/rule_registry/server/routes/__mocks__/request_responses.ts +++ b/x-pack/plugins/rule_registry/server/routes/__mocks__/request_responses.ts @@ -12,7 +12,7 @@ export const getReadIndexRequest = () => requestMock.create({ method: 'get', path: `${BASE_RAC_ALERTS_API_PATH}/index`, - query: { features: 'siem' }, + query: { ruleTypeIds: 'siem.esqlRule' }, }); export const getReadRequest = () => @@ -33,18 +33,18 @@ export const getUpdateRequest = () => }, }); -export const getReadFeatureIdsRequest = () => +export const getFindRequest = () => requestMock.create({ - method: 'get', - path: `${BASE_RAC_ALERTS_API_PATH}/_feature_ids`, - query: { registrationContext: ['security'] }, + method: 'post', + path: `${BASE_RAC_ALERTS_API_PATH}/find`, + body: { rule_type_ids: ['siem.esqlRule'], consumers: ['siem'] }, }); export const getO11yBrowserFields = () => requestMock.create({ method: 'get', path: `${BASE_RAC_ALERTS_API_PATH}/browser_fields`, - query: { featureIds: ['apm', 'logs'] }, + query: { ruleTypeIds: ['apm.anomaly', 'logs.alert.document.count'] }, }); export const getMetricThresholdAADFields = () => @@ -59,7 +59,14 @@ export const getAlertsGroupAggregationsRequest = () => method: 'post', path: `${BASE_RAC_ALERTS_API_PATH}/_group_aggregations`, body: { - featureIds: ['apm', 'infrastructure', 'logs', 'observability', 'slo', 'uptime'], + ruleTypeIds: [ + 'apm.anomaly', + 'logs.alert.document.count', + 'metrics.alert.threshold', + 'slo.rules.burnRate', + 'xpack.uptime.alerts.durationAnomaly', + ], + consumers: ['apm'], groupByField: 'kibana.alert.rule.name', aggregations: { unitsCount: { diff --git a/x-pack/plugins/rule_registry/server/routes/__mocks__/response_adapters.ts b/x-pack/plugins/rule_registry/server/routes/__mocks__/response_adapters.ts index 6afba9e232c5e..1fef218202f2d 100644 --- a/x-pack/plugins/rule_registry/server/routes/__mocks__/response_adapters.ts +++ b/x-pack/plugins/rule_registry/server/routes/__mocks__/response_adapters.ts @@ -39,6 +39,8 @@ const buildResponses = (method: Method, calls: MockCall[]): ResponseCall[] => { status: call.statusCode, body: call.body, })); + case 'notFound': + return calls.map(([call]) => ({ status: 404, body: call.body })); default: throw new Error(`Encountered unexpected call to response.${method}`); } diff --git a/x-pack/plugins/rule_registry/server/routes/find.test.ts b/x-pack/plugins/rule_registry/server/routes/find.test.ts new file mode 100644 index 0000000000000..c84868c39f889 --- /dev/null +++ b/x-pack/plugins/rule_registry/server/routes/find.test.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 { findAlertsByQueryRoute } from './find'; +import { requestContextMock } from './__mocks__/request_context'; +import { getFindRequest } from './__mocks__/request_responses'; +import { serverMock } from './__mocks__/server'; + +describe('findAlertsByQueryRoute', () => { + let server: ReturnType; + let { clients, context } = requestContextMock.createTools(); + + beforeEach(async () => { + server = serverMock.create(); + ({ clients, context } = requestContextMock.createTools()); + + // @ts-expect-error: More properties are not needed + clients.rac.find.mockResolvedValue({ hits: { hits: [] } }); + + findAlertsByQueryRoute(server.router); + }); + + test('returns 200 when querying for alerts', async () => { + const response = await server.inject(getFindRequest(), context); + + expect(response.status).toEqual(200); + expect(response.body).toEqual({ hits: { hits: [] } }); + }); + + test('calls the alerts client correctly', async () => { + const response = await server.inject(getFindRequest(), context); + + expect(response.status).toEqual(200); + expect(clients.rac.find).toHaveBeenCalledWith({ + _source: undefined, + aggs: undefined, + consumers: ['siem'], + index: undefined, + query: undefined, + ruleTypeIds: ['siem.esqlRule'], + search_after: undefined, + size: undefined, + sort: undefined, + track_total_hits: undefined, + }); + }); + + test('accepts not defined ryleTypeIds and consumers', async () => { + const response = await server.inject({ ...getFindRequest(), body: {} }, context); + expect(response.status).toEqual(200); + }); +}); diff --git a/x-pack/plugins/rule_registry/server/routes/find.ts b/x-pack/plugins/rule_registry/server/routes/find.ts index 4ce4567dd35bd..d41de4d64f71f 100644 --- a/x-pack/plugins/rule_registry/server/routes/find.ts +++ b/x-pack/plugins/rule_registry/server/routes/find.ts @@ -25,7 +25,8 @@ export const findAlertsByQueryRoute = (router: IRouter t.exact( t.partial({ aggs: t.record(t.string, t.intersection([metricsAggsSchemas, bucketAggsSchemas])), - feature_ids: t.union([t.array(t.string), t.undefined]), + rule_type_ids: t.union([t.array(t.string), t.undefined]), + consumers: t.union([t.array(t.string), t.undefined]), index: t.string, query: t.object, search_after: t.union([t.array(t.number), t.array(t.string), t.undefined]), @@ -50,7 +51,8 @@ export const findAlertsByQueryRoute = (router: IRouter try { const { aggs, - feature_ids: featureIds, + rule_type_ids: ruleTypeIds, + consumers, index, query, // eslint-disable-next-line @typescript-eslint/naming-convention @@ -65,7 +67,8 @@ export const findAlertsByQueryRoute = (router: IRouter const alertsClient = await racContext.getAlertsClient(); const alerts = await alertsClient.find({ aggs, - featureIds, + ruleTypeIds, + consumers, index, query, search_after, diff --git a/x-pack/plugins/rule_registry/server/routes/get_alert_index.test.ts b/x-pack/plugins/rule_registry/server/routes/get_alert_index.test.ts index b8ef01847d8ea..28d901dc5a137 100644 --- a/x-pack/plugins/rule_registry/server/routes/get_alert_index.test.ts +++ b/x-pack/plugins/rule_registry/server/routes/get_alert_index.test.ts @@ -31,6 +31,28 @@ describe('getAlertsIndexRoute', () => { expect(response.body).toEqual({ index_name: ['alerts-security.alerts'] }); }); + test('accepts an array of string ', async () => { + const ruleTypeIds = ['foo', 'bar']; + + await server.inject({ ...getReadIndexRequest(), query: { ruleTypeIds } }, context); + + expect(clients.rac.getAuthorizedAlertsIndices).toHaveBeenCalledWith(ruleTypeIds); + }); + + test('accepts a single string', async () => { + const ruleTypeIds = 'foo'; + + await server.inject({ ...getReadIndexRequest(), query: { ruleTypeIds } }, context); + + expect(clients.rac.getAuthorizedAlertsIndices).toHaveBeenCalledWith([ruleTypeIds]); + }); + + test('accepts not defined ryleTypeIds', async () => { + await server.inject({ ...getReadIndexRequest(), query: {} }, context); + + expect(clients.rac.getAuthorizedAlertsIndices).toHaveBeenCalledWith(undefined); + }); + describe('request validation', () => { test('rejects invalid query params', async () => { await expect( @@ -38,12 +60,12 @@ describe('getAlertsIndexRoute', () => { requestMock.create({ method: 'get', path: `${BASE_RAC_ALERTS_API_PATH}/index`, - query: { features: 4 }, + query: { ruleTypeIds: 4 }, }), context ) ).rejects.toThrowErrorMatchingInlineSnapshot( - `"Request was rejected with message: 'Invalid value \\"4\\" supplied to \\"features\\"'"` + `"Request was rejected with message: 'Invalid value \\"4\\" supplied to \\"ruleTypeIds\\"'"` ); }); diff --git a/x-pack/plugins/rule_registry/server/routes/get_alert_index.ts b/x-pack/plugins/rule_registry/server/routes/get_alert_index.ts index aa3ec89fde7c8..e83d784bd4fb7 100644 --- a/x-pack/plugins/rule_registry/server/routes/get_alert_index.ts +++ b/x-pack/plugins/rule_registry/server/routes/get_alert_index.ts @@ -8,7 +8,6 @@ import { IRouter } from '@kbn/core/server'; import * as t from 'io-ts'; import { transformError } from '@kbn/securitysolution-es-utils'; -import { validFeatureIds } from '@kbn/rule-data-utils'; import { buildRouteValidation } from './utils/route_validation'; import { RacRequestHandlerContext } from '../types'; @@ -22,7 +21,7 @@ export const getAlertsIndexRoute = (router: IRouter) = query: buildRouteValidation( t.exact( t.partial({ - features: t.string, + ruleTypeIds: t.union([t.string, t.array(t.string)]), }) ) ), @@ -40,10 +39,17 @@ export const getAlertsIndexRoute = (router: IRouter) = try { const racContext = await context.rac; const alertsClient = await racContext.getAlertsClient(); - const { features } = request.query; - const indexName = await alertsClient.getAuthorizedAlertsIndices( - features?.split(',') ?? validFeatureIds - ); + const { ruleTypeIds } = request.query; + + const ruleTypeIdsAsArray = + ruleTypeIds != null + ? Array.isArray(ruleTypeIds) + ? ruleTypeIds + : [ruleTypeIds] + : ruleTypeIds; + + const indexName = await alertsClient.getAuthorizedAlertsIndices(ruleTypeIdsAsArray); + return response.ok({ body: { index_name: indexName }, }); diff --git a/x-pack/plugins/rule_registry/server/routes/get_alert_summary.test.ts b/x-pack/plugins/rule_registry/server/routes/get_alert_summary.test.ts index e15f2d40dc826..961b33310bfc7 100644 --- a/x-pack/plugins/rule_registry/server/routes/get_alert_summary.test.ts +++ b/x-pack/plugins/rule_registry/server/routes/get_alert_summary.test.ts @@ -35,7 +35,7 @@ describe('getAlertSummaryRoute', () => { requestMock.create({ method: 'post', path: `${BASE_RAC_ALERTS_API_PATH}/_alert_summary`, - body: { gte: 4, lte: 3, featureIds: ['logs'] }, + body: { gte: 4, lte: 3, ruleTypeIds: ['logs'] }, }), context ) @@ -52,7 +52,7 @@ describe('getAlertSummaryRoute', () => { body: { gte: '2020-12-16T15:00:00.000Z', lte: '2020-12-16', - featureIds: ['logs'], + ruleTypeIds: ['logs'], }, }), context @@ -76,7 +76,7 @@ describe('getAlertSummaryRoute', () => { body: { gte: '2020-12-16T15:00:00.000Z', lte: '2020-12-16T16:00:00.000Z', - featureIds: ['logs'], + ruleTypeIds: ['logs'], fixed_interval: 'xx', }, }), @@ -102,7 +102,7 @@ describe('getAlertSummaryRoute', () => { body: { gte: '2020-12-16T15:00:00.000Z', lte: '2020-12-16T16:00:00.000Z', - featureIds: ['logs'], + ruleTypeIds: ['logs'], boop: 'unknown', }, }), @@ -112,5 +112,68 @@ describe('getAlertSummaryRoute', () => { `"Request was rejected with message: 'invalid keys \\"boop\\"'"` ); }); + + test('rejects without ruleTypeIds', async () => { + await expect( + server.inject( + requestMock.create({ + method: 'post', + path: `${BASE_RAC_ALERTS_API_PATH}/_alert_summary`, + body: { + gte: '2020-12-16T15:00:00.000Z', + lte: '2020-12-16T16:00:00.000Z', + }, + }), + context + ) + ).rejects.toThrowErrorMatchingInlineSnapshot( + `"Request was rejected with message: 'Invalid value \\"undefined\\" supplied to \\"ruleTypeIds\\"'"` + ); + }); + + test('accepts consumers', async () => { + await expect( + server.inject( + requestMock.create({ + method: 'post', + path: `${BASE_RAC_ALERTS_API_PATH}/_alert_summary`, + body: { + gte: '2020-12-16T15:00:00.000Z', + lte: '2020-12-16T16:00:00.000Z', + consumers: ['foo'], + ruleTypeIds: ['bar'], + }, + }), + context + ) + ).resolves.not.toThrow(); + }); + + test('calls the alerts client correctly', async () => { + await expect( + server.inject( + requestMock.create({ + method: 'post', + path: `${BASE_RAC_ALERTS_API_PATH}/_alert_summary`, + body: { + gte: '2020-12-16T15:00:00.000Z', + lte: '2020-12-16T16:00:00.000Z', + consumers: ['foo'], + ruleTypeIds: ['bar'], + }, + }), + context + ) + ).resolves.not.toThrow(); + + expect(clients.rac.getAlertSummary).toHaveBeenCalledWith({ + consumers: ['foo'], + filter: undefined, + fixedInterval: undefined, + gte: '2020-12-16T15:00:00.000Z', + lte: '2020-12-16T16:00:00.000Z', + ruleTypeIds: ['bar'], + }); + }); }); }); diff --git a/x-pack/plugins/rule_registry/server/routes/get_alert_summary.ts b/x-pack/plugins/rule_registry/server/routes/get_alert_summary.ts index e33b0137a932e..9be3de57fdc0a 100644 --- a/x-pack/plugins/rule_registry/server/routes/get_alert_summary.ts +++ b/x-pack/plugins/rule_registry/server/routes/get_alert_summary.ts @@ -27,13 +27,14 @@ export const getAlertSummaryRoute = (router: IRouter) t.type({ gte: t.string, lte: t.string, - featureIds: t.array(t.string), + ruleTypeIds: t.array(t.string), }) ), t.exact( t.partial({ fixed_interval: t.string, filter: t.array(t.object), + consumers: t.array(t.string), }) ), ]) @@ -52,7 +53,14 @@ export const getAlertSummaryRoute = (router: IRouter) try { const racContext = await context.rac; const alertsClient = await racContext.getAlertsClient(); - const { gte, lte, featureIds, filter, fixed_interval: fixedInterval } = request.body; + const { + gte, + lte, + ruleTypeIds, + consumers, + filter, + fixed_interval: fixedInterval, + } = request.body; if ( !( moment(gte, 'YYYY-MM-DDTHH:mm:ss.SSSZ', true).isValid() && @@ -71,7 +79,8 @@ export const getAlertSummaryRoute = (router: IRouter) const aggs = await alertsClient.getAlertSummary({ gte, lte, - featureIds, + ruleTypeIds, + consumers, filter: filter as estypes.QueryDslQueryContainer[], fixedInterval, }); diff --git a/x-pack/plugins/rule_registry/server/routes/get_alerts_group_aggregations.test.ts b/x-pack/plugins/rule_registry/server/routes/get_alerts_group_aggregations.test.ts index 1ce32adc37e62..5bf3a4a1622cd 100644 --- a/x-pack/plugins/rule_registry/server/routes/get_alerts_group_aggregations.test.ts +++ b/x-pack/plugins/rule_registry/server/routes/get_alerts_group_aggregations.test.ts @@ -200,7 +200,7 @@ describe('getAlertsGroupAggregations', () => { context ) ).rejects.toThrowErrorMatchingInlineSnapshot( - `"Request was rejected with message: 'Invalid value \\"undefined\\" supplied to \\"featureIds\\"'"` + `"Request was rejected with message: 'Invalid value \\"undefined\\" supplied to \\"ruleTypeIds\\"'"` ); }); @@ -211,7 +211,13 @@ describe('getAlertsGroupAggregations', () => { method: 'post', path: `${BASE_RAC_ALERTS_API_PATH}/_group_aggregations`, body: { - featureIds: ['apm', 'infrastructure', 'logs', 'observability', 'slo', 'uptime'], + ruleTypeIds: [ + 'apm.anomaly', + 'logs.alert.document.count', + 'metrics.alert.threshold', + 'slo.rules.burnRate', + 'xpack.uptime.alerts.durationAnomaly', + ], groupByField: 'kibana.alert.rule.name', aggregations: { scriptedAggregation: { @@ -231,7 +237,13 @@ describe('getAlertsGroupAggregations', () => { method: 'post', path: `${BASE_RAC_ALERTS_API_PATH}/_group_aggregations`, body: { - featureIds: ['apm', 'infrastructure', 'logs', 'observability', 'slo', 'uptime'], + ruleTypeIds: [ + 'apm.anomaly', + 'logs.alert.document.count', + 'metrics.alert.threshold', + 'slo.rules.burnRate', + 'xpack.uptime.alerts.durationAnomaly', + ], groupByField: 'kibana.alert.rule.name', filters: [ { @@ -256,7 +268,13 @@ describe('getAlertsGroupAggregations', () => { method: 'post', path: `${BASE_RAC_ALERTS_API_PATH}/_group_aggregations`, body: { - featureIds: ['apm', 'infrastructure', 'logs', 'observability', 'slo', 'uptime'], + ruleTypeIds: [ + 'apm.anomaly', + 'logs.alert.document.count', + 'metrics.alert.threshold', + 'slo.rules.burnRate', + 'xpack.uptime.alerts.durationAnomaly', + ], groupByField: 'kibana.alert.rule.name', aggregations: {}, runtimeMappings: {}, @@ -280,4 +298,84 @@ describe('getAlertsGroupAggregations', () => { message: 'Unable to get alerts', }); }); + + test('rejects without ruleTypeIds', async () => { + await expect( + server.inject( + requestMock.create({ + method: 'post', + path: `${BASE_RAC_ALERTS_API_PATH}/_group_aggregations`, + body: { + groupByField: 'kibana.alert.rule.name', + }, + }), + context + ) + ).rejects.toThrowErrorMatchingInlineSnapshot( + `"Request was rejected with message: 'Invalid value \\"undefined\\" supplied to \\"ruleTypeIds\\"'"` + ); + }); + + test('accepts consumers', async () => { + await expect( + server.inject( + requestMock.create({ + method: 'post', + path: `${BASE_RAC_ALERTS_API_PATH}/_group_aggregations`, + body: { + ruleTypeIds: [ + 'apm.anomaly', + 'logs.alert.document.count', + 'metrics.alert.threshold', + 'slo.rules.burnRate', + 'xpack.uptime.alerts.durationAnomaly', + ], + groupByField: 'kibana.alert.rule.name', + consumers: ['foo'], + }, + }), + context + ) + ).resolves.not.toThrow(); + }); + + test('calls the alerts client correctly', async () => { + await expect( + server.inject( + requestMock.create({ + method: 'post', + path: `${BASE_RAC_ALERTS_API_PATH}/_group_aggregations`, + body: { + ruleTypeIds: [ + 'apm.anomaly', + 'logs.alert.document.count', + 'metrics.alert.threshold', + 'slo.rules.burnRate', + 'xpack.uptime.alerts.durationAnomaly', + ], + groupByField: 'kibana.alert.rule.name', + consumers: ['foo'], + }, + }), + context + ) + ).resolves.not.toThrow(); + + expect(clients.rac.getGroupAggregations).toHaveBeenCalledWith({ + aggregations: undefined, + consumers: ['foo'], + filters: undefined, + groupByField: 'kibana.alert.rule.name', + pageIndex: 0, + pageSize: 10, + ruleTypeIds: [ + 'apm.anomaly', + 'logs.alert.document.count', + 'metrics.alert.threshold', + 'slo.rules.burnRate', + 'xpack.uptime.alerts.durationAnomaly', + ], + sort: undefined, + }); + }); }); diff --git a/x-pack/plugins/rule_registry/server/routes/get_alerts_group_aggregations.ts b/x-pack/plugins/rule_registry/server/routes/get_alerts_group_aggregations.ts index 34c56b7691a1f..6924025f2b33a 100644 --- a/x-pack/plugins/rule_registry/server/routes/get_alerts_group_aggregations.ts +++ b/x-pack/plugins/rule_registry/server/routes/get_alerts_group_aggregations.ts @@ -22,17 +22,24 @@ export const getAlertsGroupAggregations = (router: IRouter { const { - featureIds, + ruleTypeIds, + consumers, groupByField, aggregations, filters, @@ -58,7 +66,8 @@ export const getAlertsGroupAggregations = (router: IRouter { - let server: ReturnType; - let { clients, context } = requestContextMock.createTools(); - const path = `${BASE_RAC_ALERTS_API_PATH}/browser_fields`; - - beforeEach(async () => { - server = serverMock.create(); - ({ clients, context } = requestContextMock.createTools()); - }); - - describe('when racClient returns o11y indices', () => { - beforeEach(() => { - clients.rac.getAuthorizedAlertsIndices.mockResolvedValue([ - '.alerts-observability.logs.alerts-default', - ]); - - getBrowserFieldsByFeatureId(server.router); - }); - - test('route registered', async () => { - const response = await server.inject(getO11yBrowserFields(), context); - - expect(response.status).toEqual(200); - }); - - test('rejects invalid featureId type', async () => { - await expect( - server.inject( - requestMock.create({ - method: 'get', - path, - query: { featureIds: undefined }, - }), - context - ) - ).rejects.toThrowErrorMatchingInlineSnapshot( - `"Request was rejected with message: 'Invalid value \\"undefined\\" supplied to \\"featureIds\\"'"` - ); - }); - - test('returns error status if rac client "getAuthorizedAlertsIndices" fails', async () => { - clients.rac.getAuthorizedAlertsIndices.mockRejectedValue(new Error('Unable to get index')); - const response = await server.inject(getO11yBrowserFields(), context); - - expect(response.status).toEqual(500); - expect(response.body).toEqual({ - attributes: { success: false }, - message: 'Unable to get index', - }); - }); - }); -}); diff --git a/x-pack/plugins/rule_registry/server/routes/get_browser_fields_by_rule_type_ids.test.ts b/x-pack/plugins/rule_registry/server/routes/get_browser_fields_by_rule_type_ids.test.ts new file mode 100644 index 0000000000000..819ed89bc7c08 --- /dev/null +++ b/x-pack/plugins/rule_registry/server/routes/get_browser_fields_by_rule_type_ids.test.ts @@ -0,0 +1,123 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { BASE_RAC_ALERTS_API_PATH } from '../../common/constants'; +import { getBrowserFieldsByFeatureId } from './get_browser_fields_by_rule_type_ids'; +import { requestContextMock } from './__mocks__/request_context'; +import { getO11yBrowserFields } from './__mocks__/request_responses'; +import { requestMock, serverMock } from './__mocks__/server'; + +describe('getBrowserFieldsByFeatureId', () => { + let server: ReturnType; + let { clients, context } = requestContextMock.createTools(); + const path = `${BASE_RAC_ALERTS_API_PATH}/browser_fields`; + + beforeEach(async () => { + server = serverMock.create(); + ({ clients, context } = requestContextMock.createTools()); + + clients.rac.getAuthorizedAlertsIndices.mockResolvedValue([ + '.alerts-observability.logs.alerts-default', + ]); + + clients.rac.getBrowserFields.mockResolvedValue({ browserFields: {}, fields: [] }); + + getBrowserFieldsByFeatureId(server.router); + }); + + test('route registered', async () => { + const response = await server.inject(getO11yBrowserFields(), context); + + expect(response.status).toEqual(200); + }); + + test('it calls getAuthorizedAlertsIndices with o11y rule types', async () => { + const response = await server.inject(getO11yBrowserFields(), context); + + expect(response.status).toEqual(200); + expect(clients.rac.getAuthorizedAlertsIndices).toHaveBeenCalledWith([ + 'apm.anomaly', + 'logs.alert.document.count', + ]); + }); + + test('it calls getAuthorizedAlertsIndices only for o11y rule types when siem rule types are mixed', async () => { + const response = await server.inject( + { + ...getO11yBrowserFields(), + query: { ruleTypeIds: ['apm.anomaly', 'siem.esqlRuleType'] }, + }, + context + ); + + expect(response.status).toEqual(200); + expect(clients.rac.getAuthorizedAlertsIndices).toHaveBeenCalledWith(['apm.anomaly']); + }); + + test('it does not call getAuthorizedAlertsIndices with siem rule types', async () => { + const response = await server.inject( + { + ...getO11yBrowserFields(), + query: { ruleTypeIds: ['siem.esqlRuleType'] }, + }, + context + ); + + expect(response.status).toEqual(200); + expect(clients.rac.getAuthorizedAlertsIndices).not.toHaveBeenCalledWith(); + }); + + test('accepts an array of string ', async () => { + const ruleTypeIds = ['foo', 'bar']; + + await server.inject({ ...getO11yBrowserFields(), query: { ruleTypeIds } }, context); + + expect(clients.rac.getAuthorizedAlertsIndices).toHaveBeenCalledWith(ruleTypeIds); + }); + + test('accepts a single string', async () => { + const ruleTypeIds = 'foo'; + + await server.inject({ ...getO11yBrowserFields(), query: { ruleTypeIds } }, context); + + expect(clients.rac.getAuthorizedAlertsIndices).toHaveBeenCalledWith([ruleTypeIds]); + }); + + test('returns 404 when getAuthorizedAlertsIndices returns an empty array', async () => { + clients.rac.getAuthorizedAlertsIndices.mockResolvedValue([]); + + const response = await server.inject(getO11yBrowserFields(), context); + + expect(response.status).toEqual(404); + }); + + test('rejects invalid ruleTypeIds', async () => { + await expect( + server.inject( + requestMock.create({ + method: 'get', + path, + query: { ruleTypeIds: undefined }, + }), + context + ) + ).rejects.toThrowErrorMatchingInlineSnapshot( + `"Request was rejected with message: 'Invalid value \\"undefined\\" supplied to \\"ruleTypeIds\\"'"` + ); + }); + + test('returns error status if rac client "getAuthorizedAlertsIndices" fails', async () => { + clients.rac.getAuthorizedAlertsIndices.mockRejectedValue(new Error('Unable to get index')); + const response = await server.inject(getO11yBrowserFields(), context); + + expect(response.status).toEqual(500); + expect(response.body).toEqual({ + attributes: { success: false }, + message: 'Unable to get index', + }); + }); +}); 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_rule_type_ids.ts similarity index 83% rename from x-pack/plugins/rule_registry/server/routes/get_browser_fields_by_feature_id.ts rename to x-pack/plugins/rule_registry/server/routes/get_browser_fields_by_rule_type_ids.ts index 20a3781be6973..4c27095ae77c6 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_rule_type_ids.ts @@ -9,6 +9,7 @@ import { IRouter } from '@kbn/core/server'; import { transformError } from '@kbn/securitysolution-es-utils'; import * as t from 'io-ts'; +import { isSiemRuleType } from '@kbn/rule-data-utils'; import { RacRequestHandlerContext } from '../types'; import { BASE_RAC_ALERTS_API_PATH } from '../../common/constants'; import { buildRouteValidation } from './utils/route_validation'; @@ -21,7 +22,7 @@ export const getBrowserFieldsByFeatureId = (router: IRouter fId !== 'siem' - ); + const { ruleTypeIds = [] } = request.query; + + const onlyO11yRuleTypeIds = ( + Array.isArray(ruleTypeIds) ? ruleTypeIds : [ruleTypeIds] + ).filter((ruleTypeId) => !isSiemRuleType(ruleTypeId)); + const o11yIndices = - (onlyO11yFeatureIds - ? await alertsClient.getAuthorizedAlertsIndices(onlyO11yFeatureIds) + (onlyO11yRuleTypeIds + ? await alertsClient.getAuthorizedAlertsIndices(onlyO11yRuleTypeIds) : []) ?? []; + if (o11yIndices.length === 0) { return response.notFound({ body: { - message: `No alerts-observability indices found for featureIds [${featureIds}]`, + message: `No alerts-observability indices found for rule type ids [${onlyO11yRuleTypeIds}]`, attributes: { success: false }, }, }); @@ -58,10 +62,11 @@ export const getBrowserFieldsByFeatureId = (router: IRouter { - let server: ReturnType; - let { clients, context } = requestContextMock.createTools(); - - beforeEach(async () => { - server = serverMock.create(); - ({ clients, context } = requestContextMock.createTools()); - - clients.rac.getFeatureIdsByRegistrationContexts.mockResolvedValue(['siem']); - - getFeatureIdsByRegistrationContexts(server.router); - }); - - test('returns 200 when querying for features ids', async () => { - const response = await server.inject(getReadFeatureIdsRequest(), context); - - expect(response.status).toEqual(200); - expect(response.body).toEqual(['siem']); - }); - - describe('request validation', () => { - test('rejects invalid query params', async () => { - await expect( - server.inject( - requestMock.create({ - method: 'get', - path: `${BASE_RAC_ALERTS_API_PATH}/_feature_ids`, - query: { registrationContext: 4 }, - }), - context - ) - ).rejects.toThrowErrorMatchingInlineSnapshot( - `"Request was rejected with message: 'Invalid value \\"4\\" supplied to \\"registrationContext\\"'"` - ); - }); - - test('rejects unknown query params', async () => { - await expect( - server.inject( - requestMock.create({ - method: 'get', - path: `${BASE_RAC_ALERTS_API_PATH}/_feature_ids`, - query: { boop: 'siem' }, - }), - context - ) - ).rejects.toThrowErrorMatchingInlineSnapshot( - `"Request was rejected with message: 'invalid keys \\"boop\\"'"` - ); - }); - }); - - test('returns error status if rac client "getFeatureIdsByRegistrationContexts" fails', async () => { - clients.rac.getFeatureIdsByRegistrationContexts.mockRejectedValue( - new Error('Unable to get feature ids') - ); - const response = await server.inject(getReadFeatureIdsRequest(), context); - - expect(response.status).toEqual(500); - expect(response.body).toEqual({ - attributes: { success: false }, - message: 'Unable to get feature ids', - }); - }); -}); diff --git a/x-pack/plugins/rule_registry/server/routes/get_feature_ids_by_registration_contexts.ts b/x-pack/plugins/rule_registry/server/routes/get_feature_ids_by_registration_contexts.ts deleted file mode 100644 index 43bd491daafbe..0000000000000 --- a/x-pack/plugins/rule_registry/server/routes/get_feature_ids_by_registration_contexts.ts +++ /dev/null @@ -1,71 +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 { IRouter } from '@kbn/core/server'; -import * as t from 'io-ts'; -import { transformError } from '@kbn/securitysolution-es-utils'; - -import { RacRequestHandlerContext } from '../types'; -import { BASE_RAC_ALERTS_API_PATH } from '../../common/constants'; -import { buildRouteValidation } from './utils/route_validation'; - -export const getFeatureIdsByRegistrationContexts = (router: IRouter) => { - router.get( - { - path: `${BASE_RAC_ALERTS_API_PATH}/_feature_ids`, - validate: { - query: buildRouteValidation( - t.exact( - t.partial({ - registrationContext: t.union([t.string, t.array(t.string)]), - }) - ) - ), - }, - security: { - authz: { - requiredPrivileges: ['rac'], - }, - }, - options: { - access: 'internal', - }, - }, - async (context, request, response) => { - try { - const racContext = await context.rac; - const alertsClient = await racContext.getAlertsClient(); - const { registrationContext = [] } = request.query; - const featureIds = await alertsClient.getFeatureIdsByRegistrationContexts( - Array.isArray(registrationContext) ? registrationContext : [registrationContext] - ); - return response.ok({ - body: featureIds, - }); - } catch (exc) { - const err = transformError(exc); - const contentType = { - 'content-type': 'application/json', - }; - const defaultedHeaders = { - ...contentType, - }; - - return response.customError({ - headers: defaultedHeaders, - statusCode: err.statusCode, - body: { - message: err.message, - attributes: { - success: false, - }, - }, - }); - } - } - ); -}; diff --git a/x-pack/plugins/rule_registry/server/routes/index.ts b/x-pack/plugins/rule_registry/server/routes/index.ts index ae9f113ee0ac1..72ecfc4c9b8ef 100644 --- a/x-pack/plugins/rule_registry/server/routes/index.ts +++ b/x-pack/plugins/rule_registry/server/routes/index.ts @@ -13,8 +13,7 @@ import { updateAlertByIdRoute } from './update_alert_by_id'; import { getAlertsIndexRoute } from './get_alert_index'; import { bulkUpdateAlertsRoute } from './bulk_update_alerts'; import { findAlertsByQueryRoute } from './find'; -import { getFeatureIdsByRegistrationContexts } from './get_feature_ids_by_registration_contexts'; -import { getBrowserFieldsByFeatureId } from './get_browser_fields_by_feature_id'; +import { getBrowserFieldsByFeatureId } from './get_browser_fields_by_rule_type_ids'; import { getAlertSummaryRoute } from './get_alert_summary'; import { getAADFieldsByRuleType } from './get_aad_fields_by_rule_type'; @@ -25,7 +24,6 @@ export function defineRoutes(router: IRouter) { bulkUpdateAlertsRoute(router); findAlertsByQueryRoute(router); getAlertsGroupAggregations(router); - getFeatureIdsByRegistrationContexts(router); getBrowserFieldsByFeatureId(router); getAlertSummaryRoute(router); getAADFieldsByRuleType(router); diff --git a/x-pack/plugins/rule_registry/server/rule_data_plugin_service/rule_data_plugin_service.mock.ts b/x-pack/plugins/rule_registry/server/rule_data_plugin_service/rule_data_plugin_service.mock.ts index 9b279a541b3e9..cfbfafd0092bf 100644 --- a/x-pack/plugins/rule_registry/server/rule_data_plugin_service/rule_data_plugin_service.mock.ts +++ b/x-pack/plugins/rule_registry/server/rule_data_plugin_service/rule_data_plugin_service.mock.ts @@ -17,7 +17,6 @@ export const ruleDataServiceMock = { initializeIndex: jest.fn(), findIndexByName: jest.fn(), findIndexByFeature: jest.fn(), - findFeatureIdsByRegistrationContexts: jest.fn(), }), }; diff --git a/x-pack/plugins/rule_registry/server/rule_data_plugin_service/rule_data_plugin_service.ts b/x-pack/plugins/rule_registry/server/rule_data_plugin_service/rule_data_plugin_service.ts index efe4a5dd4f32f..91192848830ec 100644 --- a/x-pack/plugins/rule_registry/server/rule_data_plugin_service/rule_data_plugin_service.ts +++ b/x-pack/plugins/rule_registry/server/rule_data_plugin_service/rule_data_plugin_service.ts @@ -78,12 +78,6 @@ export interface IRuleDataService { * Note: features are used in RBAC. */ findIndexByFeature(featureId: ValidFeatureId, dataset: Dataset): IndexInfo | null; - - /** - * Looks up Kibana "feature" associated with the given registration context. - * Note: features are used in RBAC. - */ - findFeatureIdsByRegistrationContexts(registrationContexts: string[]): string[]; } // TODO: This is a leftover. Remove its usage from the "observability" plugin and delete it. @@ -248,17 +242,6 @@ export class RuleDataService implements IRuleDataService { return this.indicesByBaseName.get(baseName) ?? null; } - public findFeatureIdsByRegistrationContexts(registrationContexts: string[]): string[] { - const featureIds: string[] = []; - registrationContexts.forEach((rc) => { - const featureId = this.registrationContextByFeatureId.get(rc); - if (featureId) { - featureIds.push(featureId); - } - }); - return featureIds; - } - public findIndexByFeature(featureId: ValidFeatureId, dataset: Dataset): IndexInfo | null { const foundIndices = this.indicesByFeatureId.get(featureId) ?? []; if (dataset && foundIndices.length > 0) { diff --git a/x-pack/plugins/rule_registry/server/search_strategy/search_strategy.test.ts b/x-pack/plugins/rule_registry/server/search_strategy/search_strategy.test.ts index 4dabfb3feb390..1086714ab758a 100644 --- a/x-pack/plugins/rule_registry/server/search_strategy/search_strategy.test.ts +++ b/x-pack/plugins/rule_registry/server/search_strategy/search_strategy.test.ts @@ -4,12 +4,11 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { of } from 'rxjs'; +import { lastValueFrom, of } from 'rxjs'; import { merge } from 'lodash'; import { loggerMock } from '@kbn/logging-mocks'; -import { AlertConsumers } from '@kbn/rule-data-utils'; import { ALERT_EVENTS_FIELDS } from '@kbn/alerts-as-data-utils'; -import { ruleRegistrySearchStrategyProvider, EMPTY_RESPONSE } from './search_strategy'; +import { ruleRegistrySearchStrategyProvider } from './search_strategy'; import { dataPluginMock } from '@kbn/data-plugin/server/mocks'; import { SearchStrategyDependencies } from '@kbn/data-plugin/server'; import { alertsMock } from '@kbn/alerting-plugin/server/mocks'; @@ -18,6 +17,9 @@ import { spacesMock } from '@kbn/spaces-plugin/server/mocks'; import type { RuleRegistrySearchRequest } from '../../common'; import * as getAuthzFilterImport from '../lib/get_authz_filter'; import { getIsKibanaRequest } from '../lib/get_is_kibana_request'; +import { alertingAuthorizationMock } from '@kbn/alerting-plugin/server/authorization/alerting_authorization.mock'; +import { Boom } from '@hapi/boom'; +import { KbnSearchError } from '@kbn/data-plugin/server/search/report_search_error'; jest.mock('../lib/get_is_kibana_request'); @@ -53,8 +55,10 @@ describe('ruleRegistrySearchStrategyProvider()', () => { const security = securityMock.createSetup(); const spaces = spacesMock.createStart(); const logger = loggerMock.create(); + const authorizationMock = alertingAuthorizationMock.create(); const getAuthorizedRuleTypesMock = jest.fn(); const getAlertIndicesAliasMock = jest.fn(); + const response = getBasicResponse({ rawResponse: { hits: { @@ -73,13 +77,19 @@ describe('ruleRegistrySearchStrategyProvider()', () => { const searchStrategySearch = jest.fn().mockImplementation(() => of(response)); beforeEach(() => { + jest.clearAllMocks(); + getAuthorizedRuleTypesMock.mockResolvedValue([]); getAlertIndicesAliasMock.mockReturnValue(['test']); - const authorizationMock = { - getAuthorizedRuleTypes: getAuthorizedRuleTypesMock, - } as never; alerting.getAlertingAuthorizationWithRequest.mockResolvedValue(authorizationMock); alerting.getAlertIndicesAlias = getAlertIndicesAliasMock; + alerting.listTypes.mockReturnValue( + // @ts-expect-error: rule type properties are not needed for the test + new Map([ + ['.es-query', {}], + ['siem.esqlRule', {}], + ]) + ); data.search.getSearchStrategy.mockImplementation(() => { return { @@ -115,7 +125,7 @@ describe('ruleRegistrySearchStrategyProvider()', () => { getAuthorizedRuleTypesMock.mockResolvedValue([]); getAlertIndicesAliasMock.mockReturnValue(['observability-logs']); const request: RuleRegistrySearchRequest = { - featureIds: [AlertConsumers.LOGS], + ruleTypeIds: ['.es-query'], }; const options = {}; const deps = { @@ -124,16 +134,16 @@ describe('ruleRegistrySearchStrategyProvider()', () => { const strategy = ruleRegistrySearchStrategyProvider(data, alerting, logger, security, spaces); - const result = await strategy - .search(request, options, deps as unknown as SearchStrategyDependencies) - .toPromise(); + const result = await lastValueFrom( + strategy.search(request, options, deps as unknown as SearchStrategyDependencies) + ); expect(result).toEqual(response); }); it('should return an empty response if no valid indices are found', async () => { const request: RuleRegistrySearchRequest = { - featureIds: [AlertConsumers.LOGS], + ruleTypeIds: ['.es-query'], }; const options = {}; const deps = { @@ -145,15 +155,30 @@ describe('ruleRegistrySearchStrategyProvider()', () => { const strategy = ruleRegistrySearchStrategyProvider(data, alerting, logger, security, spaces); - const result = await strategy - .search(request, options, deps as unknown as SearchStrategyDependencies) - .toPromise(); - expect(result).toBe(EMPTY_RESPONSE); + const result = await lastValueFrom( + strategy.search(request, options, deps as unknown as SearchStrategyDependencies) + ); + + expect(result).toMatchInlineSnapshot(` + Object { + "inspect": Object { + "dsl": Array [ + "{}", + ], + }, + "rawResponse": Object { + "hits": Object { + "hits": Array [], + "total": 0, + }, + }, + } + `); }); - it('should not apply rbac filters for siem', async () => { + it('should not apply rbac filters for siem rule types', async () => { const request: RuleRegistrySearchRequest = { - featureIds: [AlertConsumers.SIEM], + ruleTypeIds: ['siem.esqlRule'], }; const options = {}; const deps = { @@ -165,15 +190,16 @@ describe('ruleRegistrySearchStrategyProvider()', () => { const strategy = ruleRegistrySearchStrategyProvider(data, alerting, logger, security, spaces); - await strategy - .search(request, options, deps as unknown as SearchStrategyDependencies) - .toPromise(); + await lastValueFrom( + strategy.search(request, options, deps as unknown as SearchStrategyDependencies) + ); + expect(getAuthzFilterSpy).not.toHaveBeenCalled(); }); - it('should throw an error if requesting multiple featureIds and one is SIEM', async () => { + it('should throw an error if requesting multiple rule types and one is for siem', async () => { const request: RuleRegistrySearchRequest = { - featureIds: [AlertConsumers.SIEM, AlertConsumers.LOGS], + ruleTypeIds: ['.es-query', 'siem.esqlRule'], }; const options = {}; const deps = { @@ -186,19 +212,70 @@ describe('ruleRegistrySearchStrategyProvider()', () => { const strategy = ruleRegistrySearchStrategyProvider(data, alerting, logger, security, spaces); let err; + try { - await strategy - .search(request, options, deps as unknown as SearchStrategyDependencies) - .toPromise(); + await lastValueFrom( + strategy.search(request, options, deps as unknown as SearchStrategyDependencies) + ); } catch (e) { err = e; } - expect(err).toBeDefined(); + + expect(err.statusCode).toBe(400); + expect(err.message).toBe( + 'The privateRuleRegistryAlertsSearchStrategy search strategy is unable to accommodate requests containing multiple rule types with mixed authorization.' + ); + }); + + it('should not throw an error with empty rule type ids', async () => { + const request: RuleRegistrySearchRequest = { + ruleTypeIds: [], + }; + + const options = {}; + const deps = { + request: {}, + }; + + getAuthorizedRuleTypesMock.mockResolvedValue([]); + getAlertIndicesAliasMock.mockReturnValue([]); + + const strategy = ruleRegistrySearchStrategyProvider(data, alerting, logger, security, spaces); + + await expect( + lastValueFrom( + strategy.search(request, options, deps as unknown as SearchStrategyDependencies) + ) + ).resolves.not.toThrow(); + }); + + it('should filter out invalid rule types', async () => { + const request: RuleRegistrySearchRequest = { + ruleTypeIds: ['.es-query', 'not-exist'], + }; + + const options = {}; + const deps = { + request: {}, + }; + + const strategy = ruleRegistrySearchStrategyProvider(data, alerting, logger, security, spaces); + + await expect( + lastValueFrom( + strategy.search(request, options, deps as unknown as SearchStrategyDependencies) + ) + ).resolves.not.toThrow(); + + expect(authorizationMock.getAllAuthorizedRuleTypesFindOperation).toHaveBeenCalledWith({ + authorizationEntity: 'alert', + ruleTypeIds: ['.es-query'], + }); }); it('should use internal user when requesting o11y alerts as RBAC is applied', async () => { const request: RuleRegistrySearchRequest = { - featureIds: [AlertConsumers.LOGS], + ruleTypeIds: ['.es-query'], }; const options = {}; const deps = { @@ -209,16 +286,17 @@ describe('ruleRegistrySearchStrategyProvider()', () => { const strategy = ruleRegistrySearchStrategyProvider(data, alerting, logger, security, spaces); - await strategy - .search(request, options, deps as unknown as SearchStrategyDependencies) - .toPromise(); + await lastValueFrom( + strategy.search(request, options, deps as unknown as SearchStrategyDependencies) + ); + expect(data.search.searchAsInternalUser.search).toHaveBeenCalled(); expect(searchStrategySearch).not.toHaveBeenCalled(); }); it('should use scoped user when requesting siem alerts as RBAC is not applied', async () => { const request: RuleRegistrySearchRequest = { - featureIds: [AlertConsumers.SIEM], + ruleTypeIds: ['siem.esqlRule'], }; const options = {}; const deps = { @@ -230,16 +308,17 @@ describe('ruleRegistrySearchStrategyProvider()', () => { const strategy = ruleRegistrySearchStrategyProvider(data, alerting, logger, security, spaces); - await strategy - .search(request, options, deps as unknown as SearchStrategyDependencies) - .toPromise(); + await lastValueFrom( + strategy.search(request, options, deps as unknown as SearchStrategyDependencies) + ); + expect(data.search.searchAsInternalUser.search as jest.Mock).not.toHaveBeenCalled(); expect(searchStrategySearch).toHaveBeenCalled(); }); it('should support pagination', async () => { const request: RuleRegistrySearchRequest = { - featureIds: [AlertConsumers.LOGS], + ruleTypeIds: ['.es-query'], pagination: { pageSize: 10, pageIndex: 0, @@ -254,9 +333,10 @@ describe('ruleRegistrySearchStrategyProvider()', () => { const strategy = ruleRegistrySearchStrategyProvider(data, alerting, logger, security, spaces); - await strategy - .search(request, options, deps as unknown as SearchStrategyDependencies) - .toPromise(); + await lastValueFrom( + strategy.search(request, options, deps as unknown as SearchStrategyDependencies) + ); + expect((data.search.searchAsInternalUser.search as jest.Mock).mock.calls.length).toBe(1); expect( (data.search.searchAsInternalUser.search as jest.Mock).mock.calls[0][0].params.body.size @@ -268,7 +348,7 @@ describe('ruleRegistrySearchStrategyProvider()', () => { it('should support sorting', async () => { const request: RuleRegistrySearchRequest = { - featureIds: [AlertConsumers.LOGS], + ruleTypeIds: ['.es-query'], sort: [ { test: { @@ -286,9 +366,10 @@ describe('ruleRegistrySearchStrategyProvider()', () => { const strategy = ruleRegistrySearchStrategyProvider(data, alerting, logger, security, spaces); - await strategy - .search(request, options, deps as unknown as SearchStrategyDependencies) - .toPromise(); + await lastValueFrom( + strategy.search(request, options, deps as unknown as SearchStrategyDependencies) + ); + expect((data.search.searchAsInternalUser.search as jest.Mock).mock.calls.length).toBe(1); expect( (data.search.searchAsInternalUser.search as jest.Mock).mock.calls[0][0].params.body.sort @@ -297,7 +378,7 @@ describe('ruleRegistrySearchStrategyProvider()', () => { it('passes the query ids if provided', async () => { const request: RuleRegistrySearchRequest = { - featureIds: [AlertConsumers.SIEM], + ruleTypeIds: ['siem.esqlRule'], query: { ids: { values: ['test-id'] }, }, @@ -311,21 +392,24 @@ describe('ruleRegistrySearchStrategyProvider()', () => { const strategy = ruleRegistrySearchStrategyProvider(data, alerting, logger, security, spaces); - await strategy - .search(request, options, deps as unknown as SearchStrategyDependencies) - .toPromise(); + await lastValueFrom( + strategy.search(request, options, deps as unknown as SearchStrategyDependencies) + ); + const arg0 = searchStrategySearch.mock.calls[0][0]; expect(arg0.params.body.fields.length).toEqual( // +2 because of fields.push({ field: 'kibana.alert.*', include_unmapped: false }); and // fields.push({ field: 'signal.*', include_unmapped: false }); ALERT_EVENTS_FIELDS.length + 2 ); + expect.arrayContaining([ expect.objectContaining({ x: 2, y: 3, }), ]); + expect(arg0).toEqual( expect.objectContaining({ id: undefined, @@ -355,9 +439,9 @@ describe('ruleRegistrySearchStrategyProvider()', () => { ); }); - it('passes the fields if provided', async () => { + it('passes the fields if provided for siem rule types', async () => { const request: RuleRegistrySearchRequest = { - featureIds: [AlertConsumers.SIEM], + ruleTypeIds: ['siem.esqlRule'], query: { ids: { values: ['test-id'] }, }, @@ -372,42 +456,264 @@ describe('ruleRegistrySearchStrategyProvider()', () => { const strategy = ruleRegistrySearchStrategyProvider(data, alerting, logger, security, spaces); - await strategy - .search(request, options, deps as unknown as SearchStrategyDependencies) - .toPromise(); + await lastValueFrom( + strategy.search(request, options, deps as unknown as SearchStrategyDependencies) + ); const arg0 = searchStrategySearch.mock.calls[0][0]; - expect(arg0.params.body.fields.length).toEqual( + const fields = arg0.params.body.fields; + + expect(fields.length).toEqual( // +2 because of fields.push({ field: 'kibana.alert.*', include_unmapped: false }); and // fields.push({ field: 'signal.*', include_unmapped: false }); + my-super-field ALERT_EVENTS_FIELDS.length + 3 ); - expect(arg0).toEqual( - expect.objectContaining({ - id: undefined, - params: expect.objectContaining({ - allow_no_indices: true, - body: expect.objectContaining({ - _source: false, - fields: expect.arrayContaining([ - expect.objectContaining({ - field: 'my-super-field', - include_unmapped: true, - }), - ]), - from: 0, - query: { - ids: { - values: ['test-id'], + + const siemField = fields.find((field: { field: string }) => field.field === 'signal.*'); + const kibanaField = fields.find((field: { field: string }) => field.field === 'kibana.alert.*'); + const myField = fields.find((field: { field: string }) => field.field === 'my-super-field'); + + expect(siemField).toMatchInlineSnapshot(` + Object { + "field": "signal.*", + "include_unmapped": false, + } + `); + + expect(kibanaField).toMatchInlineSnapshot(` + Object { + "field": "kibana.alert.*", + "include_unmapped": false, + } + `); + + expect(myField).toMatchInlineSnapshot(` + Object { + "field": "my-super-field", + "include_unmapped": true, + } + `); + }); + + it('passes the fields if provided for o11y rule types', async () => { + const request: RuleRegistrySearchRequest = { + ruleTypeIds: ['.es-query'], + query: { + ids: { values: ['test-id'] }, + }, + fields: [{ field: 'my-super-field', include_unmapped: true }], + }; + const options = {}; + const deps = { + request: {}, + }; + getAuthorizedRuleTypesMock.mockResolvedValue([]); + getAlertIndicesAliasMock.mockReturnValue(['security-siem']); + + const strategy = ruleRegistrySearchStrategyProvider(data, alerting, logger, security, spaces); + + await lastValueFrom( + strategy.search(request, options, deps as unknown as SearchStrategyDependencies) + ); + + const arg0 = (data.search.searchAsInternalUser.search as jest.Mock).mock.calls[0][0]; + const fields = arg0.params.body.fields; + + expect(fields.length).toEqual( + // +2 because of fields.push({ field: 'kibana.alert.*', include_unmapped: false }); and + // fields.push({ field: '*', include_unmapped: false }); + my-super-field + 3 + ); + + const allField = fields.find((field: { field: string }) => field.field === '*'); + const kibanaField = fields.find((field: { field: string }) => field.field === 'kibana.alert.*'); + const myField = fields.find((field: { field: string }) => field.field === 'my-super-field'); + + expect(allField).toMatchInlineSnapshot(` + Object { + "field": "*", + "include_unmapped": true, + } + `); + + expect(kibanaField).toMatchInlineSnapshot(` + Object { + "field": "kibana.alert.*", + "include_unmapped": false, + } + `); + + expect(myField).toMatchInlineSnapshot(` + Object { + "field": "my-super-field", + "include_unmapped": true, + } + `); + }); + + it('should handle Boom errors correctly', async () => { + getAuthzFilterSpy.mockRejectedValue(new Boom('boom error message', { statusCode: 400 })); + + const request: RuleRegistrySearchRequest = { + ruleTypeIds: ['.es-query'], + }; + + const options = {}; + const deps = { + request: {}, + }; + + const strategy = ruleRegistrySearchStrategyProvider(data, alerting, logger, security, spaces); + + let err; + + try { + await lastValueFrom( + strategy.search(request, options, deps as unknown as SearchStrategyDependencies) + ); + } catch (e) { + err = e; + } + + expect(err.statusCode).toBe(400); + expect(err.message).toBe('boom error message'); + }); + + it('should handle KbnSearchError errors correctly', async () => { + getAuthzFilterSpy.mockRejectedValue(new KbnSearchError('kbn search error message', 403)); + + const request: RuleRegistrySearchRequest = { + ruleTypeIds: ['.es-query'], + }; + + const options = {}; + const deps = { + request: {}, + }; + + const strategy = ruleRegistrySearchStrategyProvider(data, alerting, logger, security, spaces); + + let err; + + try { + await lastValueFrom( + strategy.search(request, options, deps as unknown as SearchStrategyDependencies) + ); + } catch (e) { + err = e; + } + + expect(err.statusCode).toBe(403); + expect(err.message).toBe('kbn search error message'); + }); + + it('should convert errors to KbnSearchError errors correctly', async () => { + getAuthzFilterSpy.mockRejectedValue(new Error('plain error message')); + + const request: RuleRegistrySearchRequest = { + ruleTypeIds: ['.es-query'], + }; + + const options = {}; + const deps = { + request: {}, + }; + + const strategy = ruleRegistrySearchStrategyProvider(data, alerting, logger, security, spaces); + + let err; + + try { + await lastValueFrom( + strategy.search(request, options, deps as unknown as SearchStrategyDependencies) + ); + } catch (e) { + err = e; + } + + expect(err.statusCode).toBe(500); + expect(err.message).toBe('plain error message'); + }); + + it('should apply the rule type IDs filter', async () => { + const request: RuleRegistrySearchRequest = { + ruleTypeIds: ['siem.esqlRule'], + }; + + const options = {}; + const deps = { + request: {}, + }; + + getAuthorizedRuleTypesMock.mockResolvedValue([]); + getAlertIndicesAliasMock.mockReturnValue(['security-siem']); + + const strategy = ruleRegistrySearchStrategyProvider(data, alerting, logger, security, spaces); + + await lastValueFrom( + strategy.search(request, options, deps as unknown as SearchStrategyDependencies) + ); + + const arg0 = searchStrategySearch.mock.calls[0][0]; + expect(arg0.params.body.query).toMatchInlineSnapshot(` + Object { + "bool": Object { + "filter": Array [ + Object { + "terms": Object { + "kibana.alert.rule.rule_type_id": Array [ + "siem.esqlRule", + ], }, }, - size: 1000, - sort: [], - }), - ignore_unavailable: true, - index: ['security-siem'], - }), - }) + ], + }, + } + `); + }); + + it('should apply the consumers filter', async () => { + const request: RuleRegistrySearchRequest = { + ruleTypeIds: ['siem.esqlRule'], + consumers: ['alerts'], + }; + + const options = {}; + const deps = { + request: {}, + }; + + getAuthorizedRuleTypesMock.mockResolvedValue([]); + getAlertIndicesAliasMock.mockReturnValue(['security-siem']); + + const strategy = ruleRegistrySearchStrategyProvider(data, alerting, logger, security, spaces); + + await lastValueFrom( + strategy.search(request, options, deps as unknown as SearchStrategyDependencies) ); + + const arg0 = searchStrategySearch.mock.calls[0][0]; + expect(arg0.params.body.query).toMatchInlineSnapshot(` + Object { + "bool": Object { + "filter": Array [ + Object { + "terms": Object { + "kibana.alert.rule.consumer": Array [ + "alerts", + ], + }, + }, + Object { + "terms": Object { + "kibana.alert.rule.rule_type_id": Array [ + "siem.esqlRule", + ], + }, + }, + ], + }, + } + `); }); }); diff --git a/x-pack/plugins/rule_registry/server/search_strategy/search_strategy.ts b/x-pack/plugins/rule_registry/server/search_strategy/search_strategy.ts index a497008086c88..246b38aaf733d 100644 --- a/x-pack/plugins/rule_registry/server/search_strategy/search_strategy.ts +++ b/x-pack/plugins/rule_registry/server/search_strategy/search_strategy.ts @@ -4,28 +4,36 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { map, mergeMap, catchError } from 'rxjs'; + +import Boom from '@hapi/boom'; +import { map, mergeMap, catchError, of } from 'rxjs'; import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import { Logger } from '@kbn/core/server'; -import { from, of } from 'rxjs'; -import { isValidFeatureId, AlertConsumers } from '@kbn/rule-data-utils'; +import { from } from 'rxjs'; import { ENHANCED_ES_SEARCH_STRATEGY } from '@kbn/data-plugin/common'; import { ISearchStrategy, PluginStart } from '@kbn/data-plugin/server'; import { ReadOperations, - PluginStartContract as AlertingStart, + AlertingServerStart, AlertingAuthorizationEntity, } from '@kbn/alerting-plugin/server'; import { SecurityPluginSetup } from '@kbn/security-plugin/server'; import { SpacesPluginStart } from '@kbn/spaces-plugin/server'; import { buildAlertFieldsRequest } from '@kbn/alerts-as-data-utils'; +import { partition } from 'lodash'; +import { isSiemRuleType } from '@kbn/rule-data-utils'; +import { KbnSearchError } from '@kbn/data-plugin/server/search/report_search_error'; import type { RuleRegistrySearchRequest, RuleRegistrySearchResponse } from '../../common'; import { MAX_ALERT_SEARCH_SIZE } from '../../common/constants'; import { AlertAuditAction, alertAuditEvent } from '..'; import { getSpacesFilter, getAuthzFilter } from '../lib'; +import { getRuleTypeIdsFilter } from '../lib/get_rule_type_ids_filter'; +import { getConsumersFilter } from '../lib/get_consumers_filter'; export const EMPTY_RESPONSE: RuleRegistrySearchResponse = { - rawResponse: {} as RuleRegistrySearchResponse['rawResponse'], + rawResponse: { + hits: { total: 0, hits: [] }, + } as unknown as RuleRegistrySearchResponse['rawResponse'], }; export const RULE_SEARCH_STRATEGY_NAME = 'privateRuleRegistryAlertsSearchStrategy'; @@ -35,7 +43,7 @@ const EXCLUDED_RULE_TYPE_IDS = ['siem.notifications']; export const ruleRegistrySearchStrategyProvider = ( data: PluginStart, - alerting: AlertingStart, + alerting: AlertingServerStart, logger: Logger, security?: SecurityPluginSetup, spaces?: SpacesPluginStart @@ -44,57 +52,69 @@ export const ruleRegistrySearchStrategyProvider = ( const requestUserEs = data.search.getSearchStrategy(ENHANCED_ES_SEARCH_STRATEGY); return { search: (request, options, deps) => { + let params = {}; + // SIEM uses RBAC fields in their alerts but also utilizes ES DLS which // is different than every other solution so we need to special case // those requests. - let siemRequest = false; - let params = {}; - if (request.featureIds.length === 1 && request.featureIds[0] === AlertConsumers.SIEM) { - siemRequest = true; - } else if (request.featureIds.includes(AlertConsumers.SIEM)) { - throw new Error( - `The ${RULE_SEARCH_STRATEGY_NAME} search strategy is unable to accommodate requests containing multiple feature IDs and one of those IDs is SIEM.` + const isAnyRuleTypeESAuthorized = request.ruleTypeIds.some(isSiemRuleType); + const isEachRuleTypeESAuthorized = + // every returns true for empty arrays + request.ruleTypeIds.length > 0 && request.ruleTypeIds.every(isSiemRuleType); + + const registeredRuleTypes = alerting.listTypes(); + + const [validRuleTypeIds, invalidRuleTypeIds] = partition(request.ruleTypeIds, (ruleTypeId) => + registeredRuleTypes.has(ruleTypeId) + ); + + if (isAnyRuleTypeESAuthorized && !isEachRuleTypeESAuthorized) { + throw new KbnSearchError( + `The ${RULE_SEARCH_STRATEGY_NAME} search strategy is unable to accommodate requests containing multiple rule types with mixed authorization.`, + 400 ); } - request.featureIds.forEach((featureId) => { - if (!isValidFeatureId(featureId)) { - logger.warn( - `Found invalid feature '${featureId}' while using ${RULE_SEARCH_STRATEGY_NAME} search strategy. No alert data from this feature will be searched.` - ); - } + + invalidRuleTypeIds.forEach((ruleTypeId) => { + logger.warn( + `Found invalid rule type '${ruleTypeId}' while using ${RULE_SEARCH_STRATEGY_NAME} search strategy. No alert data from this rule type will be searched.` + ); }); const securityAuditLogger = security?.audit.asScoped(deps.request); const getActiveSpace = async () => spaces?.spacesService.getActiveSpace(deps.request); - const getAsync = async (featureIds: string[]) => { + + const getAsync = async (ruleTypeIds: string[]) => { const [space, authorization] = await Promise.all([ getActiveSpace(), alerting.getAlertingAuthorizationWithRequest(deps.request), ]); + let authzFilter; - const fIds = new Set(featureIds); - if (!siemRequest && featureIds.length > 0) { + + if (!isAnyRuleTypeESAuthorized && ruleTypeIds.length > 0) { authzFilter = (await getAuthzFilter( authorization, - ReadOperations.Find, - fIds + ReadOperations.Find )) as estypes.QueryDslQueryContainer; } - const authorizedRuleTypes = - featureIds.length > 0 - ? await authorization.getAuthorizedRuleTypes(AlertingAuthorizationEntity.Alert, fIds) - : []; + const authorizedRuleTypes = await authorization.getAllAuthorizedRuleTypesFindOperation({ + authorizationEntity: AlertingAuthorizationEntity.Alert, + ruleTypeIds, + }); return { space, authzFilter, authorizedRuleTypes }; }; - return from(getAsync(request.featureIds)).pipe( + return from(getAsync(validRuleTypeIds)).pipe( mergeMap(({ space, authzFilter, authorizedRuleTypes }) => { - const allRuleTypes = authorizedRuleTypes.map((art: { id: string }) => art.id); - const ruleTypes = (allRuleTypes ?? []).filter( + const authorizedRuleTypesIds = Array.from(authorizedRuleTypes.keys()); + const ruleTypes = (authorizedRuleTypesIds ?? []).filter( (ruleTypeId: string) => !EXCLUDED_RULE_TYPE_IDS.includes(ruleTypeId) ); + const indices = alerting.getAlertIndicesAlias(ruleTypes, space?.id); + if (indices.length === 0) { return of(EMPTY_RESPONSE); } @@ -104,13 +124,26 @@ export const ruleRegistrySearchStrategyProvider = ( ? request.query?.bool?.filter : [request.query?.bool?.filter] : []; + if (authzFilter) { filter.push(authzFilter); } + if (space?.id) { filter.push(getSpacesFilter(space.id) as estypes.QueryDslQueryContainer); } + const ruleTypeFilter = getRuleTypeIdsFilter(request.ruleTypeIds); + const consumersFilter = getConsumersFilter(request.consumers); + + if (consumersFilter) { + filter.push(consumersFilter); + } + + if (ruleTypeFilter) { + filter.push(ruleTypeFilter); + } + const sort = request.sort ?? []; const query = { @@ -123,10 +156,11 @@ export const ruleRegistrySearchStrategyProvider = ( }, }), }; + let fields = request?.fields ?? []; fields.push({ field: 'kibana.alert.*', include_unmapped: false }); - if (siemRequest) { + if (isAnyRuleTypeESAuthorized) { fields.push({ field: 'signal.*', include_unmapped: false }); fields = fields.concat(buildAlertFieldsRequest([], false)); } else { @@ -149,7 +183,7 @@ export const ruleRegistrySearchStrategyProvider = ( ...(request.runtimeMappings ? { runtime_mappings: request.runtimeMappings } : {}), }, }; - return (siemRequest ? requestUserEs : internalUserEs).search( + return (isAnyRuleTypeESAuthorized ? requestUserEs : internalUserEs).search( { id: request.id, params }, options, deps @@ -180,7 +214,6 @@ export const ruleRegistrySearchStrategyProvider = ( return response; }), catchError((err) => { - // check if auth error, if yes, write to ecs logger if (securityAuditLogger != null && err?.output?.statusCode === 403) { securityAuditLogger.log( alertAuditEvent({ @@ -191,7 +224,15 @@ export const ruleRegistrySearchStrategyProvider = ( ); } - throw err; + if (Boom.isBoom(err)) { + throw new KbnSearchError(err.output.payload.message, err.output.statusCode); + } + + if (err instanceof KbnSearchError) { + throw err; + } + + throw new KbnSearchError(err.message, 500); }) ); }, diff --git a/x-pack/plugins/search_assistant/public/plugin.tsx b/x-pack/plugins/search_assistant/public/plugin.tsx index 15c1443045cdc..ef65f256d7b36 100644 --- a/x-pack/plugins/search_assistant/public/plugin.tsx +++ b/x-pack/plugins/search_assistant/public/plugin.tsx @@ -54,8 +54,9 @@ export class SearchAssistantPlugin pluginsStart, }); const isEnabled = appService.isEnabled(); + const aiAssistantIsEnabled = coreStart.application.capabilities.observabilityAIAssistant?.show; - if (!isEnabled) { + if (!isEnabled || !aiAssistantIsEnabled) { return {}; } diff --git a/x-pack/plugins/search_playground/kibana.jsonc b/x-pack/plugins/search_playground/kibana.jsonc index 37562347e9f37..3c4eaaddc81a2 100644 --- a/x-pack/plugins/search_playground/kibana.jsonc +++ b/x-pack/plugins/search_playground/kibana.jsonc @@ -18,6 +18,7 @@ "actions", "data", "encryptedSavedObjects", + "ml", "navigation", "share", "security", diff --git a/x-pack/plugins/security/server/usage_collector/security_usage_collector.test.ts b/x-pack/plugins/security/server/usage_collector/security_usage_collector.test.ts index 19378bfd8488b..72b9e44da3f43 100644 --- a/x-pack/plugins/security/server/usage_collector/security_usage_collector.test.ts +++ b/x-pack/plugins/security/server/usage_collector/security_usage_collector.test.ts @@ -26,6 +26,7 @@ describe('Security UsageCollector', () => { allowAccessAgreement = true, allowAuditLogging = true, allowRbac = true, + allowFips = true, isLicenseAvailable, }: Partial & { isLicenseAvailable: boolean }) => { const license = licenseMock.create(); @@ -34,6 +35,7 @@ describe('Security UsageCollector', () => { allowAccessAgreement, allowAuditLogging, allowRbac, + allowFips, } as SecurityLicenseFeatures); return license; }; @@ -44,6 +46,7 @@ describe('Security UsageCollector', () => { accessAgreementEnabled: false, authProviderCount: 1, enabledAuthProviders: ['basic'], + fipsModeEnabled: false, loginSelectorEnabled: false, httpAuthSchemes: ['apikey', 'bearer'], sessionIdleTimeoutInMinutes: 4320, @@ -106,6 +109,7 @@ describe('Security UsageCollector', () => { accessAgreementEnabled: false, authProviderCount: 0, enabledAuthProviders: [], + fipsModeEnabled: false, loginSelectorEnabled: false, httpAuthSchemes: [], sessionIdleTimeoutInMinutes: 0, @@ -426,6 +430,55 @@ describe('Security UsageCollector', () => { }); }); + describe('fipsMode enabled', () => { + it('reports when fipsMode is enabled', async () => { + const config = createSecurityConfig( + ConfigSchema.validate({ + fipsMode: { + enabled: true, + }, + }) + ); + const usageCollection = usageCollectionPluginMock.createSetupContract(); + const license = createSecurityLicense({ + isLicenseAvailable: true, + allowFips: true, + }); + registerSecurityUsageCollector({ usageCollection, config, license }); + + const usage = await usageCollection + .getCollectorByType('security') + ?.fetch(collectorFetchContext); + + expect(usage).toEqual({ + ...DEFAULT_USAGE, + fipsModeEnabled: true, + }); + }); + + it('does not report fipsMode when the license does not permit it', async () => { + const config = createSecurityConfig( + ConfigSchema.validate({ + fipsMode: { + enabled: true, + }, + }) + ); + const usageCollection = usageCollectionPluginMock.createSetupContract(); + const license = createSecurityLicense({ isLicenseAvailable: true, allowFips: false }); + registerSecurityUsageCollector({ usageCollection, config, license }); + + const usage = await usageCollection + .getCollectorByType('security') + ?.fetch(collectorFetchContext); + + expect(usage).toEqual({ + ...DEFAULT_USAGE, + fipsModeEnabled: false, + }); + }); + }); + describe('http auth schemes', () => { it('reports customized http auth schemes', async () => { const config = createSecurityConfig( diff --git a/x-pack/plugins/security/server/usage_collector/security_usage_collector.ts b/x-pack/plugins/security/server/usage_collector/security_usage_collector.ts index fc761fb13a50e..575fea2bf32c4 100644 --- a/x-pack/plugins/security/server/usage_collector/security_usage_collector.ts +++ b/x-pack/plugins/security/server/usage_collector/security_usage_collector.ts @@ -16,6 +16,7 @@ interface Usage { accessAgreementEnabled: boolean; authProviderCount: number; enabledAuthProviders: string[]; + fipsModeEnabled: boolean; httpAuthSchemes: string[]; sessionIdleTimeoutInMinutes: number; sessionLifespanInMinutes: number; @@ -93,6 +94,12 @@ export function registerSecurityUsageCollector({ usageCollection, config, licens }, }, }, + fipsModeEnabled: { + type: 'boolean', + _meta: { + description: 'Indicates if Kibana is being run in FIPS mode.', + }, + }, httpAuthSchemes: { type: 'array', items: { @@ -139,7 +146,8 @@ export function registerSecurityUsageCollector({ usageCollection, config, licens }, }, fetch: () => { - const { allowRbac, allowAccessAgreement, allowAuditLogging } = license.getFeatures(); + const { allowRbac, allowAccessAgreement, allowAuditLogging, allowFips } = + license.getFeatures(); if (!allowRbac) { return { auditLoggingEnabled: false, @@ -147,6 +155,7 @@ export function registerSecurityUsageCollector({ usageCollection, config, licens accessAgreementEnabled: false, authProviderCount: 0, enabledAuthProviders: [], + fipsModeEnabled: false, httpAuthSchemes: [], sessionIdleTimeoutInMinutes: 0, sessionLifespanInMinutes: 0, @@ -171,6 +180,8 @@ export function registerSecurityUsageCollector({ usageCollection, config, licens WELL_KNOWN_AUTH_SCHEMES.includes(scheme.toLowerCase()) ); + const fipsModeEnabled = allowFips && config.fipsMode.enabled; + const sessionExpirations = config.session.getExpirationTimeouts(undefined); // use `undefined` to get global expiration values const sessionIdleTimeoutInMinutes = sessionExpirations.idleTimeout?.asMinutes() ?? 0; const sessionLifespanInMinutes = sessionExpirations.lifespan?.asMinutes() ?? 0; @@ -202,6 +213,7 @@ export function registerSecurityUsageCollector({ usageCollection, config, licens accessAgreementEnabled, authProviderCount, enabledAuthProviders, + fipsModeEnabled, httpAuthSchemes, sessionIdleTimeoutInMinutes, sessionLifespanInMinutes, diff --git a/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/common.gen.ts b/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/common.gen.ts index 7e419dbe6453c..25c47e838d85c 100644 --- a/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/common.gen.ts +++ b/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/common.gen.ts @@ -39,6 +39,37 @@ export const EngineDescriptor = z.object({ error: z.object({}).optional(), }); +export type EngineComponentResource = z.infer; +export const EngineComponentResource = z.enum([ + 'entity_engine', + 'entity_definition', + 'index', + 'component_template', + 'index_template', + 'ingest_pipeline', + 'enrich_policy', + 'task', + 'transform', +]); +export type EngineComponentResourceEnum = typeof EngineComponentResource.enum; +export const EngineComponentResourceEnum = EngineComponentResource.enum; + +export type EngineComponentStatus = z.infer; +export const EngineComponentStatus = z.object({ + id: z.string(), + installed: z.boolean(), + resource: EngineComponentResource, + health: z.enum(['green', 'yellow', 'red', 'unknown']).optional(), + errors: z + .array( + z.object({ + title: z.string().optional(), + message: z.string().optional(), + }) + ) + .optional(), +}); + export type StoreStatus = z.infer; export const StoreStatus = z.enum(['not_installed', 'installing', 'running', 'stopped', 'error']); export type StoreStatusEnum = typeof StoreStatus.enum; diff --git a/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/common.schema.yaml b/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/common.schema.yaml index 9a42191a556ac..5adb6fe038dc9 100644 --- a/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/common.schema.yaml +++ b/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/common.schema.yaml @@ -42,6 +42,49 @@ components: - updating - error + EngineComponentStatus: + type: object + required: + - id + - installed + - resource + properties: + id: + type: string + installed: + type: boolean + resource: + $ref: '#/components/schemas/EngineComponentResource' + health: + type: string + enum: + - green + - yellow + - red + - unknown + errors: + type: array + items: + type: object + properties: + title: + type: string + message: + type: string + + EngineComponentResource: + type: string + enum: + - entity_engine + - entity_definition + - index + - component_template + - index_template + - ingest_pipeline + - enrich_policy + - task + - transform + StoreStatus: type: string enum: diff --git a/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/enablement.gen.ts b/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/enable.gen.ts similarity index 78% rename from x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/enablement.gen.ts rename to x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/enable.gen.ts index 9644a1a333d16..70a58bf02be68 100644 --- a/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/enablement.gen.ts +++ b/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/enable.gen.ts @@ -16,13 +16,7 @@ import { z } from '@kbn/zod'; -import { IndexPattern, EngineDescriptor, StoreStatus } from './common.gen'; - -export type GetEntityStoreStatusResponse = z.infer; -export const GetEntityStoreStatusResponse = z.object({ - status: StoreStatus.optional(), - engines: z.array(EngineDescriptor).optional(), -}); +import { IndexPattern, EngineDescriptor } from './common.gen'; export type InitEntityStoreRequestBody = z.infer; export const InitEntityStoreRequestBody = z.object({ diff --git a/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/enablement.schema.yaml b/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/enable.schema.yaml similarity index 65% rename from x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/enablement.schema.yaml rename to x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/enable.schema.yaml index 306e876dfc4a7..81eec22d9ade9 100644 --- a/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/enablement.schema.yaml +++ b/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/enable.schema.yaml @@ -41,24 +41,3 @@ paths: type: array items: $ref: './common.schema.yaml#/components/schemas/EngineDescriptor' - - /api/entity_store/status: - get: - x-labels: [ess, serverless] - x-codegen-enabled: true - operationId: GetEntityStoreStatus - summary: Get the status of the Entity Store - responses: - '200': - description: Successful response - content: - application/json: - schema: - type: object - properties: - status: - $ref: './common.schema.yaml#/components/schemas/StoreStatus' - engines: - type: array - items: - $ref: './common.schema.yaml#/components/schemas/EngineDescriptor' diff --git a/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/engine/index.ts b/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/engine/index.ts index b21308de36f18..32bc0a4efc07b 100644 --- a/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/engine/index.ts +++ b/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/engine/index.ts @@ -10,6 +10,5 @@ export * from './get.gen'; export * from './init.gen'; export * from './list.gen'; export * from './start.gen'; -export * from './stats.gen'; export * from './stop.gen'; export * from './apply_dataview_indices.gen'; diff --git a/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/engine/stats.gen.ts b/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/engine/stats.gen.ts deleted file mode 100644 index 8b2cb44947535..0000000000000 --- a/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/engine/stats.gen.ts +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -/* - * NOTICE: Do not edit this file manually. - * This file is automatically generated by the OpenAPI Generator, @kbn/openapi-generator. - * - * info: - * title: Get Entity Engine stats - * version: 2023-10-31 - */ - -import { z } from '@kbn/zod'; - -import { EntityType, IndexPattern, EngineStatus } from '../common.gen'; - -export type GetEntityEngineStatsRequestParams = z.infer; -export const GetEntityEngineStatsRequestParams = z.object({ - /** - * The entity type of the engine (either 'user' or 'host'). - */ - entityType: EntityType, -}); -export type GetEntityEngineStatsRequestParamsInput = z.input< - typeof GetEntityEngineStatsRequestParams ->; - -export type GetEntityEngineStatsResponse = z.infer; -export const GetEntityEngineStatsResponse = z.object({ - type: EntityType.optional(), - indexPattern: IndexPattern.optional(), - status: EngineStatus.optional(), - transforms: z.array(z.object({})).optional(), - indices: z.array(z.object({})).optional(), -}); diff --git a/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/engine/stats.schema.yaml b/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/engine/stats.schema.yaml deleted file mode 100644 index 25c010acc92ce..0000000000000 --- a/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/engine/stats.schema.yaml +++ /dev/null @@ -1,41 +0,0 @@ -openapi: 3.0.0 - -info: - title: Get Entity Engine stats - version: '2023-10-31' -paths: - /api/entity_store/engines/{entityType}/stats: - post: - x-labels: [ess, serverless] - x-codegen-enabled: true - operationId: GetEntityEngineStats - summary: Get Entity Engine stats - parameters: - - name: entityType - in: path - required: true - schema: - $ref: '../common.schema.yaml#/components/schemas/EntityType' - description: The entity type of the engine (either 'user' or 'host'). - responses: - '200': - description: Successful response - content: - application/json: - schema: - type: object - properties: - type: - $ref : '../common.schema.yaml#/components/schemas/EntityType' - indexPattern: - $ref : '../common.schema.yaml#/components/schemas/IndexPattern' - status: - $ref : '../common.schema.yaml#/components/schemas/EngineStatus' - transforms: - type: array - items: - type: object - indices: - type: array - items: - type: object diff --git a/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/status.gen.ts b/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/status.gen.ts new file mode 100644 index 0000000000000..76249a787a43b --- /dev/null +++ b/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/status.gen.ts @@ -0,0 +1,43 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +/* + * NOTICE: Do not edit this file manually. + * This file is automatically generated by the OpenAPI Generator, @kbn/openapi-generator. + * + * info: + * title: Enable Entity Store + * version: 2023-10-31 + */ + +import { z } from '@kbn/zod'; +import { BooleanFromString } from '@kbn/zod-helpers'; + +import { StoreStatus, EngineDescriptor, EngineComponentStatus } from './common.gen'; + +export type GetEntityStoreStatusRequestQuery = z.infer; +export const GetEntityStoreStatusRequestQuery = z.object({ + /** + * If true returns a detailed status of the engine including all it's components + */ + include_components: BooleanFromString.optional(), +}); +export type GetEntityStoreStatusRequestQueryInput = z.input< + typeof GetEntityStoreStatusRequestQuery +>; + +export type GetEntityStoreStatusResponse = z.infer; +export const GetEntityStoreStatusResponse = z.object({ + status: StoreStatus, + engines: z.array( + EngineDescriptor.merge( + z.object({ + components: z.array(EngineComponentStatus).optional(), + }) + ) + ), +}); diff --git a/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/status.schema.yaml b/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/status.schema.yaml new file mode 100644 index 0000000000000..a1be66282328e --- /dev/null +++ b/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/status.schema.yaml @@ -0,0 +1,44 @@ +openapi: 3.0.0 + +info: + title: Enable Entity Store + version: '2023-10-31' +paths: + /api/entity_store/status: + get: + x-labels: [ess, serverless] + x-codegen-enabled: true + operationId: GetEntityStoreStatus + summary: Get the status of the Entity Store + + parameters: + - name: include_components + in: query + schema: + type: boolean + description: If true returns a detailed status of the engine including all it's components + + responses: + '200': + description: Successful response + content: + application/json: + schema: + type: object + required: + - status + - engines + properties: + status: + $ref: './common.schema.yaml#/components/schemas/StoreStatus' + engines: + type: array + items: + allOf: + - $ref: './common.schema.yaml#/components/schemas/EngineDescriptor' + - type: object + properties: + components: + type: array + items: + $ref: './common.schema.yaml#/components/schemas/EngineComponentStatus' diff --git a/x-pack/plugins/security_solution/common/api/quickstart_client.gen.ts b/x-pack/plugins/security_solution/common/api/quickstart_client.gen.ts index 5a1cf49baecd1..d86a04f343a89 100644 --- a/x-pack/plugins/security_solution/common/api/quickstart_client.gen.ts +++ b/x-pack/plugins/security_solution/common/api/quickstart_client.gen.ts @@ -232,10 +232,9 @@ import type { UploadAssetCriticalityRecordsResponse, } from './entity_analytics/asset_criticality/upload_asset_criticality_csv.gen'; import type { - GetEntityStoreStatusResponse, InitEntityStoreRequestBodyInput, InitEntityStoreResponse, -} from './entity_analytics/entity_store/enablement.gen'; +} from './entity_analytics/entity_store/enable.gen'; import type { ApplyEntityEngineDataviewIndicesResponse } from './entity_analytics/entity_store/engine/apply_dataview_indices.gen'; import type { DeleteEntityEngineRequestQueryInput, @@ -257,10 +256,6 @@ import type { StartEntityEngineRequestParamsInput, StartEntityEngineResponse, } from './entity_analytics/entity_store/engine/start.gen'; -import type { - GetEntityEngineStatsRequestParamsInput, - GetEntityEngineStatsResponse, -} from './entity_analytics/entity_store/engine/stats.gen'; import type { StopEntityEngineRequestParamsInput, StopEntityEngineResponse, @@ -269,6 +264,10 @@ import type { ListEntitiesRequestQueryInput, ListEntitiesResponse, } from './entity_analytics/entity_store/entities/list_entities.gen'; +import type { + GetEntityStoreStatusRequestQueryInput, + GetEntityStoreStatusResponse, +} from './entity_analytics/entity_store/status.gen'; import type { CleanUpRiskEngineResponse } from './entity_analytics/risk_engine/engine_cleanup_route.gen'; import type { DisableRiskEngineResponse } from './entity_analytics/risk_engine/engine_disable_route.gen'; import type { EnableRiskEngineResponse } from './entity_analytics/risk_engine/engine_enable_route.gen'; @@ -360,6 +359,11 @@ import type { GetRuleMigrationResourcesResponse, GetRuleMigrationStatsRequestParamsInput, GetRuleMigrationStatsResponse, + InstallMigrationRulesRequestParamsInput, + InstallMigrationRulesRequestBodyInput, + InstallMigrationRulesResponse, + InstallTranslatedMigrationRulesRequestParamsInput, + InstallTranslatedMigrationRulesResponse, StartRuleMigrationRequestParamsInput, StartRuleMigrationRequestBodyInput, StartRuleMigrationResponse, @@ -1290,19 +1294,7 @@ finalize it. }) .catch(catchAxiosErrorFormatAndThrow); } - async getEntityEngineStats(props: GetEntityEngineStatsProps) { - this.log.info(`${new Date().toISOString()} Calling API GetEntityEngineStats`); - return this.kbnClient - .request({ - path: replaceParams('/api/entity_store/engines/{entityType}/stats', props.params), - headers: { - [ELASTIC_HTTP_VERSION_HEADER]: '2023-10-31', - }, - method: 'POST', - }) - .catch(catchAxiosErrorFormatAndThrow); - } - async getEntityStoreStatus() { + async getEntityStoreStatus(props: GetEntityStoreStatusProps) { this.log.info(`${new Date().toISOString()} Calling API GetEntityStoreStatus`); return this.kbnClient .request({ @@ -1311,6 +1303,8 @@ finalize it. [ELASTIC_HTTP_VERSION_HEADER]: '2023-10-31', }, method: 'GET', + + query: props.query, }) .catch(catchAxiosErrorFormatAndThrow); } @@ -1570,6 +1564,22 @@ finalize it. }) .catch(catchAxiosErrorFormatAndThrow); } + /** + * Installs migration rules + */ + async installMigrationRules(props: InstallMigrationRulesProps) { + this.log.info(`${new Date().toISOString()} Calling API InstallMigrationRules`); + return this.kbnClient + .request({ + path: replaceParams('/internal/siem_migrations/rules/{migration_id}/install', props.params), + headers: { + [ELASTIC_HTTP_VERSION_HEADER]: '1', + }, + method: 'POST', + body: props.body, + }) + .catch(catchAxiosErrorFormatAndThrow); + } /** * Install and update all Elastic prebuilt detection rules and Timelines. */ @@ -1601,6 +1611,24 @@ finalize it. }) .catch(catchAxiosErrorFormatAndThrow); } + /** + * Installs all translated migration rules + */ + async installTranslatedMigrationRules(props: InstallTranslatedMigrationRulesProps) { + this.log.info(`${new Date().toISOString()} Calling API InstallTranslatedMigrationRules`); + return this.kbnClient + .request({ + path: replaceParams( + '/internal/siem_migrations/rules/{migration_id}/install_translated', + props.params + ), + headers: { + [ELASTIC_HTTP_VERSION_HEADER]: '1', + }, + method: 'POST', + }) + .catch(catchAxiosErrorFormatAndThrow); + } async internalUploadAssetCriticalityRecords(props: InternalUploadAssetCriticalityRecordsProps) { this.log.info(`${new Date().toISOString()} Calling API InternalUploadAssetCriticalityRecords`); return this.kbnClient @@ -2285,8 +2313,8 @@ export interface GetEndpointSuggestionsProps { export interface GetEntityEngineProps { params: GetEntityEngineRequestParamsInput; } -export interface GetEntityEngineStatsProps { - params: GetEntityEngineStatsRequestParamsInput; +export interface GetEntityStoreStatusProps { + query: GetEntityStoreStatusRequestQueryInput; } export interface GetNotesProps { query: GetNotesRequestQueryInput; @@ -2335,9 +2363,16 @@ export interface InitEntityEngineProps { export interface InitEntityStoreProps { body: InitEntityStoreRequestBodyInput; } +export interface InstallMigrationRulesProps { + params: InstallMigrationRulesRequestParamsInput; + body: InstallMigrationRulesRequestBodyInput; +} export interface InstallPrepackedTimelinesProps { body: InstallPrepackedTimelinesRequestBodyInput; } +export interface InstallTranslatedMigrationRulesProps { + params: InstallTranslatedMigrationRulesRequestParamsInput; +} export interface InternalUploadAssetCriticalityRecordsProps { attachment: FormData; } diff --git a/x-pack/plugins/security_solution/common/endpoint/types/workflow_insights.ts b/x-pack/plugins/security_solution/common/endpoint/types/workflow_insights.ts new file mode 100644 index 0000000000000..11cbc1bfd7cd8 --- /dev/null +++ b/x-pack/plugins/security_solution/common/endpoint/types/workflow_insights.ts @@ -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 type { Moment } from 'moment'; + +import type { DefendInsightType } from '@kbn/elastic-assistant-common'; +import type { ExceptionListItemSchema } from '@kbn/securitysolution-io-ts-list-types'; + +export enum Category { + Endpoint = 'endpoint', +} + +export enum SourceType { + LlmConnector = 'llm-connector', +} + +export enum TargetType { + Endpoint = 'endpoint', +} + +export enum ActionType { + Refreshed = 'refreshed', // new or refreshed + Remediated = 'remediated', + Suppressed = 'suppressed', // temporarily supressed, can be refreshed + Dismissed = 'dismissed', // "permanently" dismissed, cannot be normally refreshed +} + +export type ExceptionListRemediationType = Pick< + ExceptionListItemSchema, + 'list_id' | 'name' | 'description' | 'entries' | 'tags' | 'os_types' +>; + +export interface SecurityWorkflowInsight { + id?: string; + '@timestamp': Moment; + message: string; + category: Category; + type: DefendInsightType; + source: { + type: SourceType; + id: string; + data_range_start: Moment; + data_range_end: Moment; + }; + target: { + type: TargetType; + ids: string[]; + }; + action: { + type: ActionType; + timestamp: Moment; + }; + value: string; + remediation: { + exception_list_items?: ExceptionListRemediationType[]; + }; + metadata: { + notes?: Record; + message_variables?: string[]; + }; +} + +export interface SearchParams { + size?: number; + from?: number; + ids?: string[]; + categories?: Category[]; + types?: DefendInsightType[]; + sourceTypes?: SourceType[]; + sourceIds?: string[]; + targetTypes?: TargetType[]; + targetIds?: string[]; + actionTypes: ActionType[]; +} diff --git a/x-pack/plugins/security_solution/common/siem_migrations/constants.ts b/x-pack/plugins/security_solution/common/siem_migrations/constants.ts index 8a2d6cf3775c9..565091e39a8db 100644 --- a/x-pack/plugins/security_solution/common/siem_migrations/constants.ts +++ b/x-pack/plugins/security_solution/common/siem_migrations/constants.ts @@ -5,6 +5,8 @@ * 2.0. */ +import type { Severity } from '@kbn/securitysolution-io-ts-alerting-types'; + export const SIEM_MIGRATIONS_PATH = '/internal/siem_migrations' as const; export const SIEM_RULE_MIGRATIONS_PATH = `${SIEM_MIGRATIONS_PATH}/rules` as const; @@ -14,9 +16,19 @@ export const SIEM_RULE_MIGRATION_START_PATH = `${SIEM_RULE_MIGRATION_PATH}/start export const SIEM_RULE_MIGRATION_RETRY_PATH = `${SIEM_RULE_MIGRATION_PATH}/retry` as const; export const SIEM_RULE_MIGRATION_STATS_PATH = `${SIEM_RULE_MIGRATION_PATH}/stats` as const; export const SIEM_RULE_MIGRATION_STOP_PATH = `${SIEM_RULE_MIGRATION_PATH}/stop` as const; +export const SIEM_RULE_MIGRATION_INSTALL_PATH = `${SIEM_RULE_MIGRATION_PATH}/install` as const; +export const SIEM_RULE_MIGRATION_INSTALL_TRANSLATED_PATH = + `${SIEM_RULE_MIGRATION_PATH}/install_translated` as const; export const SIEM_RULE_MIGRATION_RESOURCES_PATH = `${SIEM_RULE_MIGRATION_PATH}/resources` as const; +export enum SiemMigrationTaskStatus { + READY = 'ready', + RUNNING = 'running', + STOPPED = 'stopped', + FINISHED = 'finished', +} + export enum SiemMigrationStatus { PENDING = 'pending', PROCESSING = 'processing', @@ -29,3 +41,6 @@ export enum SiemMigrationRuleTranslationResult { PARTIAL = 'partial', UNTRANSLATABLE = 'untranslatable', } + +export const DEFAULT_TRANSLATION_RISK_SCORE = 21; +export const DEFAULT_TRANSLATION_SEVERITY: Severity = 'low'; diff --git a/x-pack/plugins/security_solution/common/siem_migrations/model/api/rules/rule_migration.gen.ts b/x-pack/plugins/security_solution/common/siem_migrations/model/api/rules/rule_migration.gen.ts index 36728e0e928a0..77a0fc94408f9 100644 --- a/x-pack/plugins/security_solution/common/siem_migrations/model/api/rules/rule_migration.gen.ts +++ b/x-pack/plugins/security_solution/common/siem_migrations/model/api/rules/rule_migration.gen.ts @@ -88,6 +88,48 @@ export type GetRuleMigrationStatsRequestParamsInput = z.input< export type GetRuleMigrationStatsResponse = z.infer; export const GetRuleMigrationStatsResponse = RuleMigrationTaskStats; +export type InstallMigrationRulesRequestParams = z.infer; +export const InstallMigrationRulesRequestParams = z.object({ + migration_id: NonEmptyString, +}); +export type InstallMigrationRulesRequestParamsInput = z.input< + typeof InstallMigrationRulesRequestParams +>; + +export type InstallMigrationRulesRequestBody = z.infer; +export const InstallMigrationRulesRequestBody = z.array(NonEmptyString); +export type InstallMigrationRulesRequestBodyInput = z.input< + typeof InstallMigrationRulesRequestBody +>; + +export type InstallMigrationRulesResponse = z.infer; +export const InstallMigrationRulesResponse = z.object({ + /** + * Indicates rules migrations have been installed. + */ + installed: z.boolean(), +}); + +export type InstallTranslatedMigrationRulesRequestParams = z.infer< + typeof InstallTranslatedMigrationRulesRequestParams +>; +export const InstallTranslatedMigrationRulesRequestParams = z.object({ + migration_id: NonEmptyString, +}); +export type InstallTranslatedMigrationRulesRequestParamsInput = z.input< + typeof InstallTranslatedMigrationRulesRequestParams +>; + +export type InstallTranslatedMigrationRulesResponse = z.infer< + typeof InstallTranslatedMigrationRulesResponse +>; +export const InstallTranslatedMigrationRulesResponse = z.object({ + /** + * Indicates rules migrations have been installed. + */ + installed: z.boolean(), +}); + export type StartRuleMigrationRequestParams = z.infer; export const StartRuleMigrationRequestParams = z.object({ migration_id: NonEmptyString, @@ -167,16 +209,7 @@ export type UpsertRuleMigrationResourcesRequestParamsInput = z.input< export type UpsertRuleMigrationResourcesRequestBody = z.infer< typeof UpsertRuleMigrationResourcesRequestBody >; -export const UpsertRuleMigrationResourcesRequestBody = z.array( - RuleMigrationResourceData.merge( - z.object({ - /** - * The rule resource migration id - */ - id: NonEmptyString, - }) - ) -); +export const UpsertRuleMigrationResourcesRequestBody = z.array(RuleMigrationResourceData); export type UpsertRuleMigrationResourcesRequestBodyInput = z.input< typeof UpsertRuleMigrationResourcesRequestBody >; diff --git a/x-pack/plugins/security_solution/common/siem_migrations/model/api/rules/rule_migration.schema.yaml b/x-pack/plugins/security_solution/common/siem_migrations/model/api/rules/rule_migration.schema.yaml index fdb589e7b45cd..f57a809bb204e 100644 --- a/x-pack/plugins/security_solution/common/siem_migrations/model/api/rules/rule_migration.schema.yaml +++ b/x-pack/plugins/security_solution/common/siem_migrations/model/api/rules/rule_migration.schema.yaml @@ -10,6 +10,7 @@ paths: summary: Creates a new rule migration operationId: CreateRuleMigration x-codegen-enabled: true + x-internal: true description: Creates a new SIEM rules migration using the original vendor rules provided tags: - SIEM Rule Migrations @@ -39,6 +40,7 @@ paths: summary: Updates rules migrations operationId: UpdateRuleMigration x-codegen-enabled: true + x-internal: true description: Updates rules migrations attributes tags: - SIEM Rule Migrations @@ -79,11 +81,79 @@ paths: type: boolean description: Indicates rules migrations have been updated. + /internal/siem_migrations/rules/{migration_id}/install: + post: + summary: Installs translated migration rules + operationId: InstallMigrationRules + x-codegen-enabled: true + description: Installs migration rules + tags: + - SIEM Rule Migrations + parameters: + - name: migration_id + in: path + required: true + schema: + description: The migration id to isnstall rules for + $ref: '../../common.schema.yaml#/components/schemas/NonEmptyString' + requestBody: + required: true + content: + application/json: + schema: + type: array + items: + description: The rule migration id + $ref: '../../common.schema.yaml#/components/schemas/NonEmptyString' + responses: + 200: + description: Indicates rules migrations have been installed correctly. + content: + application/json: + schema: + type: object + required: + - installed + properties: + installed: + type: boolean + description: Indicates rules migrations have been installed. + + /internal/siem_migrations/rules/{migration_id}/install_translated: + post: + summary: Installs all translated migration rules + operationId: InstallTranslatedMigrationRules + x-codegen-enabled: true + description: Installs all translated migration rules + tags: + - SIEM Rule Migrations + parameters: + - name: migration_id + in: path + required: true + schema: + description: The migration id to install translated rules for + $ref: '../../common.schema.yaml#/components/schemas/NonEmptyString' + responses: + 200: + description: Indicates rules migrations have been installed correctly. + content: + application/json: + schema: + type: object + required: + - installed + properties: + installed: + type: boolean + description: Indicates rules migrations have been installed. + /internal/siem_migrations/rules/stats: get: summary: Retrieves the stats for all rule migrations operationId: GetAllStatsRuleMigration x-codegen-enabled: true + x-internal: true description: Retrieves the rule migrations stats for all migrations stored in the system tags: - SIEM Rule Migrations @@ -104,6 +174,7 @@ paths: summary: Retrieves all the rules of a migration operationId: GetRuleMigration x-codegen-enabled: true + x-internal: true description: Retrieves the rule documents stored in the system given the rule migration id tags: - SIEM Rule Migrations @@ -131,6 +202,7 @@ paths: summary: Starts a rule migration operationId: StartRuleMigration x-codegen-enabled: true + x-internal: true description: Starts a SIEM rules migration using the migration id provided tags: - SIEM Rule Migrations @@ -175,6 +247,7 @@ paths: summary: Gets a rule migration task stats operationId: GetRuleMigrationStats x-codegen-enabled: true + x-internal: true description: Retrieves the stats of a SIEM rules migration using the migration id provided tags: - SIEM Rule Migrations @@ -200,6 +273,7 @@ paths: summary: Stops an existing rule migration operationId: StopRuleMigration x-codegen-enabled: true + x-internal: true description: Stops a running SIEM rules migration using the migration id provided tags: - SIEM Rule Migrations @@ -233,6 +307,7 @@ paths: summary: Creates or updates rule migration resources for a migration operationId: UpsertRuleMigrationResources x-codegen-enabled: true + x-internal: true description: Creates or updates resources for an existing SIEM rules migration tags: - SIEM Rule Migrations @@ -251,15 +326,7 @@ paths: schema: type: array items: - allOf: - - $ref: '../../rule_migration.schema.yaml#/components/schemas/RuleMigrationResourceData' - - type: object - required: - - id - properties: - id: - description: The rule resource migration id - $ref: '../../common.schema.yaml#/components/schemas/NonEmptyString' + $ref: '../../rule_migration.schema.yaml#/components/schemas/RuleMigrationResourceData' responses: 200: description: Indicates migration resources have been created or updated correctly. @@ -278,6 +345,7 @@ paths: summary: Gets rule migration resources for a migration operationId: GetRuleMigrationResources x-codegen-enabled: true + x-internal: true description: Retrieves resources for an existing SIEM rules migration tags: - SIEM Rule Migrations diff --git a/x-pack/plugins/security_solution/common/siem_migrations/model/rule_migration.gen.ts b/x-pack/plugins/security_solution/common/siem_migrations/model/rule_migration.gen.ts index 2260b83190e22..82e3c5549fd86 100644 --- a/x-pack/plugins/security_solution/common/siem_migrations/model/rule_migration.gen.ts +++ b/x-pack/plugins/security_solution/common/siem_migrations/model/rule_migration.gen.ts @@ -113,7 +113,7 @@ export type RuleMigrationTranslationResultEnum = typeof RuleMigrationTranslation export const RuleMigrationTranslationResultEnum = RuleMigrationTranslationResult.enum; /** - * The status of the rule migration process. + * The status of each rule migration. */ export type RuleMigrationStatus = z.infer; export const RuleMigrationStatus = z.enum(['pending', 'processing', 'completed', 'failed']); @@ -186,6 +186,14 @@ export const RuleMigration = z }) .merge(RuleMigrationData); +/** + * The status of the migration task. + */ +export type RuleMigrationTaskStatus = z.infer; +export const RuleMigrationTaskStatus = z.enum(['ready', 'running', 'stopped', 'finished']); +export type RuleMigrationTaskStatusEnum = typeof RuleMigrationTaskStatus.enum; +export const RuleMigrationTaskStatusEnum = RuleMigrationTaskStatus.enum; + /** * The rule migration task stats object. */ @@ -198,7 +206,7 @@ export const RuleMigrationTaskStats = z.object({ /** * Indicates if the migration task status. */ - status: z.enum(['ready', 'running', 'stopped', 'finished']), + status: RuleMigrationTaskStatus, /** * The rules migration stats. */ diff --git a/x-pack/plugins/security_solution/common/siem_migrations/model/rule_migration.schema.yaml b/x-pack/plugins/security_solution/common/siem_migrations/model/rule_migration.schema.yaml index 17c70665b9ad3..82892b4fa0722 100644 --- a/x-pack/plugins/security_solution/common/siem_migrations/model/rule_migration.schema.yaml +++ b/x-pack/plugins/security_solution/common/siem_migrations/model/rule_migration.schema.yaml @@ -155,13 +155,8 @@ components: description: The migration id $ref: './common.schema.yaml#/components/schemas/NonEmptyString' status: - type: string description: Indicates if the migration task status. - enum: - - ready - - running - - stopped - - finished + $ref: '#/components/schemas/RuleMigrationTaskStatus' rules: type: object description: The rules migration stats. @@ -194,6 +189,15 @@ components: type: string description: The moment of the last update. + RuleMigrationTaskStatus: + type: string + description: The status of the migration task. + enum: # should match SiemMigrationTaskStatus enum at ../constants.ts + - ready + - running + - stopped + - finished + RuleMigrationTranslationResult: type: string description: The rule translation result. @@ -204,7 +208,7 @@ components: RuleMigrationStatus: type: string - description: The status of the rule migration process. + description: The status of each rule migration. enum: # should match SiemMigrationsStatus enum at ../constants.ts - pending - processing diff --git a/x-pack/plugins/security_solution/common/types/timeline/cells/index.ts b/x-pack/plugins/security_solution/common/types/timeline/cells/index.ts index 8435e6ec89845..91c426c24dc78 100644 --- a/x-pack/plugins/security_solution/common/types/timeline/cells/index.ts +++ b/x-pack/plugins/security_solution/common/types/timeline/cells/index.ts @@ -13,6 +13,10 @@ import type { BrowserFields, TimelineNonEcsData } from '../../../search_strategy /** The following props are provided to the function called by `renderCellValue` */ export type CellValueElementProps = EuiDataGridCellValueElementProps & { + /** + * makes sure that field is not rendered as a plain text + * but according to the renderer. + */ asPlainText?: boolean; browserFields?: BrowserFields; data: TimelineNonEcsData[]; diff --git a/x-pack/plugins/security_solution/common/types/timeline/store.ts b/x-pack/plugins/security_solution/common/types/timeline/store.ts index c65705e0c9a74..834949d2ed591 100644 --- a/x-pack/plugins/security_solution/common/types/timeline/store.ts +++ b/x-pack/plugins/security_solution/common/types/timeline/store.ts @@ -73,7 +73,7 @@ export type OnColumnRemoved = (columnId: ColumnId) => void; export type OnColumnResized = ({ columnId, delta }: { columnId: ColumnId; delta: number }) => void; /** Invoked when a user clicks to load more item */ -export type OnChangePage = (nextPage: number) => void; +export type OnFetchMoreRecords = (nextPage: number) => void; /** Invoked when a user checks/un-checks a row */ export type OnRowSelected = ({ diff --git a/x-pack/plugins/security_solution/docs/openapi/ess/security_solution_entity_analytics_api_2023_10_31.bundled.schema.yaml b/x-pack/plugins/security_solution/docs/openapi/ess/security_solution_entity_analytics_api_2023_10_31.bundled.schema.yaml index fa79b170f3513..b1b85b8222786 100644 --- a/x-pack/plugins/security_solution/docs/openapi/ess/security_solution_entity_analytics_api_2023_10_31.bundled.schema.yaml +++ b/x-pack/plugins/security_solution/docs/openapi/ess/security_solution_entity_analytics_api_2023_10_31.bundled.schema.yaml @@ -430,41 +430,6 @@ paths: summary: Start an Entity Engine tags: - Security Entity Analytics API - /api/entity_store/engines/{entityType}/stats: - post: - operationId: GetEntityEngineStats - parameters: - - description: The entity type of the engine (either 'user' or 'host'). - in: path - name: entityType - required: true - schema: - $ref: '#/components/schemas/EntityType' - responses: - '200': - content: - application/json: - schema: - type: object - properties: - indexPattern: - $ref: '#/components/schemas/IndexPattern' - indices: - items: - type: object - type: array - status: - $ref: '#/components/schemas/EngineStatus' - transforms: - items: - type: object - type: array - type: - $ref: '#/components/schemas/EntityType' - description: Successful response - summary: Get Entity Engine stats - tags: - - Security Entity Analytics API /api/entity_store/engines/{entityType}/stop: post: operationId: StopEntityEngine @@ -615,6 +580,14 @@ paths: /api/entity_store/status: get: operationId: GetEntityStoreStatus + parameters: + - description: >- + If true returns a detailed status of the engine including all it's + components + in: query + name: include_components + schema: + type: boolean responses: '200': content: @@ -624,10 +597,20 @@ paths: properties: engines: items: - $ref: '#/components/schemas/EngineDescriptor' + allOf: + - $ref: '#/components/schemas/EngineDescriptor' + - type: object + properties: + components: + items: + $ref: '#/components/schemas/EngineComponentStatus' + type: array type: array status: $ref: '#/components/schemas/StoreStatus' + required: + - status + - engines description: Successful response summary: Get the status of the Entity Store tags: @@ -824,6 +807,47 @@ components: $ref: '#/components/schemas/AssetCriticalityLevel' required: - criticality_level + EngineComponentResource: + enum: + - entity_engine + - entity_definition + - index + - component_template + - index_template + - ingest_pipeline + - enrich_policy + - task + - transform + type: string + EngineComponentStatus: + type: object + properties: + errors: + items: + type: object + properties: + message: + type: string + title: + type: string + type: array + health: + enum: + - green + - yellow + - red + - unknown + type: string + id: + type: string + installed: + type: boolean + resource: + $ref: '#/components/schemas/EngineComponentResource' + required: + - id + - installed + - resource EngineDataviewUpdateResult: type: object properties: diff --git a/x-pack/plugins/security_solution/docs/openapi/serverless/security_solution_entity_analytics_api_2023_10_31.bundled.schema.yaml b/x-pack/plugins/security_solution/docs/openapi/serverless/security_solution_entity_analytics_api_2023_10_31.bundled.schema.yaml index 9c2b3d62b1650..4a3b3495467e9 100644 --- a/x-pack/plugins/security_solution/docs/openapi/serverless/security_solution_entity_analytics_api_2023_10_31.bundled.schema.yaml +++ b/x-pack/plugins/security_solution/docs/openapi/serverless/security_solution_entity_analytics_api_2023_10_31.bundled.schema.yaml @@ -430,41 +430,6 @@ paths: summary: Start an Entity Engine tags: - Security Entity Analytics API - /api/entity_store/engines/{entityType}/stats: - post: - operationId: GetEntityEngineStats - parameters: - - description: The entity type of the engine (either 'user' or 'host'). - in: path - name: entityType - required: true - schema: - $ref: '#/components/schemas/EntityType' - responses: - '200': - content: - application/json: - schema: - type: object - properties: - indexPattern: - $ref: '#/components/schemas/IndexPattern' - indices: - items: - type: object - type: array - status: - $ref: '#/components/schemas/EngineStatus' - transforms: - items: - type: object - type: array - type: - $ref: '#/components/schemas/EntityType' - description: Successful response - summary: Get Entity Engine stats - tags: - - Security Entity Analytics API /api/entity_store/engines/{entityType}/stop: post: operationId: StopEntityEngine @@ -615,6 +580,14 @@ paths: /api/entity_store/status: get: operationId: GetEntityStoreStatus + parameters: + - description: >- + If true returns a detailed status of the engine including all it's + components + in: query + name: include_components + schema: + type: boolean responses: '200': content: @@ -624,10 +597,20 @@ paths: properties: engines: items: - $ref: '#/components/schemas/EngineDescriptor' + allOf: + - $ref: '#/components/schemas/EngineDescriptor' + - type: object + properties: + components: + items: + $ref: '#/components/schemas/EngineComponentStatus' + type: array type: array status: $ref: '#/components/schemas/StoreStatus' + required: + - status + - engines description: Successful response summary: Get the status of the Entity Store tags: @@ -824,6 +807,47 @@ components: $ref: '#/components/schemas/AssetCriticalityLevel' required: - criticality_level + EngineComponentResource: + enum: + - entity_engine + - entity_definition + - index + - component_template + - index_template + - ingest_pipeline + - enrich_policy + - task + - transform + type: string + EngineComponentStatus: + type: object + properties: + errors: + items: + type: object + properties: + message: + type: string + title: + type: string + type: array + health: + enum: + - green + - yellow + - red + - unknown + type: string + id: + type: string + installed: + type: boolean + resource: + $ref: '#/components/schemas/EngineComponentResource' + required: + - id + - installed + - resource EngineDataviewUpdateResult: type: object properties: diff --git a/x-pack/plugins/security_solution/docs/siem_migration/README.md b/x-pack/plugins/security_solution/docs/siem_migration/README.md new file mode 100644 index 0000000000000..84a2d17277ec4 --- /dev/null +++ b/x-pack/plugins/security_solution/docs/siem_migration/README.md @@ -0,0 +1,17 @@ +# SIEM Migration Library + +## Migration Process + +The SIEM migration library defines a set of UI components and services that are used to migrate third party SIEM resources like detection rules and translate them into resources that can be used in the Elastic Security app. + +## Graphs: + +The below images are generated by running the following command from the security_solution directory: + +```bash +yarn siem-migrations:graph:draw +``` + +Main agent graph: + +![Agent Graph](./img/agent_graph.png) \ No newline at end of file diff --git a/x-pack/plugins/security_solution/docs/siem_migration/img/agent_graph.png b/x-pack/plugins/security_solution/docs/siem_migration/img/agent_graph.png new file mode 100644 index 0000000000000..ecccb602e2016 Binary files /dev/null and b/x-pack/plugins/security_solution/docs/siem_migration/img/agent_graph.png differ diff --git a/x-pack/plugins/security_solution/kibana.jsonc b/x-pack/plugins/security_solution/kibana.jsonc index 0e713bc095888..f672378c88df8 100644 --- a/x-pack/plugins/security_solution/kibana.jsonc +++ b/x-pack/plugins/security_solution/kibana.jsonc @@ -25,7 +25,6 @@ "dashboard", "data", "dataViews", - "discover", "ecsDataQualityDashboard", "elasticAssistant", "embeddable", @@ -59,7 +58,8 @@ "unifiedDocViewer", "charts", "entityManager", - "inference" + "inference", + "discoverShared" ], "optionalPlugins": [ "encryptedSavedObjects", diff --git a/x-pack/plugins/security_solution/package.json b/x-pack/plugins/security_solution/package.json index 62a406960ceeb..fd1be833c5d6b 100644 --- a/x-pack/plugins/security_solution/package.json +++ b/x-pack/plugins/security_solution/package.json @@ -27,6 +27,7 @@ "test:generate:serverless-dev": "NODE_TLS_REJECT_UNAUTHORIZED=0 node --no-warnings scripts/endpoint/resolver_generator --node https://elastic_serverless:changeme@127.0.0.1:9200 --kibana http://elastic_serverless:changeme@127.0.0.1:5601", "mappings:generate": "node scripts/mappings/mappings_generator", "mappings:load": "node scripts/mappings/mappings_loader", + "siem-migrations:graph:draw": "node scripts/siem_migration/draw_graphs", "junit:transform": "node scripts/junit_transformer --pathPattern '../../../target/kibana-security-solution/cypress/results/*.xml' --rootDirectory ../../../ --reportName 'Security Solution Cypress' --writeInPlace", "openapi:generate": "node scripts/openapi/generate", "openapi:generate:debug": "node --inspect-brk scripts/openapi/generate", @@ -35,4 +36,4 @@ "openapi:bundle:entity-analytics": "node scripts/openapi/bundle_entity_analytics", "openapi:bundle:endpoint-management": "node scripts/openapi/bundle_endpoint_management" } -} +} \ No newline at end of file diff --git a/x-pack/plugins/security_solution/public/app/actions/add_to_timeline/discover/add_to_timeline.ts b/x-pack/plugins/security_solution/public/app/actions/add_to_timeline/discover/add_to_timeline.ts index 429d1e1f9db2a..27b309b2acee4 100644 --- a/x-pack/plugins/security_solution/public/app/actions/add_to_timeline/discover/add_to_timeline.ts +++ b/x-pack/plugins/security_solution/public/app/actions/add_to_timeline/discover/add_to_timeline.ts @@ -6,8 +6,8 @@ */ import type { CellAction, CellActionFactory } from '@kbn/cell-actions'; +import { isInSecurityApp } from '../../../../common/hooks/is_in_security_app'; import type { SecurityAppStore } from '../../../../common/store'; -import { isInSecurityApp } from '../../utils'; import type { StartServices } from '../../../../types'; import { createAddToTimelineCellActionFactory } from '../cell_action/add_to_timeline'; diff --git a/x-pack/plugins/security_solution/public/app/actions/add_to_timeline/lens/add_to_timeline.ts b/x-pack/plugins/security_solution/public/app/actions/add_to_timeline/lens/add_to_timeline.ts index 3ccbd30efd614..8792d2a6004f5 100644 --- a/x-pack/plugins/security_solution/public/app/actions/add_to_timeline/lens/add_to_timeline.ts +++ b/x-pack/plugins/security_solution/public/app/actions/add_to_timeline/lens/add_to_timeline.ts @@ -10,12 +10,13 @@ import { isErrorEmbeddable } from '@kbn/embeddable-plugin/public'; import { createAction } from '@kbn/ui-actions-plugin/public'; import { apiPublishesUnifiedSearch } from '@kbn/presentation-publishing'; import { isLensApi } from '@kbn/lens-plugin/public'; +import { isInSecurityApp } from '../../../../common/hooks/is_in_security_app'; import { KibanaServices } from '../../../../common/lib/kibana'; import type { SecurityAppStore } from '../../../../common/store/types'; import { addProvider } from '../../../../timelines/store/actions'; import type { DataProvider } from '../../../../../common/types'; import { EXISTS_OPERATOR, TimelineId } from '../../../../../common/types'; -import { fieldHasCellActions, isInSecurityApp } from '../../utils'; +import { fieldHasCellActions } from '../../utils'; import { ADD_TO_TIMELINE, ADD_TO_TIMELINE_FAILED_TEXT, diff --git a/x-pack/plugins/security_solution/public/app/actions/copy_to_clipboard/discover/copy_to_clipboard.ts b/x-pack/plugins/security_solution/public/app/actions/copy_to_clipboard/discover/copy_to_clipboard.ts index 7a2c39717b342..ba92d46e6eb81 100644 --- a/x-pack/plugins/security_solution/public/app/actions/copy_to_clipboard/discover/copy_to_clipboard.ts +++ b/x-pack/plugins/security_solution/public/app/actions/copy_to_clipboard/discover/copy_to_clipboard.ts @@ -6,7 +6,7 @@ */ import type { CellAction, CellActionFactory } from '@kbn/cell-actions'; -import { isInSecurityApp } from '../../utils'; +import { isInSecurityApp } from '../../../../common/hooks/is_in_security_app'; import type { StartServices } from '../../../../types'; import { createCopyToClipboardCellActionFactory } from '../cell_action/copy_to_clipboard'; diff --git a/x-pack/plugins/security_solution/public/app/actions/copy_to_clipboard/lens/copy_to_clipboard.ts b/x-pack/plugins/security_solution/public/app/actions/copy_to_clipboard/lens/copy_to_clipboard.ts index 8546f0c3260cc..f4c61c1e7bf7b 100644 --- a/x-pack/plugins/security_solution/public/app/actions/copy_to_clipboard/lens/copy_to_clipboard.ts +++ b/x-pack/plugins/security_solution/public/app/actions/copy_to_clipboard/lens/copy_to_clipboard.ts @@ -9,8 +9,9 @@ import type { CellValueContext, IEmbeddable } from '@kbn/embeddable-plugin/publi import { isErrorEmbeddable } from '@kbn/embeddable-plugin/public'; import { createAction } from '@kbn/ui-actions-plugin/public'; import copy from 'copy-to-clipboard'; +import { isInSecurityApp } from '../../../../common/hooks/is_in_security_app'; import { KibanaServices } from '../../../../common/lib/kibana'; -import { fieldHasCellActions, isCountField, isInSecurityApp, isLensEmbeddable } from '../../utils'; +import { fieldHasCellActions, isCountField, isLensEmbeddable } from '../../utils'; import { COPY_TO_CLIPBOARD, COPY_TO_CLIPBOARD_ICON, COPY_TO_CLIPBOARD_SUCCESS } from '../constants'; export const ACTION_ID = 'embeddable_copyToClipboard'; diff --git a/x-pack/plugins/security_solution/public/app/actions/filter/discover/filter_in.ts b/x-pack/plugins/security_solution/public/app/actions/filter/discover/filter_in.ts index d0cdaed61f8a2..19ae6cf1f1748 100644 --- a/x-pack/plugins/security_solution/public/app/actions/filter/discover/filter_in.ts +++ b/x-pack/plugins/security_solution/public/app/actions/filter/discover/filter_in.ts @@ -6,8 +6,8 @@ */ import type { CellAction, CellActionFactory } from '@kbn/cell-actions'; +import { isInSecurityApp } from '../../../../common/hooks/is_in_security_app'; import type { SecurityAppStore } from '../../../../common/store'; -import { isInSecurityApp } from '../../utils'; import type { StartServices } from '../../../../types'; import { createFilterInCellActionFactory } from '../cell_action/filter_in'; diff --git a/x-pack/plugins/security_solution/public/app/actions/filter/discover/filter_out.ts b/x-pack/plugins/security_solution/public/app/actions/filter/discover/filter_out.ts index 757b2f41d99b5..77e463c5268d4 100644 --- a/x-pack/plugins/security_solution/public/app/actions/filter/discover/filter_out.ts +++ b/x-pack/plugins/security_solution/public/app/actions/filter/discover/filter_out.ts @@ -6,7 +6,7 @@ */ import type { CellActionFactory, CellAction } from '@kbn/cell-actions'; -import { isInSecurityApp } from '../../utils'; +import { isInSecurityApp } from '../../../../common/hooks/is_in_security_app'; import type { SecurityAppStore } from '../../../../common/store'; import type { StartServices } from '../../../../types'; import { createFilterOutCellActionFactory } from '../cell_action/filter_out'; diff --git a/x-pack/plugins/security_solution/public/app/actions/filter/lens/create_action.ts b/x-pack/plugins/security_solution/public/app/actions/filter/lens/create_action.ts index 966efe9590ecc..e264466767287 100644 --- a/x-pack/plugins/security_solution/public/app/actions/filter/lens/create_action.ts +++ b/x-pack/plugins/security_solution/public/app/actions/filter/lens/create_action.ts @@ -16,8 +16,9 @@ import type { CellValueContext, IEmbeddable } from '@kbn/embeddable-plugin/publi import { createAction } from '@kbn/ui-actions-plugin/public'; import { ACTION_INCOMPATIBLE_VALUE_WARNING } from '@kbn/cell-actions/src/actions/translations'; import { i18n } from '@kbn/i18n'; +import { isInSecurityApp } from '../../../../common/hooks/is_in_security_app'; import { timelineSelectors } from '../../../../timelines/store'; -import { fieldHasCellActions, isInSecurityApp, isLensEmbeddable } from '../../utils'; +import { fieldHasCellActions, isLensEmbeddable } from '../../utils'; import { TimelineId } from '../../../../../common/types'; import { DefaultCellActionTypes } from '../../constants'; import type { SecurityAppStore } from '../../../../common/store'; diff --git a/x-pack/plugins/security_solution/public/app/actions/utils.ts b/x-pack/plugins/security_solution/public/app/actions/utils.ts index d857c54d5091f..3da597db60c0e 100644 --- a/x-pack/plugins/security_solution/public/app/actions/utils.ts +++ b/x-pack/plugins/security_solution/public/app/actions/utils.ts @@ -7,7 +7,6 @@ import type { IEmbeddable } from '@kbn/embeddable-plugin/public'; import { isLensApi } from '@kbn/lens-plugin/public'; import type { Serializable } from '@kbn/utility-types'; -import { APP_UI_ID } from '../../../common/constants'; // All cell actions are disabled for these fields in Security const FIELDS_WITHOUT_CELL_ACTIONS = [ @@ -17,10 +16,6 @@ const FIELDS_WITHOUT_CELL_ACTIONS = [ 'kibana.alert.reason', ]; -export const isInSecurityApp = (currentAppId?: string): boolean => { - return !!currentAppId && currentAppId === APP_UI_ID; -}; - // @TODO: this is a temporary fix. It needs a better refactor on the consumer side here to // adapt to the new Embeddable architecture export const isLensEmbeddable = (embeddable: IEmbeddable): embeddable is IEmbeddable => { diff --git a/x-pack/plugins/security_solution/public/assistant/content/quick_prompts/index.tsx b/x-pack/plugins/security_solution/public/assistant/content/quick_prompts/index.tsx index adb952d661214..1bf997eb4de2f 100644 --- a/x-pack/plugins/security_solution/public/assistant/content/quick_prompts/index.tsx +++ b/x-pack/plugins/security_solution/public/assistant/content/quick_prompts/index.tsx @@ -12,7 +12,6 @@ import { import { APP_UI_ID } from '../../../../common'; import * as i18n from './translations'; import { - KNOWLEDGE_BASE_CATEGORY, PROMPT_CONTEXT_ALERT_CATEGORY, PROMPT_CONTEXT_DETECTION_RULES_CATEGORY, PROMPT_CONTEXT_EVENT_CATEGORY, @@ -34,16 +33,6 @@ export const BASE_SECURITY_QUICK_PROMPTS: PromptResponse[] = [ promptType: PromptTypeEnum.quick, consumer: APP_UI_ID, }, - { - name: i18n.ESQL_QUERY_GENERATION_TITLE, - content: i18n.ESQL_QUERY_GENERATION_PROMPT, - color: '#9170B8', - categories: [KNOWLEDGE_BASE_CATEGORY], - isDefault: true, - id: i18n.ESQL_QUERY_GENERATION_TITLE, - promptType: PromptTypeEnum.quick, - consumer: APP_UI_ID, - }, { name: i18n.RULE_CREATION_TITLE, content: i18n.RULE_CREATION_PROMPT, diff --git a/x-pack/plugins/security_solution/public/assistant/content/quick_prompts/translations.ts b/x-pack/plugins/security_solution/public/assistant/content/quick_prompts/translations.ts index 41b9e7ddb197b..1d122b0169be2 100644 --- a/x-pack/plugins/security_solution/public/assistant/content/quick_prompts/translations.ts +++ b/x-pack/plugins/security_solution/public/assistant/content/quick_prompts/translations.ts @@ -22,21 +22,6 @@ export const ALERT_SUMMARIZATION_PROMPT = i18n.translate( } ); -export const ESQL_QUERY_GENERATION_TITLE = i18n.translate( - 'xpack.securitySolution.assistant.quickPrompts.esqlQueryGenerationTitle', - { - defaultMessage: 'ES|QL Query Generation', - } -); - -export const ESQL_QUERY_GENERATION_PROMPT = i18n.translate( - 'xpack.securitySolution.assistant.quickPrompts.esqlQueryGenerationPrompt', - { - defaultMessage: - "As an expert user of Elastic Security, please generate an accurate and valid ESQL query to detect the use case below. Your response should be formatted to be able to use immediately in an Elastic Security timeline or detection rule. Take your time with the answer, check your knowledge really well on all the functions I am asking for. For ES|QL answers specifically, you should only ever answer with what's available in your private knowledge. I cannot afford for queries to be inaccurate. Assume I am using the Elastic Common Schema and Elastic Agent.\n\nEnsure the answers are formatted in a way which is easily copyable as a separate code block in markdown.", - } -); - export const RULE_CREATION_TITLE = i18n.translate( 'xpack.securitySolution.assistant.quickPrompts.ruleCreationTitle', { diff --git a/x-pack/plugins/security_solution/public/attack_discovery/pages/results/attack_discovery_panel/tabs/alerts_tab/index.tsx b/x-pack/plugins/security_solution/public/attack_discovery/pages/results/attack_discovery_panel/tabs/alerts_tab/index.tsx index 97bec48eaaae6..1976d97c9c8d5 100644 --- a/x-pack/plugins/security_solution/public/attack_discovery/pages/results/attack_discovery_panel/tabs/alerts_tab/index.tsx +++ b/x-pack/plugins/security_solution/public/attack_discovery/pages/results/attack_discovery_panel/tabs/alerts_tab/index.tsx @@ -6,9 +6,11 @@ */ import type { AttackDiscovery, Replacements } from '@kbn/elastic-assistant-common'; -import { AlertConsumers } from '@kbn/rule-registry-plugin/common/technical_rule_data_field_names'; +import { SECURITY_SOLUTION_RULE_TYPE_IDS } from '@kbn/securitysolution-rules'; +import type { AlertsTableStateProps } from '@kbn/triggers-actions-ui-plugin/public/application/sections/alerts_table/alerts_table_state'; import React, { useMemo } from 'react'; +import { AlertConsumers } from '@kbn/rule-data-utils'; import { ALERTS_TABLE_REGISTRY_CONFIG_IDS } from '../../../../../../../common/constants'; import { useKibana } from '../../../../../../common/lib/kibana'; @@ -39,12 +41,13 @@ const AlertsTabComponent: React.FC = ({ attackDiscovery, replacements }) const configId = ALERTS_TABLE_REGISTRY_CONFIG_IDS.CASE; // show the same row-actions as in the case view - const alertStateProps = useMemo( + const alertStateProps: AlertsTableStateProps = useMemo( () => ({ alertsTableConfigurationRegistry: triggersActionsUi.alertsTableConfigurationRegistry, configurationId: configId, id: `attack-discovery-alerts-${attackDiscovery.id}`, - featureIds: [AlertConsumers.SIEM], + ruleTypeIds: SECURITY_SOLUTION_RULE_TYPE_IDS, + consumers: [AlertConsumers.SIEM], query: alertIdsQuery, showAlertStatusWithFlapping: false, }), diff --git a/x-pack/plugins/security_solution/public/cloud_security_posture/components/csp_details/alerts_findings_details_table.tsx b/x-pack/plugins/security_solution/public/cloud_security_posture/components/csp_details/alerts_findings_details_table.tsx index 6567fb41a93f4..2b1a2002667c2 100644 --- a/x-pack/plugins/security_solution/public/cloud_security_posture/components/csp_details/alerts_findings_details_table.tsx +++ b/x-pack/plugins/security_solution/public/cloud_security_posture/components/csp_details/alerts_findings_details_table.tsx @@ -19,6 +19,8 @@ import { METRIC_TYPE } from '@kbn/analytics'; import { buildEntityAlertsQuery } from '@kbn/cloud-security-posture-common/utils/helpers'; import { useExpandableFlyoutApi } from '@kbn/expandable-flyout'; import { TableId } from '@kbn/securitysolution-data-table'; +import type { AlertsByStatus } from '../../../overview/components/detection_response/alerts_by_status/types'; +import { DETECTION_RESPONSE_ALERTS_BY_STATUS_ID } from '../../../overview/components/detection_response/alerts_by_status/types'; import { OPEN_IN_ALERTS_TITLE_HOSTNAME, OPEN_IN_ALERTS_TITLE_STATUS, @@ -34,6 +36,7 @@ import { getSeverityColor } from '../../../detections/components/alerts_kpis/sev import { SeverityBadge } from '../../../common/components/severity_badge'; import { ALERT_PREVIEW_BANNER } from '../../../flyout/document_details/preview/constants'; import { FILTER_OPEN, FILTER_ACKNOWLEDGED } from '../../../../common/types'; +import { useNonClosedAlerts } from '../../hooks/use_non_closed_alerts'; type AlertSeverity = 'low' | 'medium' | 'high' | 'critical'; @@ -68,6 +71,8 @@ export const AlertsDetailsTable = memo( ); }, []); + const [currentFilter, setCurrentFilter] = useState(''); + const [pageIndex, setPageIndex] = useState(0); const [pageSize, setPageSize] = useState(10); @@ -89,12 +94,46 @@ export const AlertsDetailsTable = memo( const { to, from } = useGlobalTime(); const { signalIndexName } = useSignalIndex(); - const { data } = useQueryAlerts({ - query: buildEntityAlertsQuery(field, to, from, value, 500), + const { data, setQuery } = useQueryAlerts({ + query: buildEntityAlertsQuery(field, to, from, value, 500, ''), queryName: ALERTS_QUERY_NAMES.BY_RULE_BY_STATUS, indexName: signalIndexName, }); + const { filteredAlertsData: alertsData } = useNonClosedAlerts({ + field, + value, + to, + from, + queryId: `${DETECTION_RESPONSE_ALERTS_BY_STATUS_ID}`, + }); + + const severityMap = new Map(); + (Object.keys(alertsData || {}) as AlertsByStatus[]).forEach((status) => { + if (alertsData?.[status]?.severities) { + alertsData?.[status]?.severities.forEach((severity) => { + const currentSeverity = severityMap.get(severity.key) || 0; + severityMap.set(severity.key, currentSeverity + severity.value); + }); + } + }); + + const alertStats = Array.from(severityMap, ([key, count]) => ({ + key: capitalize(key), + count, + color: getSeverityColor(key), + filter: () => { + setCurrentFilter(key); + setQuery(buildEntityAlertsQuery(field, to, from, value, 500, key)); + }, + isCurrentFilter: currentFilter === key, + reset: (event: React.MouseEvent) => { + setCurrentFilter(''); + setQuery(buildEntityAlertsQuery(field, to, from, value, 500, '')); + event?.stopPropagation(); + }, + })); + const alertDataResults = (data?.hits?.hits as AlertsDetailsFields[])?.map( (item: AlertsDetailsFields) => { return { @@ -108,19 +147,6 @@ export const AlertsDetailsTable = memo( } ); - const severitiesMap = alertDataResults?.map((item) => item.severity) || []; - - const alertStats = Object.entries( - severitiesMap.reduce((acc: Record, item) => { - acc[item] = (acc[item] || 0) + 1; - return acc; - }, {}) - ).map(([key, count]) => ({ - key: capitalize(key), - count, - color: getSeverityColor(key), - })); - const { pageOfItems, totalItemCount } = alertsPagination(alertDataResults || []); const pagination = { diff --git a/x-pack/plugins/security_solution/public/cloud_security_posture/components/csp_details/misconfiguration_findings_details_table.tsx b/x-pack/plugins/security_solution/public/cloud_security_posture/components/csp_details/misconfiguration_findings_details_table.tsx index 00430c2b87262..61c89e196a183 100644 --- a/x-pack/plugins/security_solution/public/cloud_security_posture/components/csp_details/misconfiguration_findings_details_table.tsx +++ b/x-pack/plugins/security_solution/public/cloud_security_posture/components/csp_details/misconfiguration_findings_details_table.tsx @@ -10,8 +10,12 @@ import type { Criteria, EuiBasicTableColumn } from '@elastic/eui'; import { EuiSpacer, EuiPanel, EuiText, EuiBasicTable, EuiIcon } from '@elastic/eui'; import { useMisconfigurationFindings } from '@kbn/cloud-security-posture/src/hooks/use_misconfiguration_findings'; import { i18n } from '@kbn/i18n'; -import type { CspFinding, CspFindingResult } from '@kbn/cloud-security-posture-common'; -import { buildEntityFlyoutPreviewQuery } from '@kbn/cloud-security-posture-common'; +import { + MISCONFIGURATION_STATUS, + type CspFinding, + type CspFindingResult, + buildMisconfigurationEntityFlyoutPreviewQuery, +} from '@kbn/cloud-security-posture-common'; import { euiThemeVars } from '@kbn/ui-theme'; import { DistributionBar } from '@kbn/security-solution-distribution-bar'; import type { CspBenchmarkRuleMetadata } from '@kbn/cloud-security-posture-common/schema/rules/latest'; @@ -25,11 +29,17 @@ import { import { METRIC_TYPE } from '@kbn/analytics'; import { useGetNavigationUrlParams } from '@kbn/cloud-security-posture/src/hooks/use_get_navigation_url_params'; import { SecurityPageName } from '@kbn/deeplinks-security'; +import { useHasMisconfigurations } from '@kbn/cloud-security-posture/src/hooks/use_has_misconfigurations'; import { SecuritySolutionLinkAnchor } from '../../../common/components/links'; type MisconfigurationFindingDetailFields = Pick; -const getFindingsStats = (passedFindingsStats: number, failedFindingsStats: number) => { +const getFindingsStats = ( + passedFindingsStats: number, + failedFindingsStats: number, + filterFunction: (filter: string) => void, + currentFilter: string +) => { if (passedFindingsStats === 0 && failedFindingsStats === 0) return []; return [ { @@ -41,6 +51,14 @@ const getFindingsStats = (passedFindingsStats: number, failedFindingsStats: numb ), count: passedFindingsStats, color: euiThemeVars.euiColorSuccess, + filter: () => { + filterFunction(MISCONFIGURATION_STATUS.PASSED); + }, + isCurrentFilter: currentFilter === MISCONFIGURATION_STATUS.PASSED, + reset: (event: React.MouseEvent) => { + filterFunction(''); + event?.stopPropagation(); + }, }, { key: i18n.translate( @@ -51,6 +69,14 @@ const getFindingsStats = (passedFindingsStats: number, failedFindingsStats: numb ), count: failedFindingsStats, color: euiThemeVars.euiColorVis9, + filter: () => { + filterFunction(MISCONFIGURATION_STATUS.FAILED); + }, + isCurrentFilter: currentFilter === MISCONFIGURATION_STATUS.FAILED, + reset: (event: React.MouseEvent) => { + filterFunction(''); + event?.stopPropagation(); + }, }, ]; }; @@ -67,15 +93,16 @@ export const MisconfigurationFindingsDetailsTable = memo( ); }, []); + const [currentFilter, setCurrentFilter] = useState(''); + const { data } = useMisconfigurationFindings({ - query: buildEntityFlyoutPreviewQuery(field, value), + query: buildMisconfigurationEntityFlyoutPreviewQuery(field, value, currentFilter), sort: [], enabled: true, pageSize: 1, }); - const passedFindings = data?.count.passed || 0; - const failedFindings = data?.count.failed || 0; + const { passedFindings, failedFindings } = useHasMisconfigurations(field, value); const [pageIndex, setPageIndex] = useState(0); const [pageSize, setPageSize] = useState(10); @@ -129,6 +156,13 @@ export const MisconfigurationFindingsDetailsTable = memo( const linkWidth = 40; const resultWidth = 74; + const misconfgurationStats = getFindingsStats( + passedFindings, + failedFindings, + setCurrentFilter, + currentFilter + ); + const columns: Array> = [ { field: 'rule', @@ -202,7 +236,7 @@ export const MisconfigurationFindingsDetailsTable = memo( - + (''); + const { data } = useVulnerabilitiesFindings({ - query: buildEntityFlyoutPreviewQuery('host.name', value), + query: buildVulnerabilityEntityFlyoutPreviewQuery('host.name', value, currentFilter), sort: [], enabled: true, pageSize: 1, }); - const { CRITICAL = 0, HIGH = 0, MEDIUM = 0, LOW = 0, NONE = 0 } = data?.count || {}; + const { counts } = useHasVulnerabilities('host.name', value); + + const { critical = 0, high = 0, medium = 0, low = 0, none = 0 } = counts || {}; const [pageIndex, setPageIndex] = useState(0); const [pageSize, setPageSize] = useState(10); @@ -120,6 +127,18 @@ export const VulnerabilitiesFindingsDetailsTable = memo(({ value }: { value: str ); }; + const vulnerabilityStats = getVulnerabilityStats( + { + critical, + high, + medium, + low, + none, + }, + setCurrentFilter, + currentFilter + ); + const columns: Array> = [ { field: 'vulnerability', @@ -220,15 +239,7 @@ export const VulnerabilitiesFindingsDetailsTable = memo(({ value }: { value: str - + { + return !!currentAppId && currentAppId === APP_UI_ID; +}; + +export const useIsInSecurityApp = () => { + const { + services: { application }, + } = useKibana(); + + const currentAppId = useObservable(application.currentAppId$); + + return useMemo(() => isInSecurityApp(currentAppId), [currentAppId]); +}; diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.tsx index 0ca0e99bb7fd0..7a39c6ea0439f 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.tsx @@ -12,7 +12,7 @@ import type { FC } from 'react'; import React, { useRef, useEffect, useState, useCallback, useMemo } from 'react'; import type { AlertsTableStateProps } from '@kbn/triggers-actions-ui-plugin/public/application/sections/alerts_table/alerts_table_state'; import type { Alert } from '@kbn/triggers-actions-ui-plugin/public/types'; -import { ALERT_BUILDING_BLOCK_TYPE } from '@kbn/rule-data-utils'; +import { ALERT_BUILDING_BLOCK_TYPE, AlertConsumers } from '@kbn/rule-data-utils'; import styled from 'styled-components'; import { useDispatch } from 'react-redux'; import { getEsQueryConfig } from '@kbn/data-plugin/public'; @@ -22,6 +22,7 @@ import { tableDefaults, TableId, } from '@kbn/securitysolution-data-table'; +import { SECURITY_SOLUTION_RULE_TYPE_IDS } from '@kbn/securitysolution-rules'; import type { RunTimeMappings } from '@kbn/timelines-plugin/common/search_strategy'; import { useGlobalTime } from '../../../common/containers/use_global_time'; import { useLicense } from '../../../common/hooks/use_license'; @@ -55,7 +56,7 @@ const { updateIsLoading, updateTotalCount } = dataTableActions; const DEFAULT_DATA_GRID_HEIGHT = 600; -const ALERT_TABLE_FEATURE_ID: AlertsTableStateProps['featureIds'] = ['siem']; +const ALERT_TABLE_CONSUMERS: AlertsTableStateProps['consumers'] = [AlertConsumers.SIEM]; // Highlight rows with building block alerts const shouldHighlightRow = (alert: Alert) => !!alert[ALERT_BUILDING_BLOCK_TYPE]; @@ -283,7 +284,8 @@ export const AlertsTableComponent: FC = ({ configurationId: configId, // stores separate configuration based on the view of the table id: `detection-engine-alert-table-${configId}-${tableView}`, - featureIds: ALERT_TABLE_FEATURE_ID, + ruleTypeIds: SECURITY_SOLUTION_RULE_TYPE_IDS, + consumers: ALERT_TABLE_CONSUMERS, query: finalBoolQuery, gridStyle, shouldHighlightRow, diff --git a/x-pack/plugins/security_solution/public/detections/components/detection_engine_filters/detection_engine_filters.tsx b/x-pack/plugins/security_solution/public/detections/components/detection_engine_filters/detection_engine_filters.tsx index 6c60aec51382e..5a01ea1f939d2 100644 --- a/x-pack/plugins/security_solution/public/detections/components/detection_engine_filters/detection_engine_filters.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/detection_engine_filters/detection_engine_filters.tsx @@ -7,12 +7,12 @@ import React, { useCallback, useMemo } from 'react'; import type { FilterControlConfig } from '@kbn/alerts-ui-shared'; -import { AlertConsumers } from '@kbn/rule-data-utils'; import { createKbnUrlStateStorage, Storage } from '@kbn/kibana-utils-plugin/public'; import { ControlGroupRenderer } from '@kbn/controls-plugin/public'; import type { AlertFilterControlsProps } from '@kbn/alerts-ui-shared/src/alert_filter_controls'; import { AlertFilterControls } from '@kbn/alerts-ui-shared/src/alert_filter_controls'; import { useHistory } from 'react-router-dom'; +import { SECURITY_SOLUTION_RULE_TYPE_IDS } from '@kbn/securitysolution-rules'; import type { DataViewSpec } from '@kbn/data-plugin/common'; import { useKibana } from '../../../common/lib/kibana'; import { DEFAULT_DETECTION_PAGE_FILTERS } from '../../../../common/constants'; @@ -78,7 +78,7 @@ export const DetectionEngineFilters = ({ controlsUrlState={filterControlsUrlState} setControlsUrlState={setFilterControlsUrlState} spaceId={spaceId} - featureIds={[AlertConsumers.SIEM]} + ruleTypeIds={SECURITY_SOLUTION_RULE_TYPE_IDS} chainingSystem="HIERARCHICAL" defaultControls={DEFAULT_DETECTION_PAGE_FILTERS} dataViewSpec={dataViewSpec} diff --git a/x-pack/plugins/security_solution/public/entity_analytics/api/entity_store.ts b/x-pack/plugins/security_solution/public/entity_analytics/api/entity_store.ts index f1afa13637bb8..0098b842748e2 100644 --- a/x-pack/plugins/security_solution/public/entity_analytics/api/entity_store.ts +++ b/x-pack/plugins/security_solution/public/entity_analytics/api/entity_store.ts @@ -5,15 +5,14 @@ * 2.0. */ import { useMemo } from 'react'; +import type { GetEntityStoreStatusResponse } from '../../../common/api/entity_analytics/entity_store/status.gen'; import type { - GetEntityStoreStatusResponse, InitEntityStoreRequestBody, InitEntityStoreResponse, -} from '../../../common/api/entity_analytics/entity_store/enablement.gen'; +} from '../../../common/api/entity_analytics/entity_store/enable.gen'; import type { DeleteEntityEngineResponse, EntityType, - GetEntityEngineResponse, InitEntityEngineResponse, ListEntityEnginesResponse, StopEntityEngineResponse, @@ -35,10 +34,11 @@ export const useEntityStoreRoutes = () => { }); }; - const getEntityStoreStatus = async () => { + const getEntityStoreStatus = async (withComponents = false) => { return http.fetch('/api/entity_store/status', { method: 'GET', version: API_VERSIONS.public.v1, + query: { include_components: withComponents }, }); }; @@ -58,13 +58,6 @@ export const useEntityStoreRoutes = () => { }); }; - const getEntityEngine = async (entityType: EntityType) => { - return http.fetch(`/api/entity_store/engines/${entityType}`, { - method: 'GET', - version: API_VERSIONS.public.v1, - }); - }; - const deleteEntityEngine = async (entityType: EntityType, deleteData: boolean) => { return http.fetch(`/api/entity_store/engines/${entityType}`, { method: 'DELETE', @@ -85,7 +78,6 @@ export const useEntityStoreRoutes = () => { getEntityStoreStatus, initEntityEngine, stopEntityEngine, - getEntityEngine, deleteEntityEngine, listEntityEngines, }; diff --git a/x-pack/plugins/security_solution/public/entity_analytics/components/entity_store/components/dashboard_enablement_panel.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_store/components/dashboard_enablement_panel.tsx index 8d0426fd99ceb..38449fa1e72ff 100644 --- a/x-pack/plugins/security_solution/public/entity_analytics/components/entity_store/components/dashboard_enablement_panel.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_store/components/dashboard_enablement_panel.tsx @@ -16,7 +16,7 @@ import { } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; import type { UseQueryResult } from '@tanstack/react-query'; -import type { GetEntityStoreStatusResponse } from '../../../../../common/api/entity_analytics/entity_store/enablement.gen'; +import type { GetEntityStoreStatusResponse } from '../../../../../common/api/entity_analytics/entity_store/status.gen'; import type { StoreStatus } from '../../../../../common/api/entity_analytics'; import { RiskEngineStatusEnum } from '../../../../../common/api/entity_analytics'; import { useInitRiskEngineMutation } from '../../../api/hooks/use_init_risk_engine_mutation'; diff --git a/x-pack/plugins/security_solution/public/entity_analytics/components/entity_store/components/engines_status/components/engine_components_status.test.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_store/components/engines_status/components/engine_components_status.test.tsx new file mode 100644 index 0000000000000..e97c9f961bb50 --- /dev/null +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_store/components/engines_status/components/engine_components_status.test.tsx @@ -0,0 +1,118 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { render, screen, fireEvent } from '@testing-library/react'; +import { EngineComponentsStatusTable } from './engine_components_status'; +import { + EngineComponentResourceEnum, + type EngineComponentStatus, +} from '../../../../../../../common/api/entity_analytics'; +import { TestProviders } from '../../../../../../common/mock'; + +const uninstalledWithErrorsComponent = { + id: 'entity_engine_id', + installed: false, + resource: EngineComponentResourceEnum.entity_engine, + errors: [{ title: 'Error 1', message: 'Error message 1' }], +}; + +const installedComponent = { + id: 'index_id', + resource: EngineComponentResourceEnum.index, + errors: [], + installed: true, +}; + +const mockComponents: EngineComponentStatus[] = [ + uninstalledWithErrorsComponent, + installedComponent, +]; + +const mockGetUrlForApp = jest.fn(); + +jest.mock('../../../../../../common/lib/kibana', () => { + return { + useKibana: jest.fn().mockReturnValue({ + services: { + application: { + getUrlForApp: () => mockGetUrlForApp(), + navigateToApp: jest.fn(), + }, + }, + }), + }; +}); + +describe('EngineComponentsStatusTable', () => { + it('renders the table with components', () => { + render(, { wrapper: TestProviders }); + expect(screen.getByTestId('engine-components-status-table')).toBeInTheDocument(); + }); + + it('expands and collapses rows correctly', () => { + render(, { wrapper: TestProviders }); + + const toggleButton = screen.getByLabelText('Expand'); + fireEvent.click(toggleButton); + + expect(screen.getByText('Error 1')).toBeInTheDocument(); + expect(screen.getByText('Error message 1')).toBeInTheDocument(); + + fireEvent.click(toggleButton); + + expect(screen.queryByText('Error 1')).not.toBeInTheDocument(); + expect(screen.queryByText('Error message 1')).not.toBeInTheDocument(); + }); + + describe('columns', () => { + it('renders the correct resource text', () => { + render(, { + wrapper: TestProviders, + }); + expect(screen.getByText('Index')).toBeInTheDocument(); + }); + + it('renders checkmark on installation column when installed', () => { + render(, { + wrapper: TestProviders, + }); + + const icon = screen.getByTestId('installation-status'); + + expect(icon).toHaveAttribute('data-euiicon-type', 'check'); + }); + + it('renders cross on installation column when installed', () => { + render(, { + wrapper: TestProviders, + }); + + const icon = screen.getByTestId('installation-status'); + + expect(icon).toHaveAttribute('data-euiicon-type', 'cross'); + }); + + it('renders the correct health status', () => { + render(, { + wrapper: TestProviders, + }); + + expect(screen.queryByRole('img', { name: /health/i })).not.toBeInTheDocument(); + }); + + it('renders the correct identifier link', () => { + mockGetUrlForApp.mockReturnValue('mockedUrl'); + + render(, { + wrapper: TestProviders, + }); + const link = screen.getByRole('link'); + expect(link).toHaveAttribute('href', 'mockedUrl'); + }); + }); +}); diff --git a/x-pack/plugins/security_solution/public/entity_analytics/components/entity_store/components/engines_status/components/engine_components_status.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_store/components/engines_status/components/engine_components_status.tsx new file mode 100644 index 0000000000000..eb789035d566f --- /dev/null +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_store/components/engines_status/components/engine_components_status.tsx @@ -0,0 +1,75 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor 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 { ReactNode } from 'react'; +import React, { useState, useMemo, useCallback, Fragment } from 'react'; +import { EuiSpacer, EuiHealth, EuiCodeBlock } from '@elastic/eui'; +import { BasicTable } from '../../../../../../common/components/ml/tables/basic_table'; +import { useColumns } from '../hooks/use_columns'; +import type { EngineComponentStatus } from '../../../../../../../common/api/entity_analytics'; + +type ExpandedRowMap = Record; + +const componentToId = ({ id, resource }: EngineComponentStatus) => `${resource}-${id}`; + +export const EngineComponentsStatusTable = ({ + components, +}: { + components: EngineComponentStatus[]; +}) => { + const [expandedItems, setExpandedItems] = useState([]); + + const itemIdToExpandedRowMap: ExpandedRowMap = useMemo(() => { + return expandedItems.reduce((acc, componentStatus) => { + if (componentStatus.errors && componentStatus.errors.length > 0) { + acc[componentToId(componentStatus)] = ( + + ); + } + return acc; + }, {}); + }, [expandedItems]); + + const onToggle = useCallback( + (component: EngineComponentStatus) => { + const isItemExpanded = expandedItems.includes(component); + + if (isItemExpanded) { + setExpandedItems(expandedItems.filter((item) => component !== item)); + } else { + setExpandedItems([...expandedItems, component]); + } + }, + [expandedItems] + ); + + const columns = useColumns(onToggle, expandedItems); + + return ( + + ); +}; + +const TransformExtendedData = ({ errors }: { errors: EngineComponentStatus['errors'] }) => { + return ( + <> + {errors?.map(({ title, message }) => ( + + + {title} + + {message} + + ))} + + ); +}; diff --git a/x-pack/plugins/security_solution/public/entity_analytics/components/entity_store/components/engines_status/hooks/use_columns.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_store/components/engines_status/hooks/use_columns.tsx new file mode 100644 index 0000000000000..3156c768bf4fc --- /dev/null +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_store/components/engines_status/hooks/use_columns.tsx @@ -0,0 +1,184 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { IconColor } from '@elastic/eui'; +import { + EuiLink, + type EuiBasicTableColumn, + EuiHealth, + EuiScreenReaderOnly, + EuiButtonIcon, + EuiIcon, +} from '@elastic/eui'; +import React, { useMemo } from 'react'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { + EngineComponentResourceEnum, + type EngineComponentResource, +} from '../../../../../../../common/api/entity_analytics'; +import type { EngineComponentStatus } from '../../../../../../../common/api/entity_analytics'; +import { useKibana } from '../../../../../../common/lib/kibana'; + +type TableColumn = EuiBasicTableColumn; + +export const HEALTH_COLOR: Record['health'], IconColor> = { + green: 'success', + unknown: 'subdued', + yellow: 'warning', + red: 'danger', +} as const; + +const RESOURCE_TO_TEXT: Record = { + ingest_pipeline: 'Ingest Pipeline', + enrich_policy: 'Enrich Policy', + index: 'Index', + component_template: 'Component Template', + task: 'Task', + transform: 'Transform', + entity_definition: 'Entity Definition', + entity_engine: 'Engine', + index_template: 'Index Template', +}; + +export const useColumns = ( + onToggleExpandedItem: (item: EngineComponentStatus) => void, + expandedItems: EngineComponentStatus[] +): TableColumn[] => { + const { getUrlForApp } = useKibana().services.application; + + return useMemo( + () => [ + { + field: 'resource', + name: ( + + ), + width: '20%', + render: (resource: EngineComponentStatus['resource']) => RESOURCE_TO_TEXT[resource], + }, + { + field: 'id', + name: ( + + ), + render: (id: EngineComponentStatus['id'], { resource, installed }) => { + const path = getResourcePath(id, resource); + + if (!installed || !path) { + return id; + } + + return ( + + {id} + + ); + }, + }, + { + field: 'installed', + name: ( + + ), + width: '10%', + align: 'center', + render: (value: boolean) => + value ? ( + + ) : ( + + ), + }, + { + name: ( + + ), + width: '10%', + align: 'center', + render: ({ installed, resource, health }: EngineComponentStatus) => { + if (!installed) { + return null; + } + + return ; + }, + }, + { + isExpander: true, + align: 'right', + width: '40px', + name: ( + + + + + + ), + mobileOptions: { header: false }, + render: (component: EngineComponentStatus) => { + const isItemExpanded = expandedItems.includes(component); + + return component.errors && component.errors.length > 0 ? ( + onToggleExpandedItem(component)} + aria-label={isItemExpanded ? 'Collapse' : 'Expand'} + iconType={isItemExpanded ? 'arrowDown' : 'arrowRight'} + /> + ) : null; + }, + }, + ], + [expandedItems, getUrlForApp, onToggleExpandedItem] + ); +}; + +const getResourcePath = (id: string, resource: EngineComponentResource) => { + if (resource === EngineComponentResourceEnum.ingest_pipeline) { + return `ingest/ingest_pipelines?pipeline=${id}`; + } + + if (resource === EngineComponentResourceEnum.index_template) { + return `data/index_management/templates/${id}`; + } + + if (resource === EngineComponentResourceEnum.index) { + return `data/index_management/indices/index_details?indexName=${id}`; + } + + if (resource === EngineComponentResourceEnum.component_template) { + return `data/index_management/component_templates/${id}`; + } + + if (resource === EngineComponentResourceEnum.enrich_policy) { + return `data/index_management/enrich_policies?policy=${id}`; + } + + if (resource === EngineComponentResourceEnum.transform) { + return `data/transform/enrich_policies?_a=(transform:(queryText:'${id}'))`; + } + return null; +}; diff --git a/x-pack/plugins/security_solution/public/entity_analytics/components/entity_store/components/engines_status/index.test.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_store/components/engines_status/index.test.tsx new file mode 100644 index 0000000000000..2f9e74df39d39 --- /dev/null +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_store/components/engines_status/index.test.tsx @@ -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 React from 'react'; +import { render, screen, fireEvent } from '@testing-library/react'; +import { EngineStatus } from '.'; + +import { TestProviders } from '@kbn/timelines-plugin/public/mock'; + +const mockUseEntityStore = jest.fn(); +jest.mock('../../hooks/use_entity_store', () => ({ + useEntityStoreStatus: () => mockUseEntityStore(), +})); + +const mockDownloadBlob = jest.fn(); +jest.mock('../../../../../common/utils/download_blob', () => ({ + downloadBlob: () => mockDownloadBlob(), +})); + +describe('EngineStatus', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('renders loading spinner when data is loading', () => { + mockUseEntityStore.mockReturnValue({ + data: undefined, + isLoading: true, + error: null, + }); + + render(, { wrapper: TestProviders }); + + expect(screen.getByRole('progressbar')).toBeInTheDocument(); + }); + + it('renders error state when there is an error', () => { + mockUseEntityStore.mockReturnValue({ + data: null, + isLoading: false, + error: new Error('Error'), + }); + + render(, { wrapper: TestProviders }); + + expect(screen.getByText('There was an error loading the engine status')).toBeInTheDocument(); + }); + + it('renders "No engines found" message when there are no engines', () => { + mockUseEntityStore.mockReturnValue({ + data: { engines: [] }, + isLoading: false, + error: null, + }); + + render(, { wrapper: TestProviders }); + + expect(screen.getByText('No engines found')).toBeInTheDocument(); + }); + + it('renders engine components when data is available', () => { + const mockData = { + engines: [ + { + type: 'test', + components: [{ id: 'entity_engine_id', installed: true, resource: 'entity_engine' }], + }, + ], + }; + mockUseEntityStore.mockReturnValue({ data: mockData, isLoading: false, error: null }); + + render(, { wrapper: TestProviders }); + + expect(screen.getByText('Test Store')).toBeInTheDocument(); + expect(screen.getByText('Download status')).toBeInTheDocument(); + }); + + it('calls downloadJson when download button is clicked', () => { + const mockData = { + engines: [ + { + type: 'test', + components: [{ id: 'entity_engine_id', installed: true, resource: 'entity_engine' }], + }, + ], + }; + mockUseEntityStore.mockReturnValue({ data: mockData, isLoading: false, error: null }); + + render(, { wrapper: TestProviders }); + + const downloadButton = screen.getByText('Download status'); + fireEvent.click(downloadButton); + + expect(mockDownloadBlob).toHaveBeenCalled(); + }); +}); diff --git a/x-pack/plugins/security_solution/public/entity_analytics/components/entity_store/components/engines_status/index.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_store/components/engines_status/index.tsx new file mode 100644 index 0000000000000..692841334bd50 --- /dev/null +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_store/components/engines_status/index.tsx @@ -0,0 +1,103 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor 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, { Fragment } from 'react'; +import { + EuiLoadingSpinner, + EuiPanel, + EuiSpacer, + EuiButtonEmpty, + EuiFlexItem, + EuiTitle, + EuiFlexGroup, + EuiCallOut, +} from '@elastic/eui'; +import { capitalize } from 'lodash/fp'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { i18n } from '@kbn/i18n'; +import { useErrorToast } from '../../../../../common/hooks/use_error_toast'; +import { downloadBlob } from '../../../../../common/utils/download_blob'; +import { EngineComponentsStatusTable } from './components/engine_components_status'; +import { useEntityStoreStatus } from '../../hooks/use_entity_store'; + +const FILE_NAME = 'engines_status.json'; + +export const EngineStatus: React.FC = () => { + const { data, isLoading, error } = useEntityStoreStatus({ withComponents: true }); + + const downloadJson = () => { + downloadBlob(new Blob([JSON.stringify(data)]), FILE_NAME); + }; + + const errorMessage = i18n.translate( + 'xpack.securitySolution.entityAnalytics.entityStore.enginesStatus.queryError', + { + defaultMessage: 'There was an error loading the engine status', + } + ); + + useErrorToast(errorMessage, error); + + if (error) { + return ; + } + + if (!data || isLoading) return ; + + if (data.engines.length === 0) { + return ( + + ); + } + + return ( + + {data?.engines?.length > 0 && ( + + + + + + + + + + )} + + {(data?.engines ?? []).map((engine) => ( + + +

        + +

        +
        + + + + + {engine.components && } + + + +
        + ))} +
        +
        + ); +}; diff --git a/x-pack/plugins/security_solution/public/entity_analytics/components/entity_store/hooks/use_entity_store.ts b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_store/hooks/use_entity_store.ts index b27b5b4cdf26a..ceb93d164af62 100644 --- a/x-pack/plugins/security_solution/public/entity_analytics/components/entity_store/hooks/use_entity_store.ts +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_store/hooks/use_entity_store.ts @@ -5,13 +5,12 @@ * 2.0. */ -import type { UseMutationOptions, UseQueryOptions } from '@tanstack/react-query'; +import type { UseMutationOptions } from '@tanstack/react-query'; import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; -import type { - GetEntityStoreStatusResponse, - InitEntityStoreResponse, -} from '../../../../../common/api/entity_analytics/entity_store/enablement.gen'; +import type { IHttpFetchError } from '@kbn/core-http-browser'; +import type { GetEntityStoreStatusResponse } from '../../../../../common/api/entity_analytics/entity_store/status.gen'; +import type { InitEntityStoreResponse } from '../../../../../common/api/entity_analytics/entity_store/enable.gen'; import { useKibana } from '../../../../common/lib/kibana/kibana_react'; import type { DeleteEntityEngineResponse, @@ -26,19 +25,24 @@ const ENTITY_STORE_STATUS = ['GET', 'ENTITY_STORE_STATUS']; interface ResponseError { body: { message: string }; } -export const useEntityStoreStatus = (options: UseQueryOptions) => { + +interface Options { + withComponents?: boolean; +} + +export const useEntityStoreStatus = (opts: Options = {}) => { const { getEntityStoreStatus } = useEntityStoreRoutes(); - const query = useQuery(ENTITY_STORE_STATUS, getEntityStoreStatus, { + return useQuery({ + queryKey: [...ENTITY_STORE_STATUS, opts.withComponents], + queryFn: () => getEntityStoreStatus(opts.withComponents), refetchInterval: (data) => { if (data?.status === 'installing') { return 5000; } return false; }, - ...options, }); - return query; }; export const ENABLE_STORE_STATUS_KEY = ['POST', 'ENABLE_ENTITY_STORE']; @@ -102,15 +106,18 @@ export const useStopEntityEngineMutation = (options?: UseMutationOptions<{}>) => }; export const DELETE_ENTITY_ENGINE_STATUS_KEY = ['POST', 'STOP_ENTITY_ENGINE']; -export const useDeleteEntityEngineMutation = (options?: UseMutationOptions<{}>) => { +export const useDeleteEntityEngineMutation = ({ onSuccess }: { onSuccess?: () => void }) => { const queryClient = useQueryClient(); const { deleteEntityEngine } = useEntityStoreRoutes(); + return useMutation( () => Promise.all([deleteEntityEngine('user', true), deleteEntityEngine('host', true)]), { mutationKey: DELETE_ENTITY_ENGINE_STATUS_KEY, - onSuccess: () => queryClient.refetchQueries({ queryKey: ENTITY_STORE_STATUS }), - ...options, + onSuccess: () => { + queryClient.refetchQueries({ queryKey: ENTITY_STORE_STATUS }); + onSuccess?.(); + }, } ); }; diff --git a/x-pack/plugins/security_solution/public/entity_analytics/pages/entity_store_management_page.test.tsx b/x-pack/plugins/security_solution/public/entity_analytics/pages/entity_store_management_page.test.tsx new file mode 100644 index 0000000000000..cc15a5360a3d1 --- /dev/null +++ b/x-pack/plugins/security_solution/public/entity_analytics/pages/entity_store_management_page.test.tsx @@ -0,0 +1,207 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { render, screen, fireEvent } from '@testing-library/react'; +import { EntityStoreManagementPage } from './entity_store_management_page'; +import { TestProviders } from '../../common/mock'; + +jest.mock('../components/entity_store/components/engines_status', () => ({ + EngineStatus: () => {'Mocked Engine Status Tab'}, +})); + +const mockUseAssetCriticalityPrivileges = jest.fn(); +jest.mock('../components/asset_criticality/use_asset_criticality', () => ({ + useAssetCriticalityPrivileges: () => mockUseAssetCriticalityPrivileges(), +})); + +const mockUseIsExperimentalFeatureEnabled = jest.fn(); +jest.mock('../../common/hooks/use_experimental_features', () => ({ + useIsExperimentalFeatureEnabled: () => mockUseIsExperimentalFeatureEnabled(), +})); + +const mockUseHasSecurityCapability = jest.fn().mockReturnValue(true); +jest.mock('../../helper_hooks', () => ({ + useHasSecurityCapability: () => mockUseHasSecurityCapability(), +})); + +const mockUseEntityStoreStatus = jest.fn(); +jest.mock('../components/entity_store/hooks/use_entity_store', () => ({ + ...jest.requireActual('../components/entity_store/hooks/use_entity_store'), + useEntityStoreStatus: () => mockUseEntityStoreStatus(), +})); + +const mockUseEntityEnginePrivileges = jest.fn(); +jest.mock('../components/entity_store/hooks/use_entity_engine_privileges', () => ({ + useEntityEnginePrivileges: () => mockUseEntityEnginePrivileges(), +})); + +describe('EntityStoreManagementPage', () => { + beforeEach(() => { + jest.clearAllMocks(); + + mockUseAssetCriticalityPrivileges.mockReturnValue({ + isLoading: false, + data: { has_write_permissions: true }, + }); + + mockUseEntityEnginePrivileges.mockReturnValue({ + data: { has_all_required: true }, + }); + + mockUseEntityStoreStatus.mockReturnValue({ + data: { + status: 'running', + }, + errors: [], + }); + + mockUseIsExperimentalFeatureEnabled.mockReturnValue(false); + }); + + it('does not render page when asset criticality is loading', () => { + mockUseAssetCriticalityPrivileges.mockReturnValue({ + isLoading: true, + }); + + render(, { wrapper: TestProviders }); + + expect(screen.queryByTestId('entityStoreManagementPage')).not.toBeInTheDocument(); + }); + + it('renders the page header', () => { + mockUseIsExperimentalFeatureEnabled.mockReturnValue(false); + + render(, { wrapper: TestProviders }); + + expect(screen.getByTestId('entityStoreManagementPage')).toBeInTheDocument(); + expect(screen.getByText('Entity Store')).toBeInTheDocument(); + }); + + it('disables the switch when status is installing', () => { + mockUseEntityStoreStatus.mockReturnValue({ + data: { + status: 'installing', + }, + errors: [], + }); + + mockUseIsExperimentalFeatureEnabled.mockReturnValue(false); + + render(, { wrapper: TestProviders }); + + expect(screen.getByTestId('entity-store-switch')).toBeDisabled(); + }); + + it('show clear entity data modal when clear data button clicked', () => { + mockUseIsExperimentalFeatureEnabled.mockReturnValue(false); + + render(, { wrapper: TestProviders }); + + fireEvent.click(screen.getByText('Clear Entity Data')); + + expect(screen.getByText('Clear Entity data?')).toBeInTheDocument(); + }); + + it('renders the AssetCriticalityIssueCallout when there is an error', () => { + mockUseAssetCriticalityPrivileges.mockReturnValue({ + isLoading: false, + error: { body: { message: 'Error message', status_code: 403 } }, + }); + + mockUseIsExperimentalFeatureEnabled.mockReturnValue(false); + + render(, { wrapper: TestProviders }); + + expect( + screen.getByText('Asset criticality CSV file upload functionality unavailable.') + ).toBeInTheDocument(); + expect(screen.getByText('Error message')).toBeInTheDocument(); + }); + + it('renders the InsufficientAssetCriticalityPrivilegesCallout when there are no write permissions', () => { + mockUseAssetCriticalityPrivileges.mockReturnValue({ + isLoading: false, + data: { has_write_permissions: false }, + }); + + mockUseIsExperimentalFeatureEnabled.mockReturnValue(false); + + render(, { wrapper: TestProviders }); + + expect( + screen.getByText('Insufficient index privileges to perform CSV upload') + ).toBeInTheDocument(); + }); + + it('selects the Import tab by default', () => { + mockUseIsExperimentalFeatureEnabled.mockReturnValue(false); + + render(, { wrapper: TestProviders }); + + expect(screen.getByText('Import Entities').parentNode).toHaveAttribute('aria-selected', 'true'); + }); + + it('switches to the Status tab when clicked', () => { + mockUseEntityStoreStatus.mockReturnValue({ + data: { + status: 'running', + }, + errors: [], + }); + + mockUseEntityEnginePrivileges.mockReturnValue({ + data: { has_all_required: true }, + }); + + mockUseIsExperimentalFeatureEnabled.mockReturnValue(false); + + render(, { wrapper: TestProviders }); + + fireEvent.click(screen.getByText('Engine Status')); + + expect(screen.getByText('Engine Status').parentNode).toHaveAttribute('aria-selected', 'true'); + }); + + it('does not render the Status tab when entity store is not installed', () => { + mockUseEntityStoreStatus.mockReturnValue({ + data: { + status: 'not_installed', + }, + errors: [], + }); + + mockUseEntityEnginePrivileges.mockReturnValue({ + data: { has_all_required: true }, + }); + + mockUseIsExperimentalFeatureEnabled.mockReturnValue(false); + + render(, { wrapper: TestProviders }); + + expect(screen.queryByText('Engine Status')).not.toBeInTheDocument(); + }); + + it('does not render the Status tab when privileges are missing', () => { + mockUseEntityStoreStatus.mockReturnValue({ + data: { + status: 'running', + }, + errors: [], + }); + + mockUseEntityEnginePrivileges.mockReturnValue({ + data: { has_all_required: false, privileges: { kibana: {}, elasticsearch: {} } }, + }); + + mockUseIsExperimentalFeatureEnabled.mockReturnValue(false); + + render(, { wrapper: TestProviders }); + + expect(screen.queryByText('Engine Status')).not.toBeInTheDocument(); + }); +}); diff --git a/x-pack/plugins/security_solution/public/entity_analytics/pages/entity_store_management_page.tsx b/x-pack/plugins/security_solution/public/entity_analytics/pages/entity_store_management_page.tsx index 7c00f61f62fbb..3cf3eb58355c6 100644 --- a/x-pack/plugins/security_solution/public/entity_analytics/pages/entity_store_management_page.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/pages/entity_store_management_page.tsx @@ -21,13 +21,15 @@ import { EuiCode, EuiSwitch, EuiHealth, - EuiButton, EuiLoadingSpinner, EuiToolTip, EuiBetaBadge, + EuiTabs, + EuiTab, + EuiButtonEmpty, } from '@elastic/eui'; import type { ReactNode } from 'react'; -import React, { useCallback, useState } from 'react'; +import React, { useCallback, useEffect, useState } from 'react'; import { FormattedMessage } from '@kbn/i18n-react'; import type { SecurityAppError } from '@kbn/securitysolution-t-grid'; @@ -47,11 +49,18 @@ import { import { TECHNICAL_PREVIEW, TECHNICAL_PREVIEW_TOOLTIP } from '../../common/translations'; import { useEntityEnginePrivileges } from '../components/entity_store/hooks/use_entity_engine_privileges'; import { MissingPrivilegesCallout } from '../components/entity_store/components/missing_privileges_callout'; +import { EngineStatus } from '../components/entity_store/components/engines_status'; + +enum TabId { + Import = 'import', + Status = 'status', +} const isSwitchDisabled = (status?: StoreStatus) => status === 'error' || status === 'installing'; const isEntityStoreEnabled = (status?: StoreStatus) => status === 'running'; const canDeleteEntityEngine = (status?: StoreStatus) => !['not_installed', 'installing'].includes(status || ''); +const isEntityStoreInstalled = (status?: StoreStatus) => status && status !== 'not_installed'; export const EntityStoreManagementPage = () => { const hasEntityAnalyticsCapability = useHasSecurityCapability('entity-analytics'); @@ -62,7 +71,7 @@ export const EntityStoreManagementPage = () => { isLoading: assetCriticalityIsLoading, } = useAssetCriticalityPrivileges('AssetCriticalityUploadPage'); const hasAssetCriticalityWritePermissions = assetCriticalityPrivileges?.has_write_permissions; - + const [selectedTabId, setSelectedTabId] = useState(TabId.Import); const entityStoreStatus = useEntityStoreStatus({}); const enableStoreMutation = useEnableEntityStoreMutation(); @@ -91,6 +100,15 @@ export const EntityStoreManagementPage = () => { const { data: privileges } = useEntityEnginePrivileges(); + const shouldDisplayEngineStatusTab = + isEntityStoreInstalled(entityStoreStatus.data?.status) && privileges?.has_all_required; + + useEffect(() => { + if (selectedTabId === TabId.Status && !shouldDisplayEngineStatusTab) { + setSelectedTabId(TabId.Import); + } + }, [shouldDisplayEngineStatusTab, selectedTabId]); + if (assetCriticalityIsLoading) { // Wait for permission before rendering content to avoid flickering return null; @@ -149,8 +167,18 @@ export const EntityStoreManagementPage = () => { onSwitch={onSwitchClick} status={entityStoreStatus.data?.status} />, + canDeleteEntityEngine(entityStoreStatus.data?.status) ? ( + + ) : null, ] - : [] + : undefined } /> @@ -169,14 +197,44 @@ export const EntityStoreManagementPage = () => { )} - - + + + + setSelectedTabId(TabId.Import)} + > + + + + {shouldDisplayEngineStatusTab && ( + setSelectedTabId(TabId.Status)} + > + + + )} + + + - + {selectedTabId === TabId.Import && ( + + )} + {selectedTabId === TabId.Status && } {enableStoreMutation.isError && ( @@ -210,19 +268,7 @@ export const EntityStoreManagementPage = () => {
        )} {callouts} - - {!isEntityStoreFeatureFlagDisabled && - privileges?.has_all_required && - canDeleteEntityEngine(entityStoreStatus.data?.status) && ( - - )} + {selectedTabId === TabId.Import && }
        @@ -375,15 +421,13 @@ const InsufficientAssetCriticalityPrivilegesCallout: React.FC = () => { ); }; -const AssetCriticalityIssueCallout: React.FC = ({ +const AssetCriticalityIssueCallout: React.FC<{ errorMessage?: string | ReactNode }> = ({ errorMessage, -}: { - errorMessage?: string | ReactNode; }) => { const msg = errorMessage ?? ( ); @@ -405,7 +449,7 @@ const AssetCriticalityIssueCallout: React.FC = ({ ); }; -const ClearEntityDataPanel: React.FC<{ +const ClearEntityDataButton: React.FC<{ deleteEntityEngineMutation: ReturnType; isClearModalVisible: boolean; closeClearModal: () => void; @@ -413,37 +457,19 @@ const ClearEntityDataPanel: React.FC<{ }> = ({ deleteEntityEngineMutation, isClearModalVisible, closeClearModal, showClearModal }) => { return ( <> - - -

        - -

        - - -
        - - { - showClearModal(); - }} - > - - -
        + { + showClearModal(); + }} + > + + + {isClearModalVisible && ( { if (!hasEntityAnalyticsCapability || assetCriticalityPrivilegesError?.body.status_code === 403) { - return ; + return ( + + ); } if (!hasAssetCriticalityWritePermissions) { return ; } return ( - -

        - -

        -
        = const { scopeId, isPreview } = useDocumentDetailsContext(); const { euiTheme } = useEuiTheme(); const { data } = useMisconfigurationPreview({ - query: buildEntityFlyoutPreviewQuery(fieldName, name), + query: buildGenericEntityFlyoutPreviewQuery(fieldName, name), sort: [], enabled: true, pageSize: 1, diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/shared/components/vulnerabilities_insight.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/shared/components/vulnerabilities_insight.tsx index 1dab4660194b9..8991124a77e24 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/shared/components/vulnerabilities_insight.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/shared/components/vulnerabilities_insight.tsx @@ -10,7 +10,7 @@ import { EuiFlexItem, type EuiFlexGroupProps, useEuiTheme } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; import { css } from '@emotion/css'; import { useVulnerabilitiesPreview } from '@kbn/cloud-security-posture/src/hooks/use_vulnerabilities_preview'; -import { buildEntityFlyoutPreviewQuery } from '@kbn/cloud-security-posture-common'; +import { buildGenericEntityFlyoutPreviewQuery } from '@kbn/cloud-security-posture-common'; import { getVulnerabilityStats, hasVulnerabilitiesData } from '@kbn/cloud-security-posture'; import { uiMetricService, @@ -53,7 +53,7 @@ export const VulnerabilitiesInsight: React.FC = ({ const { scopeId, isPreview } = useDocumentDetailsContext(); const { euiTheme } = useEuiTheme(); const { data } = useVulnerabilitiesPreview({ - query: buildEntityFlyoutPreviewQuery('host.name', hostName), + query: buildGenericEntityFlyoutPreviewQuery('host.name', hostName), sort: [], enabled: true, pageSize: 1, diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/command_render_components/integration_tests/execute_action.test.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/command_render_components/integration_tests/execute_action.test.tsx index 7e2a5bf622233..cd125348a688b 100644 --- a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/command_render_components/integration_tests/execute_action.test.tsx +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/command_render_components/integration_tests/execute_action.test.tsx @@ -73,6 +73,7 @@ describe('When using execute action from response actions console', () => { endpointAgentId: 'a.b.c', endpointCapabilities: [...capabilities], endpointPrivileges, + platform: 'linux', }), }, }; diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/command_render_components/integration_tests/get_file_action.test.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/command_render_components/integration_tests/get_file_action.test.tsx index 101c24c84e678..11fa0213394ce 100644 --- a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/command_render_components/integration_tests/get_file_action.test.tsx +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/command_render_components/integration_tests/get_file_action.test.tsx @@ -71,6 +71,7 @@ describe('When using get-file action from response actions console', () => { endpointAgentId: 'a.b.c', endpointCapabilities: [...ENDPOINT_CAPABILITIES], endpointPrivileges, + platform: 'linux', }; render = async (capabilities: EndpointCapabilities[] = [...ENDPOINT_CAPABILITIES]) => { diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/command_render_components/integration_tests/get_processes_action.test.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/command_render_components/integration_tests/get_processes_action.test.tsx index d1922a7bf6e59..48a837a574432 100644 --- a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/command_render_components/integration_tests/get_processes_action.test.tsx +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/command_render_components/integration_tests/get_processes_action.test.tsx @@ -59,6 +59,7 @@ describe('When using processes action from response actions console', () => { canSuspendProcess: true, canGetRunningProcesses: true, }, + platform: 'linux', }); }; diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/command_render_components/integration_tests/isolate_action.test.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/command_render_components/integration_tests/isolate_action.test.tsx index b022fe15d5ed2..d702bfca9945d 100644 --- a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/command_render_components/integration_tests/isolate_action.test.tsx +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/command_render_components/integration_tests/isolate_action.test.tsx @@ -67,6 +67,7 @@ describe('When using isolate action from response actions console', () => { loading: false, canIsolateHost: true, }, + platform: 'linux', }), }, }; diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/command_render_components/integration_tests/kill_process_action.test.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/command_render_components/integration_tests/kill_process_action.test.tsx index f1cf6937eef06..5f4a40b50d8a3 100644 --- a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/command_render_components/integration_tests/kill_process_action.test.tsx +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/command_render_components/integration_tests/kill_process_action.test.tsx @@ -63,6 +63,7 @@ describe.skip('When using the kill-process action from response actions console' canSuspendProcess: true, canGetRunningProcesses: true, }, + platform: 'linux', }); }; diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/command_render_components/integration_tests/release_action.test.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/command_render_components/integration_tests/release_action.test.tsx index 75278dd0f2c01..8e98d05247947 100644 --- a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/command_render_components/integration_tests/release_action.test.tsx +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/command_render_components/integration_tests/release_action.test.tsx @@ -46,6 +46,7 @@ const prepareTest = () => { canUnIsolateHost: true, loading: false, }, + platform: 'linux', }), }, }; diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/command_render_components/integration_tests/scan_action.test.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/command_render_components/integration_tests/scan_action.test.tsx index e0fde4a2133d2..f82ad0aa19b68 100644 --- a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/command_render_components/integration_tests/scan_action.test.tsx +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/command_render_components/integration_tests/scan_action.test.tsx @@ -83,6 +83,7 @@ describe('When using scan action from response actions console', () => { endpointAgentId: 'agent-a', endpointCapabilities: [...ENDPOINT_CAPABILITIES], endpointPrivileges, + platform: 'linux', }; render = async (capabilities: EndpointCapabilities[] = [...ENDPOINT_CAPABILITIES]) => { diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/command_render_components/integration_tests/status_action.test.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/command_render_components/integration_tests/status_action.test.tsx index 47f1c0b9a47e3..b1367ee132eeb 100644 --- a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/command_render_components/integration_tests/status_action.test.tsx +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/command_render_components/integration_tests/status_action.test.tsx @@ -111,6 +111,7 @@ describe.skip('When using processes action from response actions console', () => ...getEndpointAuthzInitialState(), loading: false, }, + platform: 'linux', }), }, }; diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/command_render_components/integration_tests/suspend_process_action.test.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/command_render_components/integration_tests/suspend_process_action.test.tsx index 1492acd862879..dd69a31ad36ed 100644 --- a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/command_render_components/integration_tests/suspend_process_action.test.tsx +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/command_render_components/integration_tests/suspend_process_action.test.tsx @@ -73,6 +73,7 @@ describe('When using the suspend-process action from response actions console', canSuspendProcess: true, canGetRunningProcesses: true, }, + platform: 'linux', }), }, }; diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/command_render_components/integration_tests/upload_action.test.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/command_render_components/integration_tests/upload_action.test.tsx index a6493430615ff..ced1ea4d0e0ad 100644 --- a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/command_render_components/integration_tests/upload_action.test.tsx +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/command_render_components/integration_tests/upload_action.test.tsx @@ -88,6 +88,7 @@ describe.skip('When using `upload` response action', () => { endpointAgentId: 'a.b.c', endpointCapabilities, endpointPrivileges, + platform: 'linux', }), }, }; diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/lib/console_commands_definition.ts b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/lib/console_commands_definition.ts index c81674bd4f7b8..efc52fd59c326 100644 --- a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/lib/console_commands_definition.ts +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/lib/console_commands_definition.ts @@ -153,6 +153,8 @@ export interface GetEndpointConsoleCommandsOptions { /** Applicable only for Endpoint Agents */ endpointCapabilities: ImmutableArray; endpointPrivileges: EndpointPrivileges; + /** Host's platform: windows, linux, macos */ + platform: string; } export const getEndpointConsoleCommands = ({ @@ -160,6 +162,7 @@ export const getEndpointConsoleCommands = ({ agentType, endpointCapabilities, endpointPrivileges, + platform, }: GetEndpointConsoleCommandsOptions): CommandDefinition[] => { const featureFlags = ExperimentalFeaturesService.get(); @@ -523,7 +526,7 @@ export const getEndpointConsoleCommands = ({ switch (agentType) { case 'sentinel_one': - return adjustCommandsForSentinelOne({ commandList: consoleCommands }); + return adjustCommandsForSentinelOne({ commandList: consoleCommands, platform }); case 'crowdstrike': return adjustCommandsForCrowdstrike({ commandList: consoleCommands }); default: @@ -543,8 +546,10 @@ const disableCommand = (command: CommandDefinition, agentType: ResponseActionAge /** @private */ const adjustCommandsForSentinelOne = ({ commandList, + platform, }: { commandList: CommandDefinition[]; + platform: string; }): CommandDefinition[] => { const featureFlags = ExperimentalFeaturesService.get(); const isKillProcessEnabled = featureFlags.responseActionsSentinelOneKillProcessEnabled; @@ -580,6 +585,28 @@ const adjustCommandsForSentinelOne = ({ ) ) { disableCommand(command, 'sentinel_one'); + } else { + // processes is not currently supported for Windows hosts + if (command.name === 'processes' && platform.toLowerCase() === 'windows') { + const message = i18n.translate( + 'xpack.securitySolution.consoleCommandsDefinition.sentineloneProcessesWindowRestriction', + { + defaultMessage: + 'Processes command is not currently supported for SentinelOne hosts running on Windows', + } + ); + + command.helpDisabled = true; + command.about = getCommandAboutInfo({ + aboutInfo: command.about, + isSupported: false, + dataTestSubj: 'sentineloneProcessesWindowsWarningTooltip', + tooltipContent: message, + }); + command.validate = () => { + return message; + }; + } } return command; diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/lib/get_command_about_info.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/lib/get_command_about_info.tsx index ddb5e345acc21..2b22d0067dc5b 100644 --- a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/lib/get_command_about_info.tsx +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/lib/get_command_about_info.tsx @@ -6,6 +6,7 @@ */ import React from 'react'; +import type { EuiToolTipProps } from '@elastic/eui'; import { EuiIconTip } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; @@ -17,23 +18,28 @@ const UNSUPPORTED_COMMAND_INFO = i18n.translate( } ); -const DisabledTooltip = React.memo(() => { - return ; -}); -DisabledTooltip.displayName = 'DisabledTooltip'; - export const getCommandAboutInfo = ({ aboutInfo, isSupported, + tooltipContent = UNSUPPORTED_COMMAND_INFO, + dataTestSubj, }: { - aboutInfo: string; + aboutInfo: React.ReactNode; isSupported: boolean; + tooltipContent?: EuiToolTipProps['content']; + dataTestSubj?: string; }) => { return isSupported ? ( aboutInfo ) : ( <> - {aboutInfo} + {aboutInfo}{' '} + ); }; diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/lib/integration_tests/console_commands_definition.test.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/lib/integration_tests/console_commands_definition.test.tsx index 7c1e5cf118df0..caf33de458f83 100644 --- a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/lib/integration_tests/console_commands_definition.test.tsx +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/lib/integration_tests/console_commands_definition.test.tsx @@ -52,6 +52,7 @@ describe('When displaying Endpoint Response Actions', () => { endpointAgentId: '123', endpointCapabilities: endpointMetadata.Endpoint.capabilities ?? [], endpointPrivileges: getEndpointPrivilegesInitialStateMock(), + platform: 'linux', }); }); @@ -89,6 +90,8 @@ describe('When displaying Endpoint Response Actions', () => { responseActionsCrowdstrikeManualHostIsolationEnabled: true, responseActionsSentinelOneV1Enabled: true, responseActionsSentinelOneGetFileEnabled: true, + responseActionsSentinelOneKillProcessEnabled: true, + responseActionsSentinelOneProcessesEnabled: true, }); commands = getEndpointConsoleCommands({ @@ -96,6 +99,7 @@ describe('When displaying Endpoint Response Actions', () => { endpointAgentId: '123', endpointCapabilities: endpointMetadata.Endpoint.capabilities ?? [], endpointPrivileges: getEndpointPrivilegesInitialStateMock(), + platform: 'linux', }); }); @@ -110,13 +114,34 @@ describe('When displaying Endpoint Response Actions', () => { }); it('should display response action commands in the help panel in expected order', () => { - render({ commands }); + const { queryByTestId } = render({ commands }); consoleSelectors.openHelpPanel(); const commandsInPanel = helpPanelSelectors.getHelpCommandNames( HELP_GROUPS.responseActions.label ); - expect(commandsInPanel).toEqual(['isolate', 'release', 'get-file --path']); + expect(commandsInPanel).toEqual([ + 'isolate', + 'release', + 'processes', + 'kill-process --processName', + 'get-file --path', + ]); + expect(queryByTestId('sentineloneProcessesWindowsWarningTooltip')).toBeNull(); + }); + + it('should display warning icon on processes command if host is running on windows', () => { + commands = getEndpointConsoleCommands({ + agentType: 'sentinel_one', + endpointAgentId: '123', + endpointCapabilities: endpointMetadata.Endpoint.capabilities ?? [], + endpointPrivileges: getEndpointPrivilegesInitialStateMock(), + platform: 'windows', + }); + const { getByTestId } = render({ commands }); + consoleSelectors.openHelpPanel(); + + expect(getByTestId('sentineloneProcessesWindowsWarningTooltip')).not.toBeNull(); }); }); @@ -130,6 +155,7 @@ describe('When displaying Endpoint Response Actions', () => { endpointAgentId: '123', endpointCapabilities: endpointMetadata.Endpoint.capabilities ?? [], endpointPrivileges: getEndpointPrivilegesInitialStateMock(), + platform: 'linux', }); }); diff --git a/x-pack/plugins/security_solution/public/management/hooks/use_with_show_responder.tsx b/x-pack/plugins/security_solution/public/management/hooks/use_with_show_responder.tsx index f7622681112bd..e3e830efcb047 100644 --- a/x-pack/plugins/security_solution/public/management/hooks/use_with_show_responder.tsx +++ b/x-pack/plugins/security_solution/public/management/hooks/use_with_show_responder.tsx @@ -71,6 +71,7 @@ export const useWithShowResponder = (): ShowResponseActionsConsole => { endpointAgentId: agentId, endpointCapabilities: capabilities, endpointPrivileges, + platform, }), 'data-test-subj': `${agentType}ResponseActionsConsole`, storagePrefix: 'xpack.securitySolution.Responder', diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/hooks/use_endpoint_action_items.tsx b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/hooks/use_endpoint_action_items.tsx index bb6102e8051c4..579561573488c 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/hooks/use_endpoint_action_items.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/hooks/use_endpoint_action_items.tsx @@ -56,7 +56,7 @@ export const useEndpointActionItems = ( const endpointMetadata = endpointInfo.metadata; const isIsolated = isEndpointHostIsolated(endpointMetadata); const endpointId = endpointMetadata.agent.id; - const endpointHostName = endpointMetadata.host.hostname; + const endpointHostName = endpointMetadata.host.hostname.toLowerCase(); const fleetAgentId = endpointMetadata.elastic.agent.id; const { show, selected_endpoint: _selectedEndpoint, ...currentUrlParams } = allCurrentUrlParams; const endpointActionsPath = getEndpointDetailsPath({ diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.test.tsx b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.test.tsx index d0b05404dc16d..57b0dde41177d 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.test.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.test.tsx @@ -1306,7 +1306,7 @@ describe('when on the endpoint list page', () => { it('navigates to the Security Solution Host Details page', async () => { const hostLink = await renderResult.findByTestId('hostLink'); expect(hostLink.getAttribute('href')).toEqual( - `${APP_PATH}/hosts/${hostInfo[0].metadata.host.hostname}` + `${APP_PATH}/hosts/${hostInfo[0].metadata.host.hostname.toLowerCase()}` ); }); it('navigates to the correct Ingest Agent Policy page', async () => { diff --git a/x-pack/plugins/security_solution/public/onboarding/components/__mocks__/onboarding_context_mocks.ts b/x-pack/plugins/security_solution/public/onboarding/components/__mocks__/mocks.ts similarity index 61% rename from x-pack/plugins/security_solution/public/onboarding/components/__mocks__/onboarding_context_mocks.ts rename to x-pack/plugins/security_solution/public/onboarding/components/__mocks__/mocks.ts index dcd5d681b34bf..8947800d529c3 100644 --- a/x-pack/plugins/security_solution/public/onboarding/components/__mocks__/onboarding_context_mocks.ts +++ b/x-pack/plugins/security_solution/public/onboarding/components/__mocks__/mocks.ts @@ -14,3 +14,17 @@ export const mockReportCardOpen = jest.fn(); export const mockReportCardComplete = jest.fn(); export const mockReportCardLinkClicked = jest.fn(); + +export const telemetry = { + reportCardOpen: mockReportCardOpen, + reportCardComplete: mockReportCardComplete, + reportCardLinkClicked: mockReportCardLinkClicked, +}; +export const mockTelemetry = jest.fn(() => telemetry); + +export const onboardingContext = { + spaceId: 'default', + telemetry: mockTelemetry(), + config: new Map(), +}; +export const mockOnboardingContext = jest.fn(() => onboardingContext); diff --git a/x-pack/plugins/security_solution/public/onboarding/components/__mocks__/onboarding_context.tsx b/x-pack/plugins/security_solution/public/onboarding/components/__mocks__/onboarding_context.tsx index d1c9afcef33d6..a8b7eecf273b3 100644 --- a/x-pack/plugins/security_solution/public/onboarding/components/__mocks__/onboarding_context.tsx +++ b/x-pack/plugins/security_solution/public/onboarding/components/__mocks__/onboarding_context.tsx @@ -12,17 +12,8 @@ */ import type { OnboardingContextValue } from '../onboarding_context'; -import { - mockReportCardOpen, - mockReportCardComplete, - mockReportCardLinkClicked, -} from './onboarding_context_mocks'; +import { mockOnboardingContext } from './mocks'; export const useOnboardingContext = (): OnboardingContextValue => { - return { - spaceId: 'default', - reportCardOpen: mockReportCardOpen, - reportCardComplete: mockReportCardComplete, - reportCardLinkClicked: mockReportCardLinkClicked, - }; + return mockOnboardingContext(); }; diff --git a/x-pack/plugins/security_solution/public/onboarding/components/__snapshots__/onboarding_context.test.tsx.snap b/x-pack/plugins/security_solution/public/onboarding/components/__snapshots__/onboarding_context.test.tsx.snap new file mode 100644 index 0000000000000..07275346cda1e --- /dev/null +++ b/x-pack/plugins/security_solution/public/onboarding/components/__snapshots__/onboarding_context.test.tsx.snap @@ -0,0 +1,257 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`OnboardingContextProvider config when all requirements are met should return all topics config correctly 1`] = ` +Map { + "default" => Object { + "body": Array [ + Object { + "cards": Array [ + Object { + "id": "defaultCard1", + }, + ], + "id": "defaultGroup1", + }, + ], + "id": "default", + }, + "topic1" => Object { + "body": Array [ + Object { + "cards": Array [ + Object { + "id": "topic1Card1", + }, + ], + "id": "topic1Group1", + }, + ], + "capabilitiesRequired": Array [ + "capability1", + ], + "experimentalFlagRequired": "flag1", + "id": "topic1", + "licenseTypeRequired": "gold", + }, + "topic2" => Object { + "body": Array [ + Object { + "cards": Array [ + Object { + "experimentalFlagRequired": "flag1", + "id": "topic2Card1", + }, + Object { + "id": "topic2Card2", + "licenseTypeRequired": "gold", + }, + Object { + "capabilitiesRequired": Array [ + "capability1", + ], + "id": "topic2Card3", + }, + ], + "id": "topic2Group1", + }, + ], + "id": "topic2", + }, +} +`; + +exports[`OnboardingContextProvider config when the required capabilities are not met should filter the topics config correctly 1`] = ` +Map { + "default" => Object { + "body": Array [ + Object { + "cards": Array [ + Object { + "id": "defaultCard1", + }, + ], + "id": "defaultGroup1", + }, + ], + "id": "default", + }, + "topic2" => Object { + "body": Array [ + Object { + "cards": Array [ + Object { + "experimentalFlagRequired": "flag1", + "id": "topic2Card1", + }, + Object { + "id": "topic2Card2", + "licenseTypeRequired": "gold", + }, + ], + "id": "topic2Group1", + }, + ], + "id": "topic2", + }, +} +`; + +exports[`OnboardingContextProvider config when the required experimental flag is not met and the required license is not met either and the required capabilities are not met either should return only the default topics config 1`] = ` +Map { + "default" => Object { + "body": Array [ + Object { + "cards": Array [ + Object { + "id": "defaultCard1", + }, + ], + "id": "defaultGroup1", + }, + ], + "id": "default", + }, +} +`; + +exports[`OnboardingContextProvider config when the required experimental flag is not met and the required license is not met either should filter the topics config correctly 1`] = ` +Map { + "default" => Object { + "body": Array [ + Object { + "cards": Array [ + Object { + "id": "defaultCard1", + }, + ], + "id": "defaultGroup1", + }, + ], + "id": "default", + }, + "topic2" => Object { + "body": Array [ + Object { + "cards": Array [ + Object { + "capabilitiesRequired": Array [ + "capability1", + ], + "id": "topic2Card3", + }, + ], + "id": "topic2Group1", + }, + ], + "id": "topic2", + }, +} +`; + +exports[`OnboardingContextProvider config when the required experimental flag is not met should filter the topics config correctly 1`] = ` +Map { + "default" => Object { + "body": Array [ + Object { + "cards": Array [ + Object { + "id": "defaultCard1", + }, + ], + "id": "defaultGroup1", + }, + ], + "id": "default", + }, + "topic2" => Object { + "body": Array [ + Object { + "cards": Array [ + Object { + "id": "topic2Card2", + "licenseTypeRequired": "gold", + }, + Object { + "capabilitiesRequired": Array [ + "capability1", + ], + "id": "topic2Card3", + }, + ], + "id": "topic2Group1", + }, + ], + "id": "topic2", + }, +} +`; + +exports[`OnboardingContextProvider config when the required license is not met and the required capabilities are not met either should filter the topics config correctly 1`] = ` +Map { + "default" => Object { + "body": Array [ + Object { + "cards": Array [ + Object { + "id": "defaultCard1", + }, + ], + "id": "defaultGroup1", + }, + ], + "id": "default", + }, + "topic2" => Object { + "body": Array [ + Object { + "cards": Array [ + Object { + "experimentalFlagRequired": "flag1", + "id": "topic2Card1", + }, + ], + "id": "topic2Group1", + }, + ], + "id": "topic2", + }, +} +`; + +exports[`OnboardingContextProvider config when the required license is not met should filter the topics config correctly 1`] = ` +Map { + "default" => Object { + "body": Array [ + Object { + "cards": Array [ + Object { + "id": "defaultCard1", + }, + ], + "id": "defaultGroup1", + }, + ], + "id": "default", + }, + "topic2" => Object { + "body": Array [ + Object { + "cards": Array [ + Object { + "experimentalFlagRequired": "flag1", + "id": "topic2Card1", + }, + Object { + "capabilitiesRequired": Array [ + "capability1", + ], + "id": "topic2Card3", + }, + ], + "id": "topic2Group1", + }, + ], + "id": "topic2", + }, +} +`; diff --git a/x-pack/plugins/security_solution/public/onboarding/hooks/use_onboarding_service.ts b/x-pack/plugins/security_solution/public/onboarding/components/hooks/use_onboarding_service.ts similarity index 82% rename from x-pack/plugins/security_solution/public/onboarding/hooks/use_onboarding_service.ts rename to x-pack/plugins/security_solution/public/onboarding/components/hooks/use_onboarding_service.ts index 55f3ecb8d4aca..3d94d81530289 100644 --- a/x-pack/plugins/security_solution/public/onboarding/hooks/use_onboarding_service.ts +++ b/x-pack/plugins/security_solution/public/onboarding/components/hooks/use_onboarding_service.ts @@ -5,6 +5,6 @@ * 2.0. */ -import { useKibana } from '../../common/lib/kibana/kibana_react'; +import { useKibana } from '../../../common/lib/kibana/kibana_react'; export const useOnboardingService = () => useKibana().services.onboarding; diff --git a/x-pack/plugins/security_solution/public/onboarding/hooks/use_stored_state.ts b/x-pack/plugins/security_solution/public/onboarding/components/hooks/use_stored_state.ts similarity index 60% rename from x-pack/plugins/security_solution/public/onboarding/hooks/use_stored_state.ts rename to x-pack/plugins/security_solution/public/onboarding/components/hooks/use_stored_state.ts index eac269f3a4a35..87e22de599aae 100644 --- a/x-pack/plugins/security_solution/public/onboarding/hooks/use_stored_state.ts +++ b/x-pack/plugins/security_solution/public/onboarding/components/hooks/use_stored_state.ts @@ -6,23 +6,23 @@ */ import useLocalStorage from 'react-use/lib/useLocalStorage'; -import type { OnboardingCardId } from '../constants'; -import type { IntegrationTabId } from '../components/onboarding_body/cards/integrations/types'; +import type { OnboardingCardId } from '../../constants'; +import type { IntegrationTabId } from '../onboarding_body/cards/integrations/types'; const LocalStorageKey = { - avcBannerDismissed: 'ONBOARDING_HUB.AVC_BANNER_DISMISSED', - videoVisited: 'ONBOARDING_HUB.VIDEO_VISITED', - completeCards: 'ONBOARDING_HUB.COMPLETE_CARDS', - expandedCard: 'ONBOARDING_HUB.EXPANDED_CARD', - selectedIntegrationTabId: 'ONBOARDING_HUB.SELECTED_INTEGRATION_TAB_ID', - IntegrationSearchTerm: 'ONBOARDING_HUB.INTEGRATION_SEARCH_TERM', - IntegrationScrollTop: 'ONBOARDING_HUB.INTEGRATION_SCROLL_TOP', + avcBannerDismissed: 'securitySolution.onboarding.avcBannerDismissed', + videoVisited: 'securitySolution.onboarding.videoVisited', + completeCards: 'securitySolution.onboarding.completeCards', + expandedCard: 'securitySolution.onboarding.expandedCard', + urlDetails: 'securitySolution.onboarding.urlDetails', + selectedIntegrationTabId: 'securitySolution.onboarding.selectedIntegrationTabId', + integrationSearchTerm: 'securitySolution.onboarding.integrationSearchTerm', } as const; /** * Wrapper hook for useLocalStorage, but always returns the default value when not defined instead of `undefined`. */ -const useDefinedLocalStorage = (key: string, defaultValue: T) => { +export const useDefinedLocalStorage = (key: string, defaultValue: T) => { const [value, setValue] = useLocalStorage(key, defaultValue); return [value ?? defaultValue, setValue] as const; }; @@ -40,13 +40,10 @@ export const useStoredCompletedCardIds = (spaceId: string) => useDefinedLocalStorage(`${LocalStorageKey.completeCards}.${spaceId}`, []); /** - * Stores the expanded card ID per space + * Stores the selected topic ID per space */ -export const useStoredExpandedCardId = (spaceId: string) => - useDefinedLocalStorage( - `${LocalStorageKey.expandedCard}.${spaceId}`, - null - ); +export const useStoredUrlDetails = (spaceId: string) => + useDefinedLocalStorage(`${LocalStorageKey.urlDetails}.${spaceId}`, null); /** * Stores the selected integration tab ID per space @@ -65,6 +62,6 @@ export const useStoredIntegrationTabId = ( */ export const useStoredIntegrationSearchTerm = (spaceId: string) => useDefinedLocalStorage( - `${LocalStorageKey.IntegrationSearchTerm}.${spaceId}`, + `${LocalStorageKey.integrationSearchTerm}.${spaceId}`, null ); diff --git a/x-pack/plugins/security_solution/public/onboarding/components/hooks/use_topic_id.ts b/x-pack/plugins/security_solution/public/onboarding/components/hooks/use_topic_id.ts new file mode 100644 index 0000000000000..b20e8ae392b62 --- /dev/null +++ b/x-pack/plugins/security_solution/public/onboarding/components/hooks/use_topic_id.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 { useCallback } from 'react'; +import { useParams } from 'react-router-dom'; +import { OnboardingTopicId } from '../../constants'; +import type { OnboardingRouteParams } from '../../types'; +import { useUrlDetail } from './use_url_detail'; + +/** + * Hook that returns the topic id from the URL, or the default topic id if none is present + * This is the Single Source of Truth for the topic id + */ +export const useTopicId = (): OnboardingTopicId => { + const { topicId = OnboardingTopicId.default } = useParams(); + return topicId; +}; + +export const useTopic = (): [OnboardingTopicId, (topicId: OnboardingTopicId) => void] => { + const topicId = useTopicId(); + const { setTopicDetail } = useUrlDetail(); + + const setTopicId = useCallback( + (newTopicId: OnboardingTopicId) => { + setTopicDetail(newTopicId); + }, + [setTopicDetail] + ); + + return [topicId, setTopicId]; +}; diff --git a/x-pack/plugins/security_solution/public/onboarding/components/hooks/use_url_detail.ts b/x-pack/plugins/security_solution/public/onboarding/components/hooks/use_url_detail.ts new file mode 100644 index 0000000000000..387e9d66865b3 --- /dev/null +++ b/x-pack/plugins/security_solution/public/onboarding/components/hooks/use_url_detail.ts @@ -0,0 +1,74 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { useCallback } from 'react'; +import { SecurityPageName, useNavigateTo } from '@kbn/security-solution-navigation'; +import { useStoredUrlDetails } from './use_stored_state'; +import { OnboardingTopicId, type OnboardingCardId } from '../../constants'; +import { useOnboardingContext } from '../onboarding_context'; +import { useTopicId } from './use_topic_id'; + +export const getCardIdFromHash = (hash: string): OnboardingCardId | null => + (hash.split('?')[0].replace('#', '') as OnboardingCardId) || null; + +const setHash = (cardId: OnboardingCardId | null) => { + history.replaceState(null, '', cardId == null ? ' ' : `#${cardId}`); +}; + +const getTopicPath = (topicId: OnboardingTopicId) => + topicId !== OnboardingTopicId.default ? topicId : ''; + +const getCardHash = (cardId: OnboardingCardId | null) => (cardId ? `#${cardId}` : ''); + +/** + * This hook manages the expanded card id state in the LocalStorage and the hash in the URL. + */ +export const useUrlDetail = () => { + const { spaceId, telemetry } = useOnboardingContext(); + const topicId = useTopicId(); + const [storedUrlDetail, setStoredUrlDetail] = useStoredUrlDetails(spaceId); + + const { navigateTo } = useNavigateTo(); + + const setTopicDetail = useCallback( + (newTopicId: OnboardingTopicId) => { + const path = newTopicId === OnboardingTopicId.default ? undefined : newTopicId; + setStoredUrlDetail(path ?? null); + navigateTo({ deepLinkId: SecurityPageName.landing, path }); + }, + [setStoredUrlDetail, navigateTo] + ); + + const setCardDetail = useCallback( + (newCardId: OnboardingCardId | null) => { + setHash(newCardId); + setStoredUrlDetail(`${getTopicPath(topicId)}${getCardHash(newCardId)}` || null); + if (newCardId != null) { + telemetry.reportCardOpen(newCardId); + } + }, + [setStoredUrlDetail, topicId, telemetry] + ); + + const syncUrlDetails = useCallback( + (pathTopicId: OnboardingTopicId | null, hashCardId: OnboardingCardId | null) => { + const urlDetail = `${pathTopicId || ''}${hashCardId ? `#${hashCardId}` : ''}`; + if (urlDetail && urlDetail !== storedUrlDetail) { + if (hashCardId) { + telemetry.reportCardOpen(hashCardId, { auto: true }); + } + setStoredUrlDetail(urlDetail); + } + if (!urlDetail && storedUrlDetail) { + navigateTo({ deepLinkId: SecurityPageName.landing, path: storedUrlDetail }); + } + }, + [navigateTo, setStoredUrlDetail, storedUrlDetail, telemetry] + ); + + return { setTopicDetail, setCardDetail, syncUrlDetails }; +}; diff --git a/x-pack/plugins/security_solution/public/onboarding/common/lib/__mocks__/telemetry.ts b/x-pack/plugins/security_solution/public/onboarding/components/lib/__mocks__/telemetry.ts similarity index 100% rename from x-pack/plugins/security_solution/public/onboarding/common/lib/__mocks__/telemetry.ts rename to x-pack/plugins/security_solution/public/onboarding/components/lib/__mocks__/telemetry.ts diff --git a/x-pack/plugins/security_solution/public/onboarding/common/lib/telemetry.ts b/x-pack/plugins/security_solution/public/onboarding/components/lib/telemetry.ts similarity index 100% rename from x-pack/plugins/security_solution/public/onboarding/common/lib/telemetry.ts rename to x-pack/plugins/security_solution/public/onboarding/components/lib/telemetry.ts diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding.tsx b/x-pack/plugins/security_solution/public/onboarding/components/onboarding.tsx index 17f4840e68dc4..caa0d9f9b79d7 100644 --- a/x-pack/plugins/security_solution/public/onboarding/components/onboarding.tsx +++ b/x-pack/plugins/security_solution/public/onboarding/components/onboarding.tsx @@ -7,17 +7,23 @@ import React from 'react'; +import { Routes, Route } from '@kbn/shared-ux-router'; import { EuiSpacer, useEuiTheme } from '@elastic/eui'; import { KibanaPageTemplate } from '@kbn/shared-ux-page-kibana-template'; +import { Redirect } from 'react-router-dom'; +import { ONBOARDING_PATH } from '../../../common/constants'; import { PluginTemplateWrapper } from '../../common/components/plugin_template_wrapper'; import { CenteredLoadingSpinner } from '../../common/components/centered_loading_spinner'; import { useSpaceId } from '../../common/hooks/use_space_id'; +import { OnboardingTopicId, PAGE_CONTENT_WIDTH } from '../constants'; import { OnboardingContextProvider } from './onboarding_context'; import { OnboardingAVCBanner } from './onboarding_banner'; -import { OnboardingHeader } from './onboarding_header'; -import { OnboardingBody } from './onboarding_body'; +import { OnboardingRoute } from './onboarding_route'; import { OnboardingFooter } from './onboarding_footer'; -import { PAGE_CONTENT_WIDTH } from '../constants'; + +const topicPathParam = `:topicId(${Object.values(OnboardingTopicId) // any topics + .filter((val) => val !== OnboardingTopicId.default) // except "default" + .join('|')})?`; // optional parameter export const OnboardingPage = React.memo(() => { const spaceId = useSpaceId(); @@ -42,8 +48,14 @@ export const OnboardingPage = React.memo(() => { bottomBorder="extended" style={{ backgroundColor: euiTheme.colors.body }} > - - + + + } /> + diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_banner/onboarding_banner.tsx b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_banner/onboarding_banner.tsx index 201fae862b43c..0976dbc110cc8 100644 --- a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_banner/onboarding_banner.tsx +++ b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_banner/onboarding_banner.tsx @@ -8,7 +8,7 @@ import React, { useCallback } from 'react'; import { AVCResultsBanner2024, useIsStillYear2024 } from '@kbn/avc-banner'; -import { useStoredIsAVCBannerDismissed } from '../../hooks/use_stored_state'; +import { useStoredIsAVCBannerDismissed } from '../hooks/use_stored_state'; export const OnboardingBanner = React.memo(() => { const [isAVCBannerDismissed, setIsAVCBannerDismissed] = useStoredIsAVCBannerDismissed(); diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/body_config.ts b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/body_config.ts index 7f97b5c8eacd1..93690f98b48e8 100644 --- a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/body_config.ts +++ b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/body_config.ts @@ -12,8 +12,9 @@ import { dashboardsCardConfig } from './cards/dashboards'; import { rulesCardConfig } from './cards/rules'; import { alertsCardConfig } from './cards/alerts'; import { assistantCardConfig } from './cards/assistant'; +import { aiConnectorCardConfig } from './cards/siem_migrations/ai_connector'; -export const bodyConfig: OnboardingGroupConfig[] = [ +export const defaultBodyConfig: OnboardingGroupConfig[] = [ { title: i18n.translate('xpack.securitySolution.onboarding.dataGroup.title', { defaultMessage: 'Ingest your data', @@ -34,3 +35,12 @@ export const bodyConfig: OnboardingGroupConfig[] = [ cards: [assistantCardConfig], }, ]; + +export const siemMigrationsBodyConfig: OnboardingGroupConfig[] = [ + { + title: i18n.translate('xpack.securitySolution.onboarding.configure.title', { + defaultMessage: 'Configure', + }), + cards: [aiConnectorCardConfig], + }, +]; diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/alerts/alerts_card.test.tsx b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/alerts/alerts_card.test.tsx index 3e83bcb851f82..4fec865e36f24 100644 --- a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/alerts/alerts_card.test.tsx +++ b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/alerts/alerts_card.test.tsx @@ -14,6 +14,7 @@ const props = { checkComplete: jest.fn(), isCardComplete: jest.fn(), setExpandedCardId: jest.fn(), + isCardAvailable: jest.fn(), }; describe('AlertsCard', () => { @@ -31,7 +32,8 @@ describe('AlertsCard', () => { expect(getByTestId('alertsCardDescription')).toBeInTheDocument(); }); - it('card callout should be rendered if integrations cards is not complete', () => { + it('card callout should be rendered if integrations card is available but not complete', () => { + props.isCardAvailable.mockReturnValueOnce(true); props.isCardComplete.mockReturnValueOnce(false); const { getByText } = render( @@ -43,7 +45,20 @@ describe('AlertsCard', () => { expect(getByText('To view alerts add integrations first.')).toBeInTheDocument(); }); - it('card button should be disabled if integrations cards is not complete', () => { + it('card callout should not be rendered if integrations card is not available', () => { + props.isCardAvailable.mockReturnValueOnce(false); + + const { queryByText } = render( + + + + ); + + expect(queryByText('To view alerts add integrations first.')).not.toBeInTheDocument(); + }); + + it('card button should be disabled if integrations card is available but not complete', () => { + props.isCardAvailable.mockReturnValueOnce(true); props.isCardComplete.mockReturnValueOnce(false); const { getByTestId } = render( @@ -54,4 +69,17 @@ describe('AlertsCard', () => { expect(getByTestId('alertsCardButton').querySelector('button')).toBeDisabled(); }); + + it('card button should be enabled if integrations card is complete', () => { + props.isCardAvailable.mockReturnValueOnce(true); + props.isCardComplete.mockReturnValueOnce(true); + + const { getByTestId } = render( + + + + ); + + expect(getByTestId('alertsCardButton').querySelector('button')).not.toBeDisabled(); + }); }); diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/alerts/alerts_card.tsx b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/alerts/alerts_card.tsx index 85d3994d44530..bdcf662a5643c 100644 --- a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/alerts/alerts_card.tsx +++ b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/alerts/alerts_card.tsx @@ -6,22 +6,14 @@ */ import React, { useCallback, useMemo } from 'react'; -import { - EuiFlexGroup, - EuiFlexItem, - EuiIcon, - EuiLink, - EuiSpacer, - EuiText, - useEuiTheme, - COLOR_MODES_STANDARD, -} from '@elastic/eui'; +import { EuiFlexGroup, EuiFlexItem, EuiIcon, EuiLink, EuiSpacer } from '@elastic/eui'; import { SecurityPageName } from '@kbn/security-solution-navigation'; import { SecuritySolutionLinkButton } from '../../../../../common/components/links'; import { OnboardingCardId } from '../../../../constants'; import type { OnboardingCardComponent } from '../../../../types'; import { OnboardingCardContentImagePanel } from '../common/card_content_image_panel'; import { CardCallOut } from '../common/card_callout'; +import { CardSubduedText } from '../common/card_subdued_text'; import alertsImageSrc from './images/alerts.png'; import * as i18n from './translations'; @@ -29,15 +21,18 @@ export const AlertsCard: OnboardingCardComponent = ({ isCardComplete, setExpandedCardId, setComplete, + isCardAvailable, }) => { - const { colorMode } = useEuiTheme(); - const isDarkMode = colorMode === COLOR_MODES_STANDARD.dark; - const isIntegrationsCardComplete = useMemo( () => isCardComplete(OnboardingCardId.integrations), [isCardComplete] ); + const isIntegrationsCardAvailable = useMemo( + () => isCardAvailable(OnboardingCardId.integrations), + [isCardAvailable] + ); + const expandIntegrationsCard = useCallback(() => { setExpandedCardId(OnboardingCardId.integrations, { scroll: true }); }, [setExpandedCardId]); @@ -51,14 +46,10 @@ export const AlertsCard: OnboardingCardComponent = ({ alignItems="flexStart" > - + {i18n.ALERTS_CARD_DESCRIPTION} - - {!isIntegrationsCardComplete && ( + + {isIntegrationsCardAvailable && !isIntegrationsCardComplete && ( <> setComplete(true)} deepLinkId={SecurityPageName.alerts} fill - isDisabled={!isIntegrationsCardComplete} + isDisabled={isIntegrationsCardAvailable && !isIntegrationsCardComplete} > {i18n.ALERTS_CARD_VIEW_ALERTS_BUTTON} diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/assistant/assistant_card.tsx b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/assistant/assistant_card.tsx index b728606937020..c971bd2a6f0b7 100644 --- a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/assistant/assistant_card.tsx +++ b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/assistant/assistant_card.tsx @@ -6,39 +6,35 @@ */ import React, { useCallback, useMemo } from 'react'; -import { - EuiCallOut, - EuiFlexGroup, - EuiFlexItem, - EuiIcon, - EuiLink, - EuiText, - useEuiTheme, - COLOR_MODES_STANDARD, -} from '@elastic/eui'; +import { EuiFlexGroup, EuiFlexItem, EuiIcon, EuiLink } from '@elastic/eui'; import { css } from '@emotion/css'; import { OnboardingCardId } from '../../../../constants'; import type { OnboardingCardComponent } from '../../../../types'; import * as i18n from './translations'; import { OnboardingCardContentPanel } from '../common/card_content_panel'; -import { ConnectorCards } from './connectors/connector_cards'; +import { ConnectorCards } from '../common/connectors/connector_cards'; import { CardCallOut } from '../common/card_callout'; +import { CardSubduedText } from '../common/card_subdued_text'; import type { AssistantCardMetadata } from './types'; -import { MissingPrivilegesDescription } from './connectors/missing_privileges_tooltip'; +import { MissingPrivilegesCallOut } from '../common/connectors/missing_privileges'; export const AssistantCard: OnboardingCardComponent = ({ isCardComplete, setExpandedCardId, checkCompleteMetadata, checkComplete, + isCardAvailable, }) => { - const { euiTheme, colorMode } = useEuiTheme(); - const isDarkMode = colorMode === COLOR_MODES_STANDARD.dark; const isIntegrationsCardComplete = useMemo( () => isCardComplete(OnboardingCardId.integrations), [isCardComplete] ); + const isIntegrationsCardAvailable = useMemo( + () => isCardAvailable(OnboardingCardId.integrations), + [isCardAvailable] + ); + const expandIntegrationsCard = useCallback(() => { setExpandedCardId(OnboardingCardId.integrations, { scroll: true }); }, [setExpandedCardId]); @@ -48,27 +44,14 @@ export const AssistantCard: OnboardingCardComponent = ({ const canCreateConnectors = checkCompleteMetadata?.canCreateConnectors; return ( - + {canExecuteConnectors ? ( - - {i18n.ASSISTANT_CARD_DESCRIPTION} - + {i18n.ASSISTANT_CARD_DESCRIPTION} - {isIntegrationsCardComplete ? ( - - ) : ( + {isIntegrationsCardAvailable && !isIntegrationsCardComplete ? ( = ({ } /> + ) : ( + )} ) : ( - - - + )} ); diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/assistant/assistant_check_complete.ts b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/assistant/assistant_check_complete.ts index 8c0d029cee583..6242eb02bd540 100644 --- a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/assistant/assistant_check_complete.ts +++ b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/assistant/assistant_check_complete.ts @@ -9,7 +9,7 @@ import { loadAllActions as loadConnectors } from '@kbn/triggers-actions-ui-plugi import type { AIConnector } from '@kbn/elastic-assistant/impl/connectorland/connector_selector'; import { i18n } from '@kbn/i18n'; import type { OnboardingCardCheckComplete } from '../../../../types'; -import { AllowedActionTypeIds } from './constants'; +import { AIActionTypeIds } from '../common/connectors/constants'; import type { AssistantCardMetadata } from './types'; export const checkAssistantCardComplete: OnboardingCardCheckComplete< @@ -21,7 +21,7 @@ export const checkAssistantCardComplete: OnboardingCardCheckComplete< } = application; const aiConnectors = allConnectors.reduce((acc: AIConnector[], connector) => { - if (!connector.isMissingSecrets && AllowedActionTypeIds.includes(connector.actionTypeId)) { + if (!connector.isMissingSecrets && AIActionTypeIds.includes(connector.actionTypeId)) { acc.push(connector); } return acc; diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/assistant/connectors/connector_cards.tsx b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/assistant/connectors/connector_cards.tsx deleted file mode 100644 index 472459b631b0a..0000000000000 --- a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/assistant/connectors/connector_cards.tsx +++ /dev/null @@ -1,118 +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 AIConnector } from '@kbn/elastic-assistant/impl/connectorland/connector_selector'; -import { - EuiFlexGroup, - EuiFlexItem, - EuiPanel, - EuiLoadingSpinner, - EuiText, - EuiBadge, - EuiSpacer, - EuiCallOut, -} from '@elastic/eui'; -import { css } from '@emotion/css'; -import { useKibana } from '../../../../../../common/lib/kibana'; -import { CreateConnectorPopover } from './create_connector_popover'; -import { ConnectorSetup } from './connector_setup'; -import * as i18n from './translations'; -import { MissingPrivilegesDescription } from './missing_privileges_tooltip'; - -interface ConnectorCardsProps { - connectors?: AIConnector[]; - onConnectorSaved: () => void; - canCreateConnectors?: boolean; -} - -export const ConnectorCards = React.memo( - ({ connectors, onConnectorSaved, canCreateConnectors }) => { - const { - triggersActionsUi: { actionTypeRegistry }, - } = useKibana().services; - - if (!connectors) { - return ; - } - - const hasConnectors = connectors.length > 0; - - // show callout when user is missing actions.save privilege - if (!hasConnectors && !canCreateConnectors) { - return ( - - - - ); - } - - return ( - <> - {hasConnectors ? ( - <> - - - - - ) : ( - - )} - - ); - } -); -ConnectorCards.displayName = 'ConnectorCards'; - -interface ConnectorListProps { - connectors: AIConnector[]; - actionTypeRegistry: ReturnType< - typeof useKibana - >['services']['triggersActionsUi']['actionTypeRegistry']; -} - -const ConnectorList = React.memo(({ connectors, actionTypeRegistry }) => ( - - {connectors.map((connector) => ( - - - - - {connector.name} - - - - {actionTypeRegistry.get(connector.actionTypeId).actionTypeTitle} - - - - - - ))} - -)); - -ConnectorList.displayName = 'ConnectorList'; diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/assistant/constants.ts b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/assistant/constants.ts deleted file mode 100644 index 35811c18de471..0000000000000 --- a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/assistant/constants.ts +++ /dev/null @@ -1,8 +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. - */ - -export const AllowedActionTypeIds = ['.bedrock', '.gen-ai', '.gemini']; diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/assistant/index.ts b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/assistant/index.ts index fedf975052327..4850b1ee2d865 100644 --- a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/assistant/index.ts +++ b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/assistant/index.ts @@ -25,8 +25,6 @@ export const assistantCardConfig: OnboardingCardConfig = ) ), checkComplete: checkAssistantCardComplete, - // Both capabilities are needed for this card, so we should use a double array to create an AND conditional - // (a single array would create an OR conditional between them) - capabilities: [['securitySolutionAssistant.ai-assistant']], - licenseType: 'enterprise', + capabilitiesRequired: ['securitySolutionAssistant.ai-assistant'], + licenseTypeRequired: 'enterprise', }; diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/assistant/translations.ts b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/assistant/translations.ts index de3c111280436..1c526d4974a9a 100644 --- a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/assistant/translations.ts +++ b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/assistant/translations.ts @@ -35,17 +35,3 @@ export const ASSISTANT_CARD_CALLOUT_INTEGRATIONS_BUTTON = i18n.translate( defaultMessage: 'Add integrations step', } ); - -export const ASSISTANT_CARD_CREATE_NEW_CONNECTOR_POPOVER = i18n.translate( - 'xpack.securitySolution.onboarding.assistantCard.createNewConnectorPopover', - { - defaultMessage: 'Create new connector', - } -); - -export const PRIVILEGES_MISSING_TITLE = i18n.translate( - 'xpack.securitySolution.onboarding.assistantCard.callout.title', - { - defaultMessage: 'Missing privileges', - } -); diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/attack_discovery/attack_discover_card.test.tsx b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/attack_discovery/attack_discover_card.test.tsx index 19b327f77487c..c28ae75b92c71 100644 --- a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/attack_discovery/attack_discover_card.test.tsx +++ b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/attack_discovery/attack_discover_card.test.tsx @@ -14,6 +14,7 @@ const props = { checkComplete: jest.fn(), isCardComplete: jest.fn(), setExpandedCardId: jest.fn(), + isCardAvailable: jest.fn(), }; describe('RulesCard', () => { diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/attack_discovery/index.ts b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/attack_discovery/index.ts index 3e174caa27157..beec64bd90782 100644 --- a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/attack_discovery/index.ts +++ b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/attack_discovery/index.ts @@ -22,6 +22,6 @@ export const attackDiscoveryCardConfig: OnboardingCardConfig = { './attack_discovery_card' ) ), - capabilities: 'securitySolutionAttackDiscovery.attack-discovery', - licenseType: 'enterprise', + capabilitiesRequired: 'securitySolutionAttackDiscovery.attack-discovery', + licenseTypeRequired: 'enterprise', }; diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/common/card_content_image_panel.styles.ts b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/common/card_content_image_panel.styles.ts index c7998135aa8ae..2260b95ab9442 100644 --- a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/common/card_content_image_panel.styles.ts +++ b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/common/card_content_image_panel.styles.ts @@ -6,15 +6,12 @@ */ import { css } from '@emotion/css'; -import { useEuiTheme, useEuiShadow, COLOR_MODES_STANDARD } from '@elastic/eui'; +import { useEuiTheme, useEuiShadow } from '@elastic/eui'; export const useCardContentImagePanelStyles = () => { - const { euiTheme, colorMode } = useEuiTheme(); + const { euiTheme } = useEuiTheme(); const shadowStyles = useEuiShadow('m'); - const isDarkMode = colorMode === COLOR_MODES_STANDARD.dark; return css` - padding-top: 8px; - ${isDarkMode ? `background-color: ${euiTheme.colors.lightestShade}` : ''}; .cardSpacer { width: 8%; } diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/common/card_content_panel.styles.ts b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/common/card_content_panel.styles.ts new file mode 100644 index 0000000000000..7d0fcf831e4e4 --- /dev/null +++ b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/common/card_content_panel.styles.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 { css } from '@emotion/css'; +import { COLOR_MODES_STANDARD, useEuiTheme } from '@elastic/eui'; +import { useDarkPanelStyles } from '../../onboarding_card_panel.styles'; + +export const NESTED_PANEL_CLASS_NAME = 'onboardingCardContentPanelNested'; + +export const useCardContentPanelStyles = () => { + const { euiTheme, colorMode } = useEuiTheme(); + const darkPanelStyles = useDarkPanelStyles(colorMode === COLOR_MODES_STANDARD.dark); + + return css` + padding-top: 0; + ${darkPanelStyles} + + .${NESTED_PANEL_CLASS_NAME} { + padding-top: ${euiTheme.size.s}; + ${darkPanelStyles} + } + `; +}; diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/common/card_content_panel.tsx b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/common/card_content_panel.tsx index 3d5489b9be1cc..be1b01fc77081 100644 --- a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/common/card_content_panel.tsx +++ b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/common/card_content_panel.tsx @@ -5,24 +5,19 @@ * 2.0. */ import React, { type PropsWithChildren } from 'react'; -import { COLOR_MODES_STANDARD, EuiPanel, useEuiTheme, type EuiPanelProps } from '@elastic/eui'; -import { css } from '@emotion/react'; +import { EuiPanel, type EuiPanelProps } from '@elastic/eui'; +import classnames from 'classnames'; +import { useCardContentPanelStyles, NESTED_PANEL_CLASS_NAME } from './card_content_panel.styles'; export const OnboardingCardContentPanel = React.memo>( - ({ children, ...panelProps }) => { - const { euiTheme, colorMode } = useEuiTheme(); - const isDarkMode = colorMode === COLOR_MODES_STANDARD.dark; + ({ children, className, ...panelProps }) => { + const styles = useCardContentPanelStyles(); + const panelClassName = classnames(styles); + const nestedClassName = classnames(NESTED_PANEL_CLASS_NAME, className); + return ( - - + + {children} diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/common/card_link_button.tsx b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/common/card_link_button.tsx index 96466466ee4a8..35254b45968f5 100644 --- a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/common/card_link_button.tsx +++ b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/common/card_link_button.tsx @@ -19,13 +19,13 @@ export const withReportCardLinkClick = ): React.FC => React.memo(function WithReportCardLinkClick({ onClick, cardId, linkId, ...rest }) { - const { reportCardLinkClicked } = useOnboardingContext(); + const { telemetry } = useOnboardingContext(); const onClickWithReport = useCallback( (ev) => { - reportCardLinkClicked(cardId, linkId); + telemetry.reportCardLinkClicked(cardId, linkId); onClick?.(ev); }, - [reportCardLinkClicked, cardId, linkId, onClick] + [telemetry, cardId, linkId, onClick] ); return ; }); diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/common/card_subdued_text.tsx b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/common/card_subdued_text.tsx new file mode 100644 index 0000000000000..6e022b639204e --- /dev/null +++ b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/common/card_subdued_text.tsx @@ -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 React, { type PropsWithChildren } from 'react'; +import { EuiText, useEuiTheme, COLOR_MODES_STANDARD, type EuiTextProps } from '@elastic/eui'; + +export type CardSubduedTextProps = PropsWithChildren; +export const CardSubduedText = React.memo(({ children, ...props }) => { + const { colorMode } = useEuiTheme(); + const isDarkMode = colorMode === COLOR_MODES_STANDARD.dark; + return ( + + {children} + + ); +}); +CardSubduedText.displayName = 'CardSubduedText'; diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/common/connectors/connector_cards.tsx b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/common/connectors/connector_cards.tsx new file mode 100644 index 0000000000000..b8b51198c75ff --- /dev/null +++ b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/common/connectors/connector_cards.tsx @@ -0,0 +1,153 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor 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, { useCallback } from 'react'; +import { type AIConnector } from '@kbn/elastic-assistant/impl/connectorland/connector_selector'; +import { + EuiFlexGroup, + EuiFlexItem, + EuiPanel, + EuiLoadingSpinner, + EuiText, + EuiBadge, + EuiSpacer, + EuiCallOut, + useEuiTheme, +} from '@elastic/eui'; +import { css } from '@emotion/css'; +import { useKibana } from '../../../../../../common/lib/kibana'; +import { + CreateConnectorPopover, + type CreateConnectorPopoverProps, +} from './create_connector_popover'; +import { ConnectorSetup } from './connector_setup'; +import * as i18n from './translations'; +import { MissingPrivilegesDescription } from './missing_privileges'; + +interface ConnectorCardsProps + extends CreateConnectorPopoverProps, + Omit { + connectors?: AIConnector[]; // make connectors optional to handle loading state +} + +export const ConnectorCards = React.memo( + ({ + connectors, + onConnectorSaved, + canCreateConnectors, + selectedConnectorId, + setSelectedConnectorId, + }) => { + if (!connectors) { + return ; + } + + const hasConnectors = connectors.length > 0; + + // show callout when user is missing actions.save privilege + if (!hasConnectors && !canCreateConnectors) { + return ( + + + + ); + } + + return ( + <> + {hasConnectors ? ( + <> + + + + + ) : ( + + )} + + ); + } +); +ConnectorCards.displayName = 'ConnectorCards'; + +interface ConnectorListProps { + connectors: AIConnector[]; + selectedConnectorId?: string | null; + setSelectedConnectorId?: (id: string) => void; +} + +const ConnectorList = React.memo( + ({ connectors, selectedConnectorId, setSelectedConnectorId }) => { + const { euiTheme } = useEuiTheme(); + const { actionTypeRegistry } = useKibana().services.triggersActionsUi; + const onConnectorClick = useCallback( + (id: string) => { + setSelectedConnectorId?.(id); + }, + [setSelectedConnectorId] + ); + + const selectedCss = `border: 2px solid ${euiTheme.colors.primary};`; + + return ( + + {connectors.map((connector) => ( + + onConnectorClick(connector.id) : undefined} + css={css` + ${selectedConnectorId === connector.id ? selectedCss : ''} + `} + color={selectedConnectorId === connector.id ? 'primary' : 'plain'} + > + + + {connector.name} + + + + {actionTypeRegistry.get(connector.actionTypeId).actionTypeTitle} + + + + + + ))} + + ); + } +); + +ConnectorList.displayName = 'ConnectorList'; diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/assistant/connectors/connector_setup.tsx b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/common/connectors/connector_setup.tsx similarity index 100% rename from x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/assistant/connectors/connector_setup.tsx rename to x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/common/connectors/connector_setup.tsx diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/common/connectors/constants.ts b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/common/connectors/constants.ts new file mode 100644 index 0000000000000..5c9c94e369854 --- /dev/null +++ b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/common/connectors/constants.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 const AIActionTypeIds = ['.bedrock', '.gen-ai', '.gemini']; diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/assistant/connectors/create_connector_popover.tsx b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/common/connectors/create_connector_popover.tsx similarity index 94% rename from x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/assistant/connectors/create_connector_popover.tsx rename to x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/common/connectors/create_connector_popover.tsx index 32bcd66f49249..c6c378fc8e29f 100644 --- a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/assistant/connectors/create_connector_popover.tsx +++ b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/common/connectors/create_connector_popover.tsx @@ -9,9 +9,9 @@ import { css } from '@emotion/css'; import { EuiPopover, EuiLink, EuiText } from '@elastic/eui'; import { ConnectorSetup } from './connector_setup'; import * as i18n from './translations'; -import { MissingPrivilegesTooltip } from './missing_privileges_tooltip'; +import { MissingPrivilegesTooltip } from './missing_privileges'; -interface CreateConnectorPopoverProps { +export interface CreateConnectorPopoverProps { onConnectorSaved: () => void; canCreateConnectors?: boolean; } diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/assistant/connectors/hooks/use_load_action_types.ts b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/common/connectors/hooks/use_load_action_types.ts similarity index 81% rename from x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/assistant/connectors/hooks/use_load_action_types.ts rename to x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/common/connectors/hooks/use_load_action_types.ts index 5bdee57baafc0..48b8fdfc20d59 100644 --- a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/assistant/connectors/hooks/use_load_action_types.ts +++ b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/common/connectors/hooks/use_load_action_types.ts @@ -9,9 +9,9 @@ import { useMemo } from 'react'; import { useLoadActionTypes as loadActionTypes } from '@kbn/elastic-assistant/impl/connectorland/use_load_action_types'; import type { HttpSetup } from '@kbn/core-http-browser'; import type { IToasts } from '@kbn/core-notifications-browser'; -import { AllowedActionTypeIds } from '../../constants'; +import { AIActionTypeIds } from '../constants'; export const useFilteredActionTypes = (http: HttpSetup, toasts: IToasts) => { const { data } = loadActionTypes({ http, toasts }); - return useMemo(() => data?.filter(({ id }) => AllowedActionTypeIds.includes(id)), [data]); + return useMemo(() => data?.filter(({ id }) => AIActionTypeIds.includes(id)), [data]); }; diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/assistant/connectors/missing_privileges_tooltip.tsx b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/common/connectors/missing_privileges.tsx similarity index 78% rename from x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/assistant/connectors/missing_privileges_tooltip.tsx rename to x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/common/connectors/missing_privileges.tsx index 811ef72d67634..40e211d857680 100644 --- a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/assistant/connectors/missing_privileges_tooltip.tsx +++ b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/common/connectors/missing_privileges.tsx @@ -5,13 +5,29 @@ * 2.0. */ import React from 'react'; -import { EuiCode, EuiFlexGroup, EuiFlexItem, EuiToolTip } from '@elastic/eui'; +import { EuiCallOut, EuiCode, EuiFlexGroup, EuiFlexItem, EuiToolTip } from '@elastic/eui'; import * as i18n from './translations'; +export const MissingPrivilegesDescription = React.memo(() => { + return ( + + {i18n.PRIVILEGES_REQUIRED_TITLE} + + +
          +
        • {i18n.REQUIRED_PRIVILEGES_CONNECTORS_ALL}
        • +
        +
        +
        + {i18n.CONTACT_ADMINISTRATOR} +
        + ); +}); +MissingPrivilegesDescription.displayName = 'MissingPrivilegesDescription'; + interface MissingPrivilegesTooltip { children: React.ReactElement; // EuiToolTip requires a single ReactElement child } - export const MissingPrivilegesTooltip = React.memo(({ children }) => ( (({ )); MissingPrivilegesTooltip.displayName = 'MissingPrivilegesTooltip'; -export const MissingPrivilegesDescription = React.memo(() => { +export const MissingPrivilegesCallOut = React.memo(() => { return ( - - {i18n.PRIVILEGES_REQUIRED_TITLE} - - -
          -
        • {i18n.REQUIRED_PRIVILEGES_CONNECTORS_ALL}
        • -
        -
        -
        - {i18n.CONTACT_ADMINISTRATOR} -
        + + + ); }); -MissingPrivilegesDescription.displayName = 'MissingPrivilegesDescription'; +MissingPrivilegesCallOut.displayName = 'MissingPrivilegesCallOut'; diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/assistant/connectors/translations.ts b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/common/connectors/translations.ts similarity index 100% rename from x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/assistant/connectors/translations.ts rename to x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/common/connectors/translations.ts diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/dashboards/dashboards_card.test.tsx b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/dashboards/dashboards_card.test.tsx index f7aa198eccab4..d654fd9ca5a08 100644 --- a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/dashboards/dashboards_card.test.tsx +++ b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/dashboards/dashboards_card.test.tsx @@ -17,9 +17,10 @@ const props = { checkComplete: jest.fn(), isCardComplete: jest.fn(), setExpandedCardId: jest.fn(), + isCardAvailable: jest.fn(), }; -describe('RulesCard', () => { +describe('DashboardsCard', () => { beforeEach(() => { jest.clearAllMocks(); }); @@ -34,7 +35,8 @@ describe('RulesCard', () => { expect(getByTestId('dashboardsDescription')).toBeInTheDocument(); }); - it('card callout should be rendered if integrations cards is not complete', () => { + it('card callout should be rendered if integrations card is available but not complete', () => { + props.isCardAvailable.mockReturnValueOnce(true); props.isCardComplete.mockReturnValueOnce(false); const { getByText } = render( @@ -46,7 +48,20 @@ describe('RulesCard', () => { expect(getByText('To view dashboards add integrations first.')).toBeInTheDocument(); }); - it('card button should be disabled if integrations cards is not complete', () => { + it('card callout should not be rendered if integrations card is not available', () => { + props.isCardAvailable.mockReturnValueOnce(false); + + const { queryByText } = render( + + + + ); + + expect(queryByText('To view dashboards add integrations first.')).not.toBeInTheDocument(); + }); + + it('card button should be disabled if integrations card is available but not complete', () => { + props.isCardAvailable.mockReturnValueOnce(true); props.isCardComplete.mockReturnValueOnce(false); const { getByTestId } = render( @@ -57,7 +72,22 @@ describe('RulesCard', () => { expect(getByTestId('dashboardsCardButton').querySelector('button')).toBeDisabled(); }); + + it('card button should be enabled if integrations card is complete', () => { + props.isCardAvailable.mockReturnValueOnce(true); + props.isCardComplete.mockReturnValueOnce(true); + + const { getByTestId } = render( + + + + ); + + expect(getByTestId('dashboardsCardButton').querySelector('button')).not.toBeDisabled(); + }); + it('should expand integrations card when callout link is clicked', () => { + props.isCardAvailable.mockReturnValueOnce(true); props.isCardComplete.mockReturnValueOnce(false); // To show the callout const { getByTestId } = render( diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/dashboards/dashboards_card.tsx b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/dashboards/dashboards_card.tsx index 201aa4f0d3150..db7f6dc9a1f7f 100644 --- a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/dashboards/dashboards_card.tsx +++ b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/dashboards/dashboards_card.tsx @@ -6,22 +6,14 @@ */ import React, { useCallback, useMemo } from 'react'; -import { - EuiFlexGroup, - EuiFlexItem, - EuiIcon, - EuiLink, - EuiSpacer, - EuiText, - useEuiTheme, - COLOR_MODES_STANDARD, -} from '@elastic/eui'; +import { EuiFlexGroup, EuiFlexItem, EuiIcon, EuiLink, EuiSpacer } from '@elastic/eui'; import { SecurityPageName } from '@kbn/security-solution-navigation'; import { OnboardingCardId } from '../../../../constants'; import type { OnboardingCardComponent } from '../../../../types'; import { OnboardingCardContentImagePanel } from '../common/card_content_image_panel'; import { CardCallOut } from '../common/card_callout'; import { CardLinkButton } from '../common/card_link_button'; +import { CardSubduedText } from '../common/card_subdued_text'; import dashboardsImageSrc from './images/dashboards.png'; import * as i18n from './translations'; @@ -29,15 +21,18 @@ export const DashboardsCard: OnboardingCardComponent = ({ isCardComplete, setComplete, setExpandedCardId, + isCardAvailable, }) => { - const { colorMode } = useEuiTheme(); - const isDarkMode = colorMode === COLOR_MODES_STANDARD.dark; - const isIntegrationsCardComplete = useMemo( () => isCardComplete(OnboardingCardId.integrations), [isCardComplete] ); + const isIntegrationsCardAvailable = useMemo( + () => isCardAvailable(OnboardingCardId.integrations), + [isCardAvailable] + ); + const expandIntegrationsCard = useCallback(() => { setExpandedCardId(OnboardingCardId.integrations, { scroll: true }); }, [setExpandedCardId]); @@ -54,14 +49,10 @@ export const DashboardsCard: OnboardingCardComponent = ({ alignItems="flexStart" > - + {i18n.DASHBOARDS_CARD_DESCRIPTION} - - {!isIntegrationsCardComplete && ( + + {isIntegrationsCardAvailable && !isIntegrationsCardComplete && ( <> {i18n.DASHBOARDS_CARD_GO_TO_DASHBOARDS_BUTTON} diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/dashboards/index.ts b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/dashboards/index.ts index 356b15f50bf9b..6d9bce2e34904 100644 --- a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/dashboards/index.ts +++ b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/dashboards/index.ts @@ -22,5 +22,5 @@ export const dashboardsCardConfig: OnboardingCardConfig = { './dashboards_card' ) ), - capabilities: ['dashboard.show'], + capabilitiesRequired: ['dashboard.show'], }; diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations/callouts/agent_required_callout.test.tsx b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations/callouts/agent_required_callout.test.tsx index 53e8b6c34e8f2..4f5ae2f919d66 100644 --- a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations/callouts/agent_required_callout.test.tsx +++ b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations/callouts/agent_required_callout.test.tsx @@ -14,10 +14,10 @@ import React from 'react'; import { render } from '@testing-library/react'; import { AgentRequiredCallout } from './agent_required_callout'; import { TestProviders } from '../../../../../../common/mock/test_providers'; -import { trackOnboardingLinkClick } from '../../../../../common/lib/telemetry'; +import { trackOnboardingLinkClick } from '../../../../lib/telemetry'; jest.mock('../../../../../../common/lib/kibana'); -jest.mock('../../../../../common/lib/telemetry'); +jest.mock('../../../../lib/telemetry'); describe('AgentRequiredCallout', () => { beforeEach(() => { diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations/callouts/agent_required_callout.tsx b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations/callouts/agent_required_callout.tsx index b1d18b138487b..763dfe749adba 100644 --- a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations/callouts/agent_required_callout.tsx +++ b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations/callouts/agent_required_callout.tsx @@ -12,7 +12,7 @@ import { LinkAnchor } from '../../../../../../common/components/links'; import { CardCallOut } from '../../common/card_callout'; import { useNavigation } from '../../../../../../common/lib/kibana'; import { FLEET_APP_ID, ADD_AGENT_PATH, TELEMETRY_AGENT_REQUIRED } from '../constants'; -import { trackOnboardingLinkClick } from '../../../../../common/lib/telemetry'; +import { trackOnboardingLinkClick } from '../../../../lib/telemetry'; const fleetAgentLinkProps = { appId: FLEET_APP_ID, path: ADD_AGENT_PATH }; diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations/callouts/agentless_available_callout.test.tsx b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations/callouts/agentless_available_callout.test.tsx index 7cd3b60c0c6ed..e761381747f46 100644 --- a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations/callouts/agentless_available_callout.test.tsx +++ b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations/callouts/agentless_available_callout.test.tsx @@ -10,10 +10,10 @@ import React from 'react'; import { TestProviders } from '../../../../../../common/mock/test_providers'; import { AgentlessAvailableCallout } from './agentless_available_callout'; import { useKibana } from '../../../../../../common/lib/kibana'; -import { trackOnboardingLinkClick } from '../../../../../common/lib/telemetry'; +import { trackOnboardingLinkClick } from '../../../../lib/telemetry'; jest.mock('../../../../../../common/lib/kibana'); -jest.mock('../../../../../common/lib/telemetry'); +jest.mock('../../../../lib/telemetry'); describe('AgentlessAvailableCallout', () => { const mockUseKibana = useKibana as jest.Mock; diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations/callouts/agentless_available_callout.tsx b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations/callouts/agentless_available_callout.tsx index eaf8cbaa3b287..81c4db22f39ab 100644 --- a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations/callouts/agentless_available_callout.tsx +++ b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations/callouts/agentless_available_callout.tsx @@ -12,7 +12,7 @@ import { css } from '@emotion/react'; import { useKibana } from '../../../../../../common/lib/kibana'; import { LinkAnchor } from '../../../../../../common/components/links'; -import { trackOnboardingLinkClick } from '../../../../../common/lib/telemetry'; +import { trackOnboardingLinkClick } from '../../../../lib/telemetry'; import { CardCallOut } from '../../common/card_callout'; import { TELEMETRY_AGENTLESS_LEARN_MORE } from '../constants'; diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations/callouts/endpoint_callout.test.tsx b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations/callouts/endpoint_callout.test.tsx index 50ac060eba241..7d89003359743 100644 --- a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations/callouts/endpoint_callout.test.tsx +++ b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations/callouts/endpoint_callout.test.tsx @@ -14,10 +14,10 @@ import React from 'react'; import { render } from '@testing-library/react'; import { EndpointCallout } from './endpoint_callout'; import { TestProviders } from '../../../../../../common/mock/test_providers'; -import { trackOnboardingLinkClick } from '../../../../../common/lib/telemetry'; +import { trackOnboardingLinkClick } from '../../../../lib/telemetry'; jest.mock('../../../../../../common/lib/kibana'); -jest.mock('../../../../../common/lib/telemetry'); +jest.mock('../../../../lib/telemetry'); describe('EndpointCallout', () => { beforeEach(() => { diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations/callouts/endpoint_callout.tsx b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations/callouts/endpoint_callout.tsx index d5b0199c9f401..b761a17901a38 100644 --- a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations/callouts/endpoint_callout.tsx +++ b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations/callouts/endpoint_callout.tsx @@ -13,7 +13,7 @@ import { css } from '@emotion/react'; import { useKibana } from '../../../../../../common/lib/kibana/kibana_react'; import { LinkAnchor } from '../../../../../../common/components/links'; import { CardCallOut } from '../../common/card_callout'; -import { trackOnboardingLinkClick } from '../../../../../common/lib/telemetry'; +import { trackOnboardingLinkClick } from '../../../../lib/telemetry'; import { TELEMETRY_ENDPOINT_LEARN_MORE } from '../constants'; export const EndpointCallout = React.memo(() => { diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations/callouts/integration_card_top_callout.test.tsx b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations/callouts/integration_card_top_callout.test.tsx index e0aedafe45595..9cf346aeed901 100644 --- a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations/callouts/integration_card_top_callout.test.tsx +++ b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations/callouts/integration_card_top_callout.test.tsx @@ -9,10 +9,10 @@ import React from 'react'; import { render, waitFor } from '@testing-library/react'; import { of } from 'rxjs'; import { IntegrationCardTopCallout } from './integration_card_top_callout'; -import { useOnboardingService } from '../../../../../hooks/use_onboarding_service'; +import { useOnboardingService } from '../../../../hooks/use_onboarding_service'; import { IntegrationTabId } from '../types'; -jest.mock('../../../../../hooks/use_onboarding_service', () => ({ +jest.mock('../../../../hooks/use_onboarding_service', () => ({ useOnboardingService: jest.fn(), })); diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations/callouts/integration_card_top_callout.tsx b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations/callouts/integration_card_top_callout.tsx index 3a6b5ae3be92c..40f4ae95cf088 100644 --- a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations/callouts/integration_card_top_callout.tsx +++ b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations/callouts/integration_card_top_callout.tsx @@ -8,7 +8,7 @@ import React from 'react'; import useObservable from 'react-use/lib/useObservable'; -import { useOnboardingService } from '../../../../../hooks/use_onboarding_service'; +import { useOnboardingService } from '../../../../hooks/use_onboarding_service'; import { AgentlessAvailableCallout } from './agentless_available_callout'; import { InstalledIntegrationsCallout } from './installed_integrations_callout'; import { IntegrationTabId } from '../types'; diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations/callouts/manage_integrations_callout.tsx b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations/callouts/manage_integrations_callout.tsx index 839e5870d4b7e..4085f2310d570 100644 --- a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations/callouts/manage_integrations_callout.tsx +++ b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations/callouts/manage_integrations_callout.tsx @@ -11,7 +11,7 @@ import { EuiIcon } from '@elastic/eui'; import { LinkAnchor } from '../../../../../../common/components/links'; import { CardCallOut } from '../../common/card_callout'; import { useAddIntegrationsUrl } from '../../../../../../common/hooks/use_add_integrations_url'; -import { trackOnboardingLinkClick } from '../../../../../common/lib/telemetry'; +import { trackOnboardingLinkClick } from '../../../../lib/telemetry'; import { TELEMETRY_MANAGE_INTEGRATIONS } from '../constants'; export const ManageIntegrationsCallout = React.memo( diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations/index.ts b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations/index.ts index 07e80ab64f522..3568376c192cf 100644 --- a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations/index.ts +++ b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations/index.ts @@ -27,5 +27,5 @@ export const integrationsCardConfig: OnboardingCardConfig ({ ...jest.requireActual('../../../../../common/lib/kibana'), useNavigation: jest.fn().mockReturnValue({ diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations/integration_card_grid_tabs.tsx b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations/integration_card_grid_tabs.tsx index e1ce7f5cdecf1..6b5e3f60a24e1 100644 --- a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations/integration_card_grid_tabs.tsx +++ b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations/integration_card_grid_tabs.tsx @@ -14,7 +14,7 @@ import { withLazyHook } from '../../../../../common/components/with_lazy_hook'; import { useStoredIntegrationSearchTerm, useStoredIntegrationTabId, -} from '../../../../hooks/use_stored_state'; +} from '../../../hooks/use_stored_state'; import { useOnboardingContext } from '../../../onboarding_context'; import { DEFAULT_TAB, @@ -29,7 +29,7 @@ import { INTEGRATION_TABS, INTEGRATION_TABS_BY_ID } from './integration_tabs_con import { useIntegrationCardList } from './use_integration_card_list'; import { IntegrationTabId } from './types'; import { IntegrationCardTopCallout } from './callouts/integration_card_top_callout'; -import { trackOnboardingLinkClick } from '../../../../common/lib/telemetry'; +import { trackOnboardingLinkClick } from '../../../lib/telemetry'; export interface IntegrationsCardGridTabsProps { installedIntegrationsCount: number; diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations/integrations_card.test.tsx b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations/integrations_card.test.tsx index 296d5391fd611..c01fbfa96123d 100644 --- a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations/integrations_card.test.tsx +++ b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations/integrations_card.test.tsx @@ -15,6 +15,7 @@ const props = { checkComplete: jest.fn(), isCardComplete: jest.fn(), setExpandedCardId: jest.fn(), + isCardAvailable: jest.fn(), }; describe('IntegrationsCard', () => { diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations/use_integration_card_list.test.ts b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations/use_integration_card_list.test.ts index 19ab340276b83..095b2f988e59c 100644 --- a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations/use_integration_card_list.test.ts +++ b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations/use_integration_card_list.test.ts @@ -6,9 +6,9 @@ */ import { renderHook } from '@testing-library/react-hooks'; import { useIntegrationCardList } from './use_integration_card_list'; -import { trackOnboardingLinkClick } from '../../../../common/lib/telemetry'; +import { trackOnboardingLinkClick } from '../../../lib/telemetry'; -jest.mock('../../../../common/lib/telemetry'); +jest.mock('../../../lib/telemetry'); jest.mock('../../../../../common/lib/kibana', () => ({ ...jest.requireActual('../../../../../common/lib/kibana'), useNavigation: jest.fn().mockReturnValue({ diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations/use_integration_card_list.ts b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations/use_integration_card_list.ts index ccea5299551c1..660464ba73501 100644 --- a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations/use_integration_card_list.ts +++ b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations/use_integration_card_list.ts @@ -23,7 +23,7 @@ import { TELEMETRY_INTEGRATION_CARD, } from './constants'; import type { GetAppUrl, NavigateTo } from '../../../../../common/lib/kibana'; -import { trackOnboardingLinkClick } from '../../../../common/lib/telemetry'; +import { trackOnboardingLinkClick } from '../../../lib/telemetry'; const addPathParamToUrl = (url: string, onboardingLink: string) => { const encoded = encodeURIComponent(onboardingLink); diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/rules/rules_card.test.tsx b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/rules/rules_card.test.tsx index f7156adc34eba..e32d13b787a51 100644 --- a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/rules/rules_card.test.tsx +++ b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/rules/rules_card.test.tsx @@ -13,6 +13,7 @@ const props = { setComplete: jest.fn(), checkComplete: jest.fn(), isCardComplete: jest.fn(), + isCardAvailable: jest.fn(), setExpandedCardId: jest.fn(), }; @@ -31,7 +32,8 @@ describe('RulesCard', () => { expect(getByTestId('rulesCardDescription')).toBeInTheDocument(); }); - it('card callout should be rendered if integrations cards is not complete', () => { + it('card callout should be rendered if integrations card is available but not complete', () => { + props.isCardAvailable.mockReturnValueOnce(true); props.isCardComplete.mockReturnValueOnce(false); const { getByText } = render( @@ -43,7 +45,20 @@ describe('RulesCard', () => { expect(getByText('To add Elastic rules add integrations first.')).toBeInTheDocument(); }); - it('card button should be disabled if integrations cards is not complete', () => { + it('card callout should not be rendered if integrations card is not available', () => { + props.isCardAvailable.mockReturnValueOnce(false); + + const { queryByText } = render( + + + + ); + + expect(queryByText('To add Elastic rules add integrations first.')).not.toBeInTheDocument(); + }); + + it('card button should be disabled if integrations card is available but not complete', () => { + props.isCardAvailable.mockReturnValueOnce(true); props.isCardComplete.mockReturnValueOnce(false); const { getByTestId } = render( @@ -54,4 +69,17 @@ describe('RulesCard', () => { expect(getByTestId('rulesCardButton').querySelector('button')).toBeDisabled(); }); + + it('card button should be enabled if integrations card is complete', () => { + props.isCardAvailable.mockReturnValueOnce(true); + props.isCardComplete.mockReturnValueOnce(true); + + const { getByTestId } = render( + + + + ); + + expect(getByTestId('rulesCardButton').querySelector('button')).not.toBeDisabled(); + }); }); diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/rules/rules_card.tsx b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/rules/rules_card.tsx index 50c722d49c359..c1eb789d6a46f 100644 --- a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/rules/rules_card.tsx +++ b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/rules/rules_card.tsx @@ -6,34 +6,32 @@ */ import React, { useCallback, useMemo } from 'react'; -import { - EuiFlexGroup, - EuiFlexItem, - EuiIcon, - EuiLink, - EuiSpacer, - EuiText, - useEuiTheme, - COLOR_MODES_STANDARD, -} from '@elastic/eui'; +import { EuiFlexGroup, EuiFlexItem, EuiIcon, EuiLink, EuiSpacer } from '@elastic/eui'; import { SecurityPageName } from '@kbn/security-solution-navigation'; import { SecuritySolutionLinkButton } from '../../../../../common/components/links'; import { OnboardingCardId } from '../../../../constants'; import type { OnboardingCardComponent } from '../../../../types'; import { OnboardingCardContentImagePanel } from '../common/card_content_image_panel'; import { CardCallOut } from '../common/card_callout'; +import { CardSubduedText } from '../common/card_subdued_text'; import rulesImageSrc from './images/rules.png'; import * as i18n from './translations'; -export const RulesCard: OnboardingCardComponent = ({ isCardComplete, setExpandedCardId }) => { - const { colorMode } = useEuiTheme(); - const isDarkMode = colorMode === COLOR_MODES_STANDARD.dark; - +export const RulesCard: OnboardingCardComponent = ({ + isCardComplete, + setExpandedCardId, + isCardAvailable, +}) => { const isIntegrationsCardComplete = useMemo( () => isCardComplete(OnboardingCardId.integrations), [isCardComplete] ); + const isIntegrationsCardAvailable = useMemo( + () => isCardAvailable(OnboardingCardId.integrations), + [isCardAvailable] + ); + const expandIntegrationsCard = useCallback(() => { setExpandedCardId(OnboardingCardId.integrations, { scroll: true }); }, [setExpandedCardId]); @@ -47,14 +45,10 @@ export const RulesCard: OnboardingCardComponent = ({ isCardComplete, setExpanded alignItems="flexStart" > - + {i18n.RULES_CARD_DESCRIPTION} - - {!isIntegrationsCardComplete && ( + + {isIntegrationsCardAvailable && !isIntegrationsCardComplete && ( <> {i18n.RULES_CARD_ADD_RULES_BUTTON} diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/siem_migrations/ai_connector/ai_connector_card.tsx b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/siem_migrations/ai_connector/ai_connector_card.tsx new file mode 100644 index 0000000000000..127e6b4d57ebd --- /dev/null +++ b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/siem_migrations/ai_connector/ai_connector_card.tsx @@ -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 React, { useCallback } from 'react'; +import { + EuiFlexGroup, + EuiFlexItem, + EuiText, + useEuiTheme, + COLOR_MODES_STANDARD, +} from '@elastic/eui'; +import { useKibana } from '../../../../../../common/lib/kibana/kibana_react'; +import { useDefinedLocalStorage } from '../../../../hooks/use_stored_state'; +import type { OnboardingCardComponent } from '../../../../../types'; +import * as i18n from './translations'; +import { OnboardingCardContentPanel } from '../../common/card_content_panel'; +import { ConnectorCards } from '../../common/connectors/connector_cards'; +import type { AIConnectorCardMetadata } from './types'; +import { MissingPrivilegesCallOut } from '../../common/connectors/missing_privileges'; + +export const AIConnectorCard: OnboardingCardComponent = ({ + checkCompleteMetadata, + checkComplete, + setComplete, +}) => { + const { siemMigrations } = useKibana().services; + const { euiTheme, colorMode } = useEuiTheme(); + const isDarkMode = colorMode === COLOR_MODES_STANDARD.dark; + + const [storedConnectorId, setStoredConnectorId] = useDefinedLocalStorage( + siemMigrations.rules.connectorIdStorage.key, + null + ); + const setSelectedConnectorId = useCallback( + (connectorId: string) => { + setStoredConnectorId(connectorId); + setComplete(true); + }, + [setComplete, setStoredConnectorId] + ); + + const connectors = checkCompleteMetadata?.connectors; + const canExecuteConnectors = checkCompleteMetadata?.canExecuteConnectors; + const canCreateConnectors = checkCompleteMetadata?.canCreateConnectors; + + return ( + + {canExecuteConnectors ? ( + + + + {i18n.AI_CONNECTOR_CARD_DESCRIPTION} + + + + + + + ) : ( + + )} + + ); +}; + +// eslint-disable-next-line import/no-default-export +export default AIConnectorCard; diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/siem_migrations/ai_connector/connectors_check_complete.ts b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/siem_migrations/ai_connector/connectors_check_complete.ts new file mode 100644 index 0000000000000..d7121fe97cf7c --- /dev/null +++ b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/siem_migrations/ai_connector/connectors_check_complete.ts @@ -0,0 +1,45 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { loadAllActions as loadConnectors } from '@kbn/triggers-actions-ui-plugin/public/common/constants'; +import type { AIConnector } from '@kbn/elastic-assistant/impl/connectorland/connector_selector'; +import type { OnboardingCardCheckComplete } from '../../../../../types'; +import { AIActionTypeIds } from '../../common/connectors/constants'; +import type { AIConnectorCardMetadata } from './types'; + +export const checkAssistantCardComplete: OnboardingCardCheckComplete< + AIConnectorCardMetadata +> = async ({ http, application, siemMigrations }) => { + let isComplete = false; + const allConnectors = await loadConnectors({ http }); + const { capabilities } = application; + + const aiConnectors = allConnectors.reduce((acc: AIConnector[], connector) => { + if (!connector.isMissingSecrets && AIActionTypeIds.includes(connector.actionTypeId)) { + acc.push(connector); + } + return acc; + }, []); + + const storedConnectorId = siemMigrations.rules.connectorIdStorage.get(); + if (storedConnectorId) { + if (aiConnectors.length === 0) { + siemMigrations.rules.connectorIdStorage.remove(); + } else { + isComplete = aiConnectors.some((connector) => connector.id === storedConnectorId); + } + } + + return { + isComplete, + metadata: { + connectors: aiConnectors, + canExecuteConnectors: Boolean(capabilities.actions?.show && capabilities.actions?.execute), + canCreateConnectors: Boolean(capabilities.actions?.save), + }, + }; +}; diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/siem_migrations/ai_connector/index.ts b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/siem_migrations/ai_connector/index.ts new file mode 100644 index 0000000000000..45080123889d5 --- /dev/null +++ b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/siem_migrations/ai_connector/index.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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { AssistantAvatar } from '@kbn/elastic-assistant'; +import type { OnboardingCardConfig } from '../../../../../types'; +import { OnboardingCardId } from '../../../../../constants'; +import { AI_CONNECTOR_CARD_TITLE } from './translations'; +import { checkAssistantCardComplete } from './connectors_check_complete'; +import type { AIConnectorCardMetadata } from './types'; + +export const aiConnectorCardConfig: OnboardingCardConfig = { + id: OnboardingCardId.siemMigrationsAiConnectors, + title: AI_CONNECTOR_CARD_TITLE, + icon: AssistantAvatar, + Component: React.lazy( + () => + import( + /* webpackChunkName: "onboarding_siem_migrations_ai_connector_card" */ + './ai_connector_card' + ) + ), + checkComplete: checkAssistantCardComplete, + licenseTypeRequired: 'enterprise', +}; diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/siem_migrations/ai_connector/translations.ts b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/siem_migrations/ai_connector/translations.ts new file mode 100644 index 0000000000000..c05951e1ddf27 --- /dev/null +++ b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/siem_migrations/ai_connector/translations.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 { i18n } from '@kbn/i18n'; + +export const AI_CONNECTOR_CARD_TITLE = i18n.translate( + 'xpack.securitySolution.onboarding.aiConnector.title', + { + defaultMessage: 'Configure AI Provider', + } +); + +export const AI_CONNECTOR_CARD_DESCRIPTION = i18n.translate( + 'xpack.securitySolution.onboarding.aiConnector.description', + { + defaultMessage: + 'Choose and configure any AI provider available to start a SIEM rules migration.', + } +); diff --git a/x-pack/plugins/security_solution/public/siem_migrations/rules/hooks/translations.ts b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/siem_migrations/ai_connector/types.ts similarity index 55% rename from x-pack/plugins/security_solution/public/siem_migrations/rules/hooks/translations.ts rename to x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/siem_migrations/ai_connector/types.ts index 74845b5f257ad..3e0a471da6f5c 100644 --- a/x-pack/plugins/security_solution/public/siem_migrations/rules/hooks/translations.ts +++ b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/cards/siem_migrations/ai_connector/types.ts @@ -5,11 +5,10 @@ * 2.0. */ -import { i18n } from '@kbn/i18n'; +import type { ActionConnector } from '@kbn/alerts-ui-shared'; -export const COLUMN_STATUS = i18n.translate( - 'xpack.securitySolution.siemMigrations.rules.columns.statusTitle', - { - defaultMessage: 'Status', - } -); +export interface AIConnectorCardMetadata { + connectors: ActionConnector[]; + canExecuteConnectors: boolean; + canCreateConnectors: boolean; +} diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/hooks/use_body_config.test.ts b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/hooks/use_body_config.test.ts index 775ff09546fe6..c2c89594669c9 100644 --- a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/hooks/use_body_config.test.ts +++ b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/hooks/use_body_config.test.ts @@ -6,112 +6,59 @@ */ import { renderHook } from '@testing-library/react-hooks'; import { useBodyConfig } from './use_body_config'; -import { useKibana } from '../../../../common/lib/kibana/kibana_react'; -import useObservable from 'react-use/lib/useObservable'; -import { hasCapabilities } from '../../../../common/lib/capabilities'; +import { mockOnboardingContext, onboardingContext } from '../../__mocks__/mocks'; -const bodyConfig = [ - { - title: 'Group 1', - cards: [ - { - id: 'license_card', - title: 'licensed card', - icon: 'fleetApp', - licenseType: 'platinum', - }, - { - id: 'capabilities_card', - title: 'rbac card', - icon: 'fleetApp', - capabilities: ['siem.crud'], - }, - ], - }, - { - title: 'Group 2', - cards: [ - { - id: 'capabilities_license_card', - title: 'all card', - icon: 'fleetApp', - capabilities: ['siem.crud'], - licenseType: 'platinum', - }, - ], - }, -]; +const topicId = 'topic-id'; +const mockUseTopicId = jest.fn(() => topicId); +jest.mock('../../hooks/use_topic_id', () => ({ + useTopicId: () => mockUseTopicId(), +})); -// Mock dependencies -jest.mock('react-use/lib/useObservable'); -jest.mock('../../../../common/lib/kibana/kibana_react'); -jest.mock('../../../../common/lib/capabilities'); -jest.mock('../body_config', () => ({ bodyConfig })); +const defaultBodyConfig = [{ title: 'Default Group 1', cards: [] }]; +const bodyConfig = [{ title: 'Group 1', cards: [] }]; +const config = new Map([ + ['default', { body: defaultBodyConfig }], + [topicId, { body: bodyConfig }], +]); -const mockLicenseHasAtLeast = jest.fn(); -const mockUseObservable = useObservable as jest.Mock; -const mockHasCapabilities = hasCapabilities as jest.Mock; -mockUseObservable.mockReturnValue({ hasAtLeast: mockLicenseHasAtLeast }); - -(useKibana as jest.Mock).mockReturnValue({ - services: { application: { capabilities: {} }, licensing: {} }, -}); +jest.mock('../../onboarding_context'); describe('useBodyConfig', () => { beforeEach(() => { - mockLicenseHasAtLeast.mockReturnValue(true); - mockHasCapabilities.mockReturnValue(true); jest.clearAllMocks(); }); - it('should return an empty array if license is not defined', () => { - mockUseObservable.mockReturnValueOnce(undefined); - const { result } = renderHook(useBodyConfig); - expect(result.current).toEqual([]); - }); + describe('when the selected topic does not have a body config', () => { + beforeEach(() => { + mockOnboardingContext.mockReturnValue({ ...onboardingContext, config: new Map() }); + }); - it('should return all cards if no capabilities or licenseType are filtered', () => { - const { result } = renderHook(useBodyConfig); - expect(result.current).toEqual(bodyConfig); + it('should return an empty array', () => { + const { result } = renderHook(() => useBodyConfig()); + expect(result.current).toEqual([]); + }); }); - it('should filter out cards based on license', () => { - mockLicenseHasAtLeast.mockReturnValue(false); + describe('when the selected topic has a body config', () => { + beforeEach(() => { + mockOnboardingContext.mockReturnValue({ ...onboardingContext, config }); + }); - const { result } = renderHook(useBodyConfig); - - expect(result.current).toEqual([ - { - title: 'Group 1', - cards: [ - { - id: 'capabilities_card', - title: 'rbac card', - icon: 'fleetApp', - capabilities: ['siem.crud'], - }, - ], - }, - ]); + it('should return the body config for the selected topic', () => { + const { result } = renderHook(() => useBodyConfig()); + expect(result.current).toEqual(bodyConfig); + }); }); - it('should filter out cards based on capabilities', () => { - mockHasCapabilities.mockReturnValue(false); - - const { result } = renderHook(useBodyConfig); + describe('when the selected topic does not exist (not expected)', () => { + beforeEach(() => { + mockUseTopicId.mockReturnValue('non-existent-topic'); + mockOnboardingContext.mockReturnValue({ ...onboardingContext, config }); + }); - expect(result.current).toEqual([ - { - title: 'Group 1', - cards: [ - { - id: 'license_card', - title: 'licensed card', - icon: 'fleetApp', - licenseType: 'platinum', - }, - ], - }, - ]); + it('should return the body config for the selected topic', () => { + const { result } = renderHook(() => useBodyConfig()); + expect(result.current).toEqual([]); + }); }); }); diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/hooks/use_body_config.ts b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/hooks/use_body_config.ts index f7b12e5988c0d..0d6a26a3439d6 100644 --- a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/hooks/use_body_config.ts +++ b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/hooks/use_body_config.ts @@ -5,51 +5,26 @@ * 2.0. */ -import useObservable from 'react-use/lib/useObservable'; import { useMemo } from 'react'; -import { hasCapabilities } from '../../../../common/lib/capabilities'; -import { useKibana } from '../../../../common/lib/kibana/kibana_react'; -import { bodyConfig } from '../body_config'; +import { useOnboardingContext } from '../../onboarding_context'; +import { useTopicId } from '../../hooks/use_topic_id'; import type { OnboardingGroupConfig } from '../../../types'; /** - * Hook that filters the config based on the user's capabilities and license + * Hook that returns the body config for the selected topic */ -export const useBodyConfig = () => { - const { application, licensing } = useKibana().services; - const license = useObservable(licensing.license$); - - const filteredBodyConfig = useMemo(() => { - // Return empty array when the license is not defined. It should always become defined at some point. - // This exit case prevents code dependant on the cards config (like completion checks) from running multiple times. - if (!license) { - return []; +export const useBodyConfig = (): OnboardingGroupConfig[] => { + const topicId = useTopicId(); + const { config } = useOnboardingContext(); + const topicBodyConfig = useMemo(() => { + let bodyConfig: OnboardingGroupConfig[] = []; + const topicConfig = config.get(topicId); + // The selected topic should always exist in the config, but we check just in case + if (topicConfig) { + bodyConfig = topicConfig.body; } - return bodyConfig.reduce((filteredGroups, group) => { - const filteredCards = group.cards.filter((card) => { - if (card.capabilities) { - const cardHasCapabilities = hasCapabilities(application.capabilities, card.capabilities); - if (!cardHasCapabilities) { - return false; - } - } - - if (card.licenseType) { - const cardHasLicense = license.hasAtLeast(card.licenseType); - if (!cardHasLicense) { - return false; - } - } - - return true; - }); - - if (filteredCards.length > 0) { - filteredGroups.push({ ...group, cards: filteredCards }); - } - return filteredGroups; - }, []); - }, [license, application.capabilities]); + return bodyConfig; + }, [config, topicId]); - return filteredBodyConfig; + return topicBodyConfig; }; diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/hooks/use_completed_cards.test.ts b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/hooks/use_completed_cards.test.ts index 2c9fcd573f0d6..1ace059a5115e 100644 --- a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/hooks/use_completed_cards.test.ts +++ b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/hooks/use_completed_cards.test.ts @@ -6,11 +6,10 @@ */ import { renderHook, act, type RenderHookResult } from '@testing-library/react-hooks'; -import { waitFor } from '@testing-library/react'; import { useCompletedCards } from './use_completed_cards'; import type { OnboardingGroupConfig } from '../../../types'; import type { OnboardingCardId } from '../../../constants'; -import { mockReportCardComplete } from '../../__mocks__/onboarding_context_mocks'; +import { mockReportCardComplete } from '../../__mocks__/mocks'; import { useKibana } from '../../../../common/lib/kibana'; const defaultStoredCompletedCardIds: OnboardingCardId[] = []; @@ -20,8 +19,8 @@ const mockUseStoredCompletedCardIds = jest.fn(() => [ defaultStoredCompletedCardIds, mockSetStoredCompletedCardIds, ]); -jest.mock('../../../hooks/use_stored_state', () => ({ - ...jest.requireActual('../../../hooks/use_stored_state'), +jest.mock('../../hooks/use_stored_state', () => ({ + ...jest.requireActual('../../hooks/use_stored_state'), useStoredCompletedCardIds: () => mockUseStoredCompletedCardIds(), })); @@ -99,6 +98,8 @@ const mockFailureCardsGroupConfig = [ }, ] as unknown as OnboardingGroupConfig[]; +const flushPromises = () => new Promise(setImmediate); + describe('useCompletedCards Hook', () => { beforeEach(() => { jest.clearAllMocks(); @@ -114,11 +115,7 @@ describe('useCompletedCards Hook', () => { services: { notifications: { toasts: { addError: mockAddError } } }, }); renderResult = renderHook(useCompletedCards, { initialProps: mockFailureCardsGroupConfig }); - await act(async () => { - await waitFor(() => { - expect(mockSetStoredCompletedCardIds).toHaveBeenCalledTimes(0); // number of completed cards - }); - }); + await act(flushPromises); }); describe('when a the auto check is called', () => { @@ -158,11 +155,7 @@ describe('useCompletedCards Hook', () => { >; beforeEach(async () => { renderResult = renderHook(useCompletedCards, { initialProps: mockCardsGroupConfig }); - await act(async () => { - await waitFor(() => { - expect(mockSetStoredCompletedCardIds).toHaveBeenCalledTimes(4); // number of completed cards - }); - }); + await act(flushPromises); }); it('should set the correct completed card ids', async () => { @@ -258,12 +251,8 @@ describe('useCompletedCards Hook', () => { beforeEach(async () => { jest.clearAllMocks(); cardIncomplete.checkComplete.mockResolvedValueOnce(true); - await act(async () => { - renderResult.result.current.checkCardComplete(cardIncomplete.id); - await waitFor(() => { - expect(mockSetStoredCompletedCardIds).toHaveBeenCalledTimes(1); - }); - }); + renderResult.result.current.checkCardComplete(cardIncomplete.id); + await act(flushPromises); }); it('should set the correct completed card ids', async () => { diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/hooks/use_completed_cards.ts b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/hooks/use_completed_cards.ts index 34092bf2d5eec..8f3bcf0b618d6 100644 --- a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/hooks/use_completed_cards.ts +++ b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/hooks/use_completed_cards.ts @@ -5,15 +5,15 @@ * 2.0. */ -import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; +import { useCallback, useEffect, useMemo, useState } from 'react'; import { useKibana } from '../../../../common/lib/kibana'; -import { useStoredCompletedCardIds } from '../../../hooks/use_stored_state'; +import { useStoredCompletedCardIds } from '../../hooks/use_stored_state'; import type { OnboardingCardId } from '../../../constants'; import type { CheckCompleteResult, CheckCompleteResponse, - OnboardingGroupConfig, OnboardingCardConfig, + OnboardingGroupConfig, } from '../../../types'; import { useOnboardingContext } from '../../onboarding_context'; @@ -32,10 +32,9 @@ export type CardCheckCompleteResult = Partial { - const { spaceId, reportCardComplete } = useOnboardingContext(); +export const useCompletedCards = (bodyConfig: OnboardingGroupConfig[]) => { + const { spaceId, telemetry } = useOnboardingContext(); const services = useKibana().services; - const autoCheckCompletedRef = useRef(false); // Use stored state to keep localStorage in sync, and a local state to avoid unnecessary re-renders. const [storedCompleteCardIds, setStoredCompleteCardIds] = useStoredCompletedCardIds(spaceId); @@ -55,7 +54,7 @@ export const useCompletedCards = (cardsGroupConfig: OnboardingGroupConfig[]) => const isCurrentlyComplete = currentCompleteCards.includes(cardId); if (completed && !isCurrentlyComplete) { const newCompleteCardIds = [...currentCompleteCards, cardId]; - reportCardComplete(cardId, options); + telemetry.reportCardComplete(cardId, options); setStoredCompleteCardIds(newCompleteCardIds); // Keep the stored state in sync with the local state return newCompleteCardIds; } else if (!completed && isCurrentlyComplete) { @@ -66,7 +65,7 @@ export const useCompletedCards = (cardsGroupConfig: OnboardingGroupConfig[]) => return currentCompleteCards; // No change }); }, - [reportCardComplete, setStoredCompleteCardIds] // static dependencies, this function needs to be stable + [setStoredCompleteCardIds, telemetry] // static dependencies, this function needs to be stable ); const getCardCheckCompleteResult = useCallback( @@ -88,11 +87,11 @@ export const useCompletedCards = (cardsGroupConfig: OnboardingGroupConfig[]) => // Internal: stores all cards that have a checkComplete function in a flat array const cardsWithAutoCheck = useMemo( () => - cardsGroupConfig.reduce((acc, group) => { + bodyConfig.reduce((acc, group) => { acc.push(...group.cards.filter((card) => card.checkComplete)); return acc; }, []), - [cardsGroupConfig] + [bodyConfig] ); // Internal: sets the result of a checkComplete function @@ -118,9 +117,7 @@ export const useCompletedCards = (cardsGroupConfig: OnboardingGroupConfig[]) => .checkComplete?.(services) .catch((err: Error) => { services.notifications.toasts.addError(err, { title: cardConfig.title }); - return { - isComplete: false, - }; + return { isComplete: false }; }) .then((checkCompleteResult) => { processCardCheckCompleteResult(cardId, checkCompleteResult); @@ -131,19 +128,13 @@ export const useCompletedCards = (cardsGroupConfig: OnboardingGroupConfig[]) => ); useEffect(() => { - // Initial auto-check for all cards, it should run only once, after cardsGroupConfig is properly populated - if (cardsWithAutoCheck.length === 0 || autoCheckCompletedRef.current) { - return; - } - autoCheckCompletedRef.current = true; + // Initial auto-check for all body cards, it should run once per `bodyConfig` (topic) change. cardsWithAutoCheck.map((card) => card .checkComplete?.(services) .catch((err: Error) => { services.notifications.toasts.addError(err, { title: card.title }); - return { - isComplete: false, - }; + return { isComplete: false }; }) .then((checkCompleteResult) => { processCardCheckCompleteResult(card.id, checkCompleteResult); diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/hooks/use_expanded_card.test.ts b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/hooks/use_expanded_card.test.ts index 55f60e591c17d..26612d83b565f 100644 --- a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/hooks/use_expanded_card.test.ts +++ b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/hooks/use_expanded_card.test.ts @@ -9,16 +9,14 @@ import { renderHook, act } from '@testing-library/react-hooks'; import { useExpandedCard } from './use_expanded_card'; import { HEIGHT_ANIMATION_DURATION } from '../onboarding_card_panel.styles'; import type { OnboardingCardId } from '../../../constants'; -import { mockReportCardOpen } from '../../__mocks__/onboarding_context_mocks'; import { waitFor } from '@testing-library/react'; const scrollTimeout = HEIGHT_ANIMATION_DURATION + 50; -const mockSetStorageExpandedCardId = jest.fn(); -const mockUseStoredExpandedCardId = jest.fn(() => [null, mockSetStorageExpandedCardId]); -jest.mock('../../../hooks/use_stored_state', () => ({ - ...jest.requireActual('../../../hooks/use_stored_state'), - useStoredExpandedCardId: () => mockUseStoredExpandedCardId(), +const mockSetCardDetail = jest.fn(); +jest.mock('../../hooks/use_url_detail', () => ({ + ...jest.requireActual('../../hooks/use_url_detail'), + useUrlDetail: () => ({ setCardDetail: mockSetCardDetail }), })); jest.mock('react-router-dom', () => ({ @@ -26,14 +24,10 @@ jest.mock('react-router-dom', () => ({ useLocation: () => ({ hash: '#card-1', pathname: '/test' }), })); -jest.mock('../../onboarding_context'); - describe('useExpandedCard Hook', () => { const mockCardId = 'card-1' as OnboardingCardId; const mockScrollTo = jest.fn(); global.window.scrollTo = mockScrollTo; - const mockReplaceState = jest.fn(); - global.history.replaceState = mockReplaceState; const mockGetElementById = jest.fn().mockReturnValue({ focus: jest.fn(), @@ -45,40 +39,11 @@ describe('useExpandedCard Hook', () => { jest.clearAllMocks(); }); - describe('when the page is loading', () => { - beforeEach(() => { - Object.defineProperty(document, 'readyState', { - value: 'loading', - configurable: true, - }); - }); - - it('should not scroll if the page is not fully loaded', async () => { - renderHook(useExpandedCard); - - // Ensure that scroll and focus were triggered - await waitFor( - () => { - expect(mockScrollTo).not.toHaveBeenCalled(); - }, - { timeout: scrollTimeout } - ); - }); - }); - describe('when the page is completely loaded', () => { beforeEach(() => { - Object.defineProperty(document, 'readyState', { - value: 'complete', - configurable: true, - }); renderHook(useExpandedCard); }); - it('should set the expanded card id from the hash', () => { - expect(mockSetStorageExpandedCardId).toHaveBeenCalledWith(mockCardId); - }); - it('should scroll to the expanded card id from the hash', async () => { // Ensure that scroll and focus were triggered await waitFor( @@ -89,10 +54,6 @@ describe('useExpandedCard Hook', () => { { timeout: scrollTimeout } ); }); - - it('should report the expanded card id from the hash', () => { - expect(mockReportCardOpen).toHaveBeenCalledWith(mockCardId, { auto: true }); - }); }); describe('when the card is expanded manually', () => { @@ -111,12 +72,8 @@ describe('useExpandedCard Hook', () => { }); }); - it('should set the expanded card id in storage', () => { - expect(mockSetStorageExpandedCardId).toHaveBeenCalledWith(mockCardId); - }); - - it('should set the URL hash', () => { - expect(mockReplaceState).toHaveBeenCalledWith(null, '', `#${mockCardId}`); + it('should set the expanded card id', () => { + expect(mockSetCardDetail).toHaveBeenCalledWith(mockCardId); }); it('should not scroll', async () => { @@ -129,10 +86,6 @@ describe('useExpandedCard Hook', () => { { timeout: scrollTimeout } ); }); - - it('should report the expanded card id', () => { - expect(mockReportCardOpen).toHaveBeenCalledWith(mockCardId); - }); }); describe('when scroll is enabled', () => { @@ -143,12 +96,8 @@ describe('useExpandedCard Hook', () => { }); }); - it('should set the expanded card id in storage', () => { - expect(mockSetStorageExpandedCardId).toHaveBeenCalledWith(mockCardId); - }); - - it('should set the URL hash', () => { - expect(mockReplaceState).toHaveBeenCalledWith(null, '', `#${mockCardId}`); + it('should set the expanded card id', () => { + expect(mockSetCardDetail).toHaveBeenCalledWith(mockCardId); }); it('should scroll', async () => { @@ -161,10 +110,6 @@ describe('useExpandedCard Hook', () => { { timeout: scrollTimeout } ); }); - - it('should report the expanded card id', () => { - expect(mockReportCardOpen).toHaveBeenCalledWith(mockCardId); - }); }); }); }); diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/hooks/use_expanded_card.ts b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/hooks/use_expanded_card.ts index 131953e4b0687..514618390695c 100644 --- a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/hooks/use_expanded_card.ts +++ b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/hooks/use_expanded_card.ts @@ -5,13 +5,12 @@ * 2.0. */ -import { useCallback, useEffect, useState } from 'react'; +import { useCallback, useEffect, useMemo, useState } from 'react'; import { useLocation } from 'react-router-dom'; -import { useStoredExpandedCardId } from '../../../hooks/use_stored_state'; import { HEIGHT_ANIMATION_DURATION } from '../onboarding_card_panel.styles'; -import type { OnboardingCardId } from '../../../constants'; +import { type OnboardingCardId } from '../../../constants'; import type { SetExpandedCardId } from '../../../types'; -import { useOnboardingContext } from '../../onboarding_context'; +import { getCardIdFromHash, useUrlDetail } from '../../hooks/use_url_detail'; const HEADER_OFFSET = 40; @@ -25,59 +24,36 @@ const scrollToCard = (cardId: OnboardingCardId) => { }, HEIGHT_ANIMATION_DURATION); }; -const setHash = (cardId: OnboardingCardId | null) => { - history.replaceState(null, '', cardId == null ? ' ' : `#${cardId}`); -}; - /** * This hook manages the expanded card id state in the LocalStorage and the hash in the URL. */ export const useExpandedCard = () => { - const { spaceId, reportCardOpen } = useOnboardingContext(); - const [expandedCardId, setStorageExpandedCardId] = useStoredExpandedCardId(spaceId); - const location = useLocation(); - - const [documentReadyState, setReadyState] = useState(document.readyState); + const { setCardDetail } = useUrlDetail(); + const { hash } = useLocation(); + const cardIdFromHash = useMemo(() => getCardIdFromHash(hash), [hash]); - useEffect(() => { - const readyStateListener = () => setReadyState(document.readyState); - document.addEventListener('readystatechange', readyStateListener); - return () => document.removeEventListener('readystatechange', readyStateListener); - }, []); + const [cardId, setCardId] = useState(null); - // This effect implements auto-scroll in the initial render, further changes in the hash should not trigger this effect + // This effect implements auto-scroll in the initial render. useEffect(() => { - if (documentReadyState !== 'complete') return; // Wait for page to finish loading before scrolling - let cardIdFromHash = location.hash.split('?')[0].replace('#', '') as OnboardingCardId | ''; - if (!cardIdFromHash) { - if (expandedCardId == null) return; - // If the hash is empty, but it is defined the storage we use the storage value - cardIdFromHash = expandedCardId; - setHash(cardIdFromHash); - } - - // If the hash is defined and different from the storage, the hash takes precedence - if (expandedCardId !== cardIdFromHash) { - setStorageExpandedCardId(cardIdFromHash); - reportCardOpen(cardIdFromHash, { auto: true }); + if (cardIdFromHash) { + setCardId(cardIdFromHash); + scrollToCard(cardIdFromHash); } - scrollToCard(cardIdFromHash); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [documentReadyState]); + // cardIdFromHash is only defined once on page load + // it does not change with subsequent url hash changes since history.replaceState is used + }, [cardIdFromHash]); const setExpandedCardId = useCallback( - (cardId, options) => { - setStorageExpandedCardId(cardId); - setHash(cardId); - if (cardId != null) { - reportCardOpen(cardId); - if (options?.scroll) { - scrollToCard(cardId); - } + (newCardId, options) => { + setCardId(newCardId); + setCardDetail(newCardId); + if (newCardId != null && options?.scroll) { + scrollToCard(newCardId); } }, - [setStorageExpandedCardId, reportCardOpen] + [setCardDetail] ); - return { expandedCardId, setExpandedCardId }; + return { expandedCardId: cardId, setExpandedCardId }; }; diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/onboarding_body.tsx b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/onboarding_body.tsx index 3209028e1f0cd..947a0dff46343 100644 --- a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/onboarding_body.tsx +++ b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/onboarding_body.tsx @@ -14,10 +14,10 @@ import { OnboardingCardGroup } from './onboarding_card_group'; import { OnboardingCardPanel } from './onboarding_card_panel'; import { useExpandedCard } from './hooks/use_expanded_card'; import { useCompletedCards } from './hooks/use_completed_cards'; +import type { IsCardAvailable } from '../../types'; export const OnboardingBody = React.memo(() => { const bodyConfig = useBodyConfig(); - const { expandedCardId, setExpandedCardId } = useExpandedCard(); const { isCardComplete, setCardComplete, getCardCheckCompleteResult, checkCardComplete } = useCompletedCards(bodyConfig); @@ -48,6 +48,12 @@ export const OnboardingBody = React.memo(() => { [checkCardComplete] ); + const isCardAvailable = useCallback( + (cardId: OnboardingCardId) => + bodyConfig.some((group) => group.cards.some((card) => card.id === cardId)), + [bodyConfig] + ); + return ( {bodyConfig.map((group, index) => ( @@ -73,6 +79,7 @@ export const OnboardingBody = React.memo(() => { setComplete={createSetCardComplete(id)} checkComplete={createCheckCardComplete(id)} isCardComplete={isCardComplete} + isCardAvailable={isCardAvailable} setExpandedCardId={setExpandedCardId} checkCompleteMetadata={cardCheckCompleteResult?.metadata} /> diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/onboarding_card_panel.styles.ts b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/onboarding_card_panel.styles.ts index a01d80b27488f..ca3e3e765b977 100644 --- a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/onboarding_card_panel.styles.ts +++ b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_body/onboarding_card_panel.styles.ts @@ -14,6 +14,7 @@ export const useCardPanelStyles = () => { const { euiTheme, colorMode } = useEuiTheme(); const successBackgroundColor = useEuiBackgroundColor('success'); const isDarkMode = colorMode === COLOR_MODES_STANDARD.dark; + const darkModeStyles = useDarkPanelStyles(isDarkMode); return css` .onboardingCardHeader { @@ -57,11 +58,15 @@ export const useCardPanelStyles = () => { background-color: ${successBackgroundColor}; } } - ${isDarkMode - ? ` - background-color: ${euiTheme.colors.lightestShade}; - border: 1px solid ${euiTheme.colors.mediumShade}; - ` - : ''} + ${darkModeStyles} `; }; + +export const useDarkPanelStyles = (isDarkMode: boolean) => { + const { euiTheme } = useEuiTheme(); + const darkPanelStyles = css` + background-color: ${euiTheme.colors.lightestShade}; + border-color: ${euiTheme.colors.mediumShade}; + `; + return isDarkMode ? darkPanelStyles : ''; +}; diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_context.test.tsx b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_context.test.tsx new file mode 100644 index 0000000000000..cb395996903be --- /dev/null +++ b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_context.test.tsx @@ -0,0 +1,161 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor 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 { renderHook } from '@testing-library/react'; +import { OnboardingContextProvider, useOnboardingContext } from './onboarding_context'; +import { useLicense } from '../../common/hooks/use_license'; +import { hasCapabilities } from '../../common/lib/capabilities'; +import { ExperimentalFeaturesService } from '../../common/experimental_features_service'; + +jest.mock('../../common/lib/kibana/kibana_react', () => ({ + useKibana: jest.fn().mockReturnValue({ services: { application: { capabilities: {} } } }), +})); +jest.mock('../../common/lib/capabilities', () => ({ hasCapabilities: jest.fn() })); +const mockHasCapabilities = hasCapabilities as jest.Mock; + +jest.mock('../../common/hooks/use_license', () => ({ useLicense: jest.fn() })); +const mockUseLicense = useLicense as jest.Mock; + +jest.mock('../../common/experimental_features_service', () => ({ + ExperimentalFeaturesService: { get: jest.fn() }, +})); +const mockExperimentalFeatures = ExperimentalFeaturesService.get as jest.Mock; + +jest.mock('../config', () => ({ + onboardingConfig: [ + { + id: 'default', + body: [ + { + id: 'defaultGroup1', + cards: [{ id: 'defaultCard1' }], + }, + ], + }, + { + id: 'topic1', + experimentalFlagRequired: 'flag1', + licenseTypeRequired: 'gold', + capabilitiesRequired: ['capability1'], + body: [ + { + id: 'topic1Group1', + cards: [{ id: 'topic1Card1' }], + }, + ], + }, + { + id: 'topic2', + body: [ + { + id: 'topic2Group1', + cards: [ + { id: 'topic2Card1', experimentalFlagRequired: 'flag1' }, + { id: 'topic2Card2', licenseTypeRequired: 'gold' }, + { id: 'topic2Card3', capabilitiesRequired: ['capability1'] }, + ], + }, + ], + }, + ], +})); + +const wrapper: React.FC> = ({ children }) => ( + {children} +); + +describe('OnboardingContextProvider', () => { + describe('config', () => { + beforeEach(() => { + jest.clearAllMocks(); + mockExperimentalFeatures.mockReturnValue({ flag1: true }); + mockUseLicense.mockReturnValue({ isAtLeast: jest.fn(() => true) }); + mockHasCapabilities.mockReturnValue(true); + }); + + describe('when all requirements are met', () => { + it('should return all topics config correctly', () => { + const { result } = renderHook(useOnboardingContext, { wrapper }); + expect(result.current.config.size).toEqual(3); + expect(result.current.config).toMatchSnapshot(); + }); + }); + + describe('when the required experimental flag is not met', () => { + beforeEach(() => { + mockExperimentalFeatures.mockReturnValue({}); + }); + + it('should filter the topics config correctly', () => { + const { result } = renderHook(useOnboardingContext, { wrapper }); + expect(result.current.config.size).toEqual(2); + expect(result.current.config).toMatchSnapshot(); + }); + + describe('and the required license is not met either', () => { + beforeEach(() => { + mockUseLicense.mockReturnValue({ isAtLeast: jest.fn(() => false) }); + }); + + it('should filter the topics config correctly', () => { + const { result } = renderHook(useOnboardingContext, { wrapper }); + expect(result.current.config.size).toEqual(2); + expect(result.current.config).toMatchSnapshot(); + }); + + describe('and the required capabilities are not met either', () => { + beforeEach(() => { + mockHasCapabilities.mockReturnValue(false); + }); + + it('should return only the default topics config', () => { + const { result } = renderHook(useOnboardingContext, { wrapper }); + expect(result.current.config.size).toEqual(1); + expect(result.current.config).toMatchSnapshot(); + }); + }); + }); + }); + + describe('when the required license is not met', () => { + beforeEach(() => { + mockUseLicense.mockReturnValue({ isAtLeast: jest.fn(() => false) }); + }); + + it('should filter the topics config correctly', () => { + const { result } = renderHook(useOnboardingContext, { wrapper }); + expect(result.current.config.size).toEqual(2); + expect(result.current.config).toMatchSnapshot(); + }); + + describe('and the required capabilities are not met either', () => { + beforeEach(() => { + mockHasCapabilities.mockReturnValue(false); + }); + + it('should filter the topics config correctly', () => { + const { result } = renderHook(useOnboardingContext, { wrapper }); + expect(result.current.config.size).toEqual(2); + expect(result.current.config).toMatchSnapshot(); + }); + }); + }); + + describe('when the required capabilities are not met', () => { + beforeEach(() => { + mockHasCapabilities.mockReturnValue(false); + }); + + it('should filter the topics config correctly', () => { + const { result } = renderHook(useOnboardingContext, { wrapper }); + expect(result.current.config.size).toEqual(2); + expect(result.current.config).toMatchSnapshot(); + }); + }); + }); +}); diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_context.tsx b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_context.tsx index 2a6597628a26d..17932207c6271 100644 --- a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_context.tsx +++ b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_context.tsx @@ -6,46 +6,43 @@ */ import type { PropsWithChildren } from 'react'; -import React, { createContext, useContext, useMemo } from 'react'; +import React, { createContext, useCallback, useContext, useMemo } from 'react'; import { useKibana } from '../../common/lib/kibana/kibana_react'; -import type { OnboardingCardId } from '../constants'; +import type { OnboardingTopicId, OnboardingCardId } from '../constants'; import { OnboardingHubEventTypes } from '../../common/lib/telemetry'; +import { useLicense } from '../../common/hooks/use_license'; +import { ExperimentalFeaturesService } from '../../common/experimental_features_service'; -export interface OnboardingContextValue { - spaceId: string; +import { hasCapabilities } from '../../common/lib/capabilities'; +import type { + OnboardingConfigAvailabilityProps, + OnboardingGroupConfig, + TopicConfig, +} from '../types'; +import { onboardingConfig } from '../config'; + +export interface OnboardingTelemetry { reportCardOpen: (cardId: OnboardingCardId, options?: { auto?: boolean }) => void; reportCardComplete: (cardId: OnboardingCardId, options?: { auto?: boolean }) => void; reportCardLinkClicked: (cardId: OnboardingCardId, linkId: string) => void; } + +export type OnboardingConfig = Map; +export interface OnboardingContextValue { + spaceId: string; + telemetry: OnboardingTelemetry; + config: OnboardingConfig; +} const OnboardingContext = createContext(null); export const OnboardingContextProvider: React.FC> = React.memo(({ children, spaceId }) => { - const { telemetry } = useKibana().services; + const config = useFilteredConfig(); + const telemetry = useOnboardingTelemetry(); const value = useMemo( - () => ({ - spaceId, - reportCardOpen: (cardId, { auto = false } = {}) => { - telemetry.reportEvent(OnboardingHubEventTypes.OnboardingHubStepOpen, { - stepId: cardId, - trigger: auto ? 'navigation' : 'click', - }); - }, - reportCardComplete: (cardId, { auto = false } = {}) => { - telemetry.reportEvent(OnboardingHubEventTypes.OnboardingHubStepFinished, { - stepId: cardId, - trigger: auto ? 'auto_check' : 'click', - }); - }, - reportCardLinkClicked: (cardId, linkId: string) => { - telemetry.reportEvent(OnboardingHubEventTypes.OnboardingHubStepLinkClicked, { - originStepId: cardId, - stepLinkId: linkId, - }); - }, - }), - [spaceId, telemetry] + () => ({ spaceId, telemetry, config }), + [spaceId, telemetry, config] ); return {children}; @@ -61,3 +58,82 @@ export const useOnboardingContext = () => { } return context; }; + +/** + * Hook that filters the config based on the user's capabilities, license and experimental features + */ +const useFilteredConfig = (): OnboardingConfig => { + const { capabilities } = useKibana().services.application; + const experimentalFeatures = ExperimentalFeaturesService.get(); + const license = useLicense(); + + const isAvailable = useCallback( + (item: OnboardingConfigAvailabilityProps) => { + if (item.experimentalFlagRequired && !experimentalFeatures[item.experimentalFlagRequired]) { + return false; + } + if (item.licenseTypeRequired && !license.isAtLeast(item.licenseTypeRequired)) { + return false; + } + if (item.capabilitiesRequired && !hasCapabilities(capabilities, item.capabilitiesRequired)) { + return false; + } + return true; + }, + [license, capabilities, experimentalFeatures] + ); + + const filteredConfig = useMemo( + () => + onboardingConfig.reduce((filteredTopicConfigs, topicConfig) => { + if (!isAvailable(topicConfig)) { + return filteredTopicConfigs; + } + const filteredBody = topicConfig.body.reduce( + (filteredGroups, group) => { + const filteredCards = group.cards.filter(isAvailable); + + if (filteredCards.length > 0) { + filteredGroups.push({ ...group, cards: filteredCards }); + } + return filteredGroups; + }, + [] + ); + if (filteredBody.length > 0) { + filteredTopicConfigs.set(topicConfig.id, { ...topicConfig, body: filteredBody }); + } + return filteredTopicConfigs; + }, new Map()), + [isAvailable] + ); + + return filteredConfig; +}; + +const useOnboardingTelemetry = (): OnboardingTelemetry => { + const { telemetry } = useKibana().services; + return useMemo( + () => ({ + reportCardOpen: (cardId, { auto = false } = {}) => { + telemetry.reportEvent(OnboardingHubEventTypes.OnboardingHubStepOpen, { + stepId: cardId, + trigger: auto ? 'navigation' : 'click', + }); + }, + reportCardComplete: (cardId, { auto = false } = {}) => { + telemetry.reportEvent(OnboardingHubEventTypes.OnboardingHubStepFinished, { + stepId: cardId, + trigger: auto ? 'auto_check' : 'click', + }); + }, + reportCardLinkClicked: (cardId, linkId: string) => { + telemetry.reportEvent(OnboardingHubEventTypes.OnboardingHubStepLinkClicked, { + originStepId: cardId, + stepLinkId: linkId, + }); + }, + }), + [telemetry] + ); +}; diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_footer/onboarding_footer.test.tsx b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_footer/onboarding_footer.test.tsx index ae80d0c9273c3..2b663add12248 100644 --- a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_footer/onboarding_footer.test.tsx +++ b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_footer/onboarding_footer.test.tsx @@ -7,11 +7,11 @@ import React from 'react'; import { render } from '@testing-library/react'; -import { trackOnboardingLinkClick } from '../../common/lib/telemetry'; +import { trackOnboardingLinkClick } from '../lib/telemetry'; import { FooterLinkItem } from './onboarding_footer'; import { OnboardingFooterLinkItemId, TELEMETRY_FOOTER_LINK } from './constants'; -jest.mock('../../common/lib/telemetry'); +jest.mock('../lib/telemetry'); describe('OnboardingFooterComponent', () => { beforeEach(() => { diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_footer/onboarding_footer.tsx b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_footer/onboarding_footer.tsx index 125d2af118d3f..9db64386be067 100644 --- a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_footer/onboarding_footer.tsx +++ b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_footer/onboarding_footer.tsx @@ -9,7 +9,7 @@ import React, { useCallback } from 'react'; import { EuiFlexGroup, EuiFlexItem, EuiLink, EuiSpacer, EuiText, EuiTitle } from '@elastic/eui'; import { useFooterStyles } from './onboarding_footer.styles'; import { useFooterItems } from './footer_items'; -import { trackOnboardingLinkClick } from '../../common/lib/telemetry'; +import { trackOnboardingLinkClick } from '../lib/telemetry'; import type { OnboardingFooterLinkItemId } from './constants'; import { TELEMETRY_FOOTER_LINK } from './constants'; diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_header/cards/common/link_card.test.tsx b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_header/cards/common/link_card.test.tsx index 83bfa317d8fbb..febc8431627b8 100644 --- a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_header/cards/common/link_card.test.tsx +++ b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_header/cards/common/link_card.test.tsx @@ -8,10 +8,10 @@ import React from 'react'; import { render } from '@testing-library/react'; import { LinkCard } from './link_card'; -import { OnboardingHeaderCardId, TELEMETRY_HEADER_CARD } from '../../../constants'; -import { trackOnboardingLinkClick } from '../../../../common/lib/telemetry'; +import { OnboardingHeaderCardId, TELEMETRY_HEADER_CARD } from '../../constants'; +import { trackOnboardingLinkClick } from '../../../lib/telemetry'; -jest.mock('../../../../common/lib/telemetry'); +jest.mock('../../../lib/telemetry'); describe('DataIngestionHubHeaderCardComponent', () => { beforeEach(() => { diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_header/cards/common/link_card.tsx b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_header/cards/common/link_card.tsx index 12b3877628dbc..71ab7b007b35f 100644 --- a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_header/cards/common/link_card.tsx +++ b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_header/cards/common/link_card.tsx @@ -8,10 +8,10 @@ import React, { useCallback } from 'react'; import { EuiCard, EuiImage, EuiLink, EuiSpacer, EuiText, EuiTitle } from '@elastic/eui'; import classNames from 'classnames'; -import { trackOnboardingLinkClick } from '../../../../common/lib/telemetry'; +import { trackOnboardingLinkClick } from '../../../lib/telemetry'; import { useCardStyles } from './link_card.styles'; -import type { OnboardingHeaderCardId } from '../../../constants'; -import { TELEMETRY_HEADER_CARD } from '../../../constants'; +import type { OnboardingHeaderCardId } from '../../constants'; +import { TELEMETRY_HEADER_CARD } from '../../constants'; interface LinkCardProps { id: OnboardingHeaderCardId; diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_header/cards/demo_card/demo_card.tsx b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_header/cards/demo_card/demo_card.tsx index b86ae2dcd219d..9daf13527108d 100644 --- a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_header/cards/demo_card/demo_card.tsx +++ b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_header/cards/demo_card/demo_card.tsx @@ -10,7 +10,7 @@ import { LinkCard } from '../common/link_card'; import demoImage from './images/demo_card.png'; import darkDemoImage from './images/demo_card_dark.png'; import * as i18n from './translations'; -import { OnboardingHeaderCardId } from '../../../constants'; +import { OnboardingHeaderCardId } from '../../constants'; export const DemoCard = React.memo<{ isDarkMode: boolean }>(({ isDarkMode }) => { return ( diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_header/cards/teammates_card/teammates_card.tsx b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_header/cards/teammates_card/teammates_card.tsx index 81e6ffb3657fe..0a425acd0a93f 100644 --- a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_header/cards/teammates_card/teammates_card.tsx +++ b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_header/cards/teammates_card/teammates_card.tsx @@ -7,8 +7,8 @@ import React from 'react'; import useObservable from 'react-use/lib/useObservable'; -import { OnboardingHeaderCardId } from '../../../constants'; -import { useOnboardingService } from '../../../../hooks/use_onboarding_service'; +import { OnboardingHeaderCardId } from '../../constants'; +import { useOnboardingService } from '../../../hooks/use_onboarding_service'; import { LinkCard } from '../common/link_card'; import teammatesImage from './images/teammates_card.png'; import darkTeammatesImage from './images/teammates_card_dark.png'; diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_header/cards/video_card/video_card.tsx b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_header/cards/video_card/video_card.tsx index 2e91b7374c505..15a8950aed277 100644 --- a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_header/cards/video_card/video_card.tsx +++ b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_header/cards/video_card/video_card.tsx @@ -6,7 +6,7 @@ */ import React, { useCallback, useState } from 'react'; -import { OnboardingHeaderCardId } from '../../../constants'; +import { OnboardingHeaderCardId } from '../../constants'; import { OnboardingHeaderVideoModal } from './video_modal'; import * as i18n from './translations'; import videoImage from './images/video_card.png'; diff --git a/x-pack/plugins/security_solution/public/onboarding/components/constants.ts b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_header/constants.ts similarity index 100% rename from x-pack/plugins/security_solution/public/onboarding/components/constants.ts rename to x-pack/plugins/security_solution/public/onboarding/components/onboarding_header/constants.ts diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_header/onboarding_header.styles.ts b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_header/onboarding_header.styles.ts index 34cc060a97386..40cfd7a5d9e1f 100644 --- a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_header/onboarding_header.styles.ts +++ b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_header/onboarding_header.styles.ts @@ -18,5 +18,8 @@ export const useOnboardingHeaderStyles = () => { .onboardingHeaderGreetings { color: ${euiTheme.colors.darkShade}; } + .onboardingHeaderTopicSelector { + width: calc(${PAGE_CONTENT_WIDTH} / 3); + } `; }; diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_header/onboarding_header.tsx b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_header/onboarding_header.tsx index 0210c88186a9a..1175c125e6a81 100644 --- a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_header/onboarding_header.tsx +++ b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_header/onboarding_header.tsx @@ -17,6 +17,7 @@ import { useEuiTheme, } from '@elastic/eui'; import { useCurrentUser } from '../../../common/lib/kibana/hooks'; +import { OnboardingHeaderTopicSelector } from './onboarding_header_topic_selector'; import { useOnboardingHeaderStyles } from './onboarding_header.styles'; import rocketImage from './images/header_rocket.png'; import rocketDarkImage from './images/header_rocket_dark.png'; @@ -42,23 +43,25 @@ export const OnboardingHeader = React.memo(() => { {currentUserName && ( - {i18n.GET_STARTED_PAGE_TITLE(currentUserName)} + {i18n.ONBOARDING_PAGE_TITLE(currentUserName)} )} -

        {i18n.GET_STARTED_DATA_INGESTION_HUB_SUBTITLE}

        +

        {i18n.ONBOARDING_PAGE_SUBTITLE}

        - {i18n.GET_STARTED_DATA_INGESTION_HUB_DESCRIPTION} + {i18n.ONBOARDING_PAGE_DESCRIPTION} + +
        diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_header/onboarding_header_topic_selector.tsx b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_header/onboarding_header_topic_selector.tsx new file mode 100644 index 0000000000000..c949f51d23da1 --- /dev/null +++ b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_header/onboarding_header_topic_selector.tsx @@ -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 React, { useMemo } from 'react'; +import { EuiButtonGroup } from '@elastic/eui'; +import type { OnboardingTopicId } from '../../constants'; +import { useOnboardingContext } from '../onboarding_context'; +import { useTopic } from '../hooks/use_topic_id'; + +export const OnboardingHeaderTopicSelector = React.memo(() => { + const { config } = useOnboardingContext(); + const [topicId, setTopicId] = useTopic(); + + const selectorOptions = useMemo( + () => + [...config.values()].map((topicConfig) => ({ + id: topicConfig.id, + label: topicConfig.title, + })), + [config] + ); + + if (selectorOptions.length < 2) { + return null; + } + + return ( + setTopicId(id as OnboardingTopicId)} + isFullWidth + /> + ); +}); +OnboardingHeaderTopicSelector.displayName = 'OnboardingHeaderTopicSelector'; diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_header/translations.ts b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_header/translations.ts index c1f8ca8695bb6..62eadcdcd83a6 100644 --- a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_header/translations.ts +++ b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_header/translations.ts @@ -7,22 +7,36 @@ import { i18n } from '@kbn/i18n'; -export const GET_STARTED_PAGE_TITLE = (userName: string) => +export const ONBOARDING_PAGE_TITLE = (userName: string) => i18n.translate('xpack.securitySolution.onboarding.Title', { defaultMessage: `Hi {userName}!`, values: { userName }, }); -export const GET_STARTED_DATA_INGESTION_HUB_SUBTITLE = i18n.translate( +export const ONBOARDING_PAGE_SUBTITLE = i18n.translate( 'xpack.securitySolution.onboarding.subTitle', { defaultMessage: `Welcome to Elastic Security`, } ); -export const GET_STARTED_DATA_INGESTION_HUB_DESCRIPTION = i18n.translate( +export const ONBOARDING_PAGE_DESCRIPTION = i18n.translate( 'xpack.securitySolution.onboarding.description', { defaultMessage: `A SIEM with AI-driven security analytics, XDR and Cloud Security.`, } ); + +export const ONBOARDING_PAGE_DEFAULT_TOPIC = i18n.translate( + 'xpack.securitySolution.onboarding.topic.default', + { + defaultMessage: 'Set up security', + } +); + +export const ONBOARDING_PAGE_SIEM_MIGRATIONS_TOPIC = i18n.translate( + 'xpack.securitySolution.onboarding.topic.siemMigrations', + { + defaultMessage: 'SIEM Rule migration', + } +); diff --git a/x-pack/plugins/security_solution/public/onboarding/components/onboarding_route.tsx b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_route.tsx new file mode 100644 index 0000000000000..6e7dca524ce81 --- /dev/null +++ b/x-pack/plugins/security_solution/public/onboarding/components/onboarding_route.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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useEffect } from 'react'; + +import type { RouteComponentProps } from 'react-router-dom'; +import { OnboardingHeader } from './onboarding_header'; +import { OnboardingBody } from './onboarding_body'; +import type { OnboardingRouteParams } from '../types'; +import { getCardIdFromHash, useUrlDetail } from './hooks/use_url_detail'; + +type OnboardingRouteProps = RouteComponentProps; + +export const OnboardingRoute = React.memo(({ match, location }) => { + const { syncUrlDetails } = useUrlDetail(); + + /** + * This effect syncs the URL details with the stored state, it only needs to be executed once per page load. + */ + useEffect(() => { + const pathTopicId = match.params.topicId || null; + const hashCardId = getCardIdFromHash(location.hash); + syncUrlDetails(pathTopicId, hashCardId); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + return ( + <> + + + + ); +}); +OnboardingRoute.displayName = 'OnboardingContent'; diff --git a/x-pack/plugins/security_solution/public/onboarding/config.ts b/x-pack/plugins/security_solution/public/onboarding/config.ts new file mode 100644 index 0000000000000..a8f5909f9b059 --- /dev/null +++ b/x-pack/plugins/security_solution/public/onboarding/config.ts @@ -0,0 +1,33 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; +import { OnboardingTopicId } from './constants'; +import { + defaultBodyConfig, + siemMigrationsBodyConfig, +} from './components/onboarding_body/body_config'; +import type { TopicConfig } from './types'; + +export const onboardingConfig: TopicConfig[] = [ + { + id: OnboardingTopicId.default, + title: i18n.translate('xpack.securitySolution.onboarding.topic.default', { + defaultMessage: 'Set up security', + }), + body: defaultBodyConfig, + }, + { + id: OnboardingTopicId.siemMigrations, + title: i18n.translate('xpack.securitySolution.onboarding.topic.siemMigrations', { + defaultMessage: 'SIEM Rule migration', + }), + body: siemMigrationsBodyConfig, + licenseTypeRequired: 'enterprise', + experimentalFlagRequired: 'siemMigrationsEnabled', + }, +]; diff --git a/x-pack/plugins/security_solution/public/onboarding/constants.ts b/x-pack/plugins/security_solution/public/onboarding/constants.ts index 0eb277bd61875..e360e4591bb37 100644 --- a/x-pack/plugins/security_solution/public/onboarding/constants.ts +++ b/x-pack/plugins/security_solution/public/onboarding/constants.ts @@ -6,6 +6,11 @@ */ export const PAGE_CONTENT_WIDTH = '1150px'; +export enum OnboardingTopicId { + default = 'default', + siemMigrations = 'siem_migrations', +} + export enum OnboardingCardId { integrations = 'integrations', dashboards = 'dashboards', @@ -13,4 +18,7 @@ export enum OnboardingCardId { alerts = 'alerts', assistant = 'assistant', attackDiscovery = 'attack_discovery', + + // siem_migrations topic cards + siemMigrationsAiConnectors = 'ai_connectors', } diff --git a/x-pack/plugins/security_solution/public/onboarding/types.ts b/x-pack/plugins/security_solution/public/onboarding/types.ts index 9dfe1e75596db..d9c5aa2c9bc20 100644 --- a/x-pack/plugins/security_solution/public/onboarding/types.ts +++ b/x-pack/plugins/security_solution/public/onboarding/types.ts @@ -9,7 +9,8 @@ import type React from 'react'; import type { IconType } from '@elastic/eui'; import type { LicenseType } from '@kbn/licensing-plugin/public'; -import type { OnboardingCardId } from './constants'; +import type { ExperimentalFeatures } from '../../common'; +import type { OnboardingTopicId, OnboardingCardId } from './constants'; import type { RequiredCapabilities } from '../common/lib/capabilities'; import type { StartServices } from '../types'; @@ -41,6 +42,7 @@ export type CheckCompleteResponse = export type SetComplete = (isComplete: boolean) => void; export type IsCardComplete = (cardId: OnboardingCardId) => boolean; +export type IsCardAvailable = (cardId: OnboardingCardId) => boolean; export type SetExpandedCardId = ( cardId: OnboardingCardId | null, options?: { scroll?: boolean } @@ -59,6 +61,10 @@ export type OnboardingCardComponent = React.Component * Function to check if a specific card is complete. */ isCardComplete: IsCardComplete; + /** + * Function to check if a specific card is rendered. + */ + isCardAvailable: IsCardAvailable; /** * Function to expand a specific card ID and scroll to it. */ @@ -74,31 +80,17 @@ export type OnboardingCardCheckComplete = ( services: StartServices ) => Promise>; -export interface OnboardingCardConfig { - id: OnboardingCardId; - title: string; - icon: IconType; - /** - * Component that renders the card content when expanded. - * It receives a `setComplete` function to allow the card to mark itself as complete if needed. - * Please use React.lazy() to load the component. - */ - Component: React.LazyExoticComponent>; +export interface OnboardingConfigAvailabilityProps { /** - * Function for auto-checking completion for the card - * @returns Promise for the complete status - */ - checkComplete?: OnboardingCardCheckComplete; - /** - * The RBAC capability strings required to enable the card. It uses object dot notation. e.g. `'siem.crud'`. + * The RBAC capability strings required to enable the item. It uses object dot notation. e.g. `'siem.crud'`. * * The format of the capabilities property supports OR and AND mechanism: * * To specify capabilities in an OR fashion, they can be defined in a single level array like: `capabilities: [cap1, cap2]`. - * If either of "cap1 || cap2" is granted the card will be included. + * If either of "cap1 || cap2" is granted the item will be included. * * To specify capabilities with AND conditional, use a second level array: `capabilities: [['cap1', 'cap2']]`. - * This would result in the boolean expression "cap1 && cap2", both capabilities must be granted to include the card. + * This would result in the boolean expression "cap1 && cap2", both capabilities must be granted to include the item. * * They can also be combined like: `capabilities: ['cap1', ['cap2', 'cap3']]` which would result in the boolean expression "cap1 || (cap2 && cap3)". * @@ -106,12 +98,34 @@ export interface OnboardingCardConfig { * * Default is `undefined` (no capabilities required) */ - capabilities?: RequiredCapabilities; + capabilitiesRequired?: RequiredCapabilities; /** - * Minimum license required to enable the card. + * Minimum license required to enable the item. * Default is `basic` */ - licenseType?: LicenseType; + licenseTypeRequired?: LicenseType; + /** + * The experimental features required to enable the item. + */ + experimentalFlagRequired?: keyof ExperimentalFeatures; +} + +export interface OnboardingCardConfig + extends OnboardingConfigAvailabilityProps { + id: OnboardingCardId; + title: string; + icon: IconType; + /** + * Component that renders the card content when expanded. + * It receives a `setComplete` function to allow the card to mark itself as complete if needed. + * Please use React.lazy() to load the component. + */ + Component: React.LazyExoticComponent>; + /** + * Function for auto-checking completion for the card + * @returns Promise for the complete status + */ + checkComplete?: OnboardingCardCheckComplete; } export interface OnboardingGroupConfig { @@ -120,3 +134,19 @@ export interface OnboardingGroupConfig { // eslint-disable-next-line @typescript-eslint/no-explicit-any cards: Array>; } + +export interface TopicConfig extends OnboardingConfigAvailabilityProps { + id: OnboardingTopicId; + /** + * The onboarding topic title. + */ + title: string; + /** + * The onboarding body configuration. + */ + body: OnboardingGroupConfig[]; +} + +export interface OnboardingRouteParams { + topicId?: OnboardingTopicId; +} diff --git a/x-pack/plugins/security_solution/public/one_discover/app_wrapper/index.tsx b/x-pack/plugins/security_solution/public/one_discover/app_wrapper/index.tsx new file mode 100644 index 0000000000000..eb5c325475f2c --- /dev/null +++ b/x-pack/plugins/security_solution/public/one_discover/app_wrapper/index.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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import React, { useMemo } from 'react'; +import { ExpandableFlyoutProvider } from '@kbn/expandable-flyout'; +import { Provider as ReduxStoreProvider } from 'react-redux'; +import { EuiThemeProvider } from '@kbn/kibana-react-plugin/common'; +import { KibanaContextProvider, useKibana } from '@kbn/kibana-react-plugin/public'; +import { NavigationProvider } from '@kbn/security-solution-navigation'; +import type { CoreStart } from '@kbn/core/public'; +import type { SecuritySolutionAppWrapperFeature } from '@kbn/discover-shared-plugin/public'; +import type { DiscoverServices } from '@kbn/discover-plugin/public'; +import { CellActionsProvider } from '@kbn/cell-actions'; +import { APP_ID } from '../../../common'; +import { SecuritySolutionFlyout } from '../../flyout'; +import { StatefulEventContext } from '../../common/components/events_viewer/stateful_event_context'; +import type { SecurityAppStore } from '../../common/store'; +import { ReactQueryClientProvider } from '../../common/containers/query_client/query_client_provider'; +import type { StartPluginsDependencies, StartServices } from '../../types'; +import { MlCapabilitiesProvider } from '../../common/components/ml/permissions/ml_capabilities_provider'; +import { UserPrivilegesProvider } from '../../common/components/user_privileges/user_privileges_context'; +import { DiscoverInTimelineContextProvider } from '../../common/components/discover_in_timeline/provider'; +import { UpsellingProvider } from '../../common/components/upselling_provider'; +import { ConsoleManager } from '../../management/components/console'; +import { AssistantProvider } from '../../assistant/provider'; +import { ONE_DISCOVER_SCOPE_ID } from '../constants'; + +export const createSecuritySolutionDiscoverAppWrapperGetter = ({ + core, + services, + plugins, + store, +}: { + core: CoreStart; + services: StartServices; + plugins: StartPluginsDependencies; + /** + * instance of Security App store that should be used in Discover + */ + store: SecurityAppStore; +}) => { + const getSecuritySolutionDiscoverAppWrapper: Awaited< + ReturnType + > = () => { + return function SecuritySolutionDiscoverAppWrapper({ children }) { + const { services: discoverServices } = useKibana(); + const CasesContext = useMemo(() => plugins.cases.ui.getCasesContext(), []); + + const userCasesPermissions = useMemo(() => plugins.cases.helpers.canUseCases([APP_ID]), []); + + /** + * + * Since this component is meant to be used only in the context of Discover, + * these services are appended/overwritten to the existing services object + * provided by the Discover plugin. + * + */ + const securitySolutionServices: StartServices = useMemo( + () => ({ + ...services, + /* Helps with getting correct instance of query, timeFilter and filterManager instances from discover */ + data: discoverServices.data, + }), + [discoverServices] + ); + + const statefulEventContextValue = useMemo( + () => ({ + // timelineId acts as scopeId + timelineID: ONE_DISCOVER_SCOPE_ID, + enableHostDetailsFlyout: true, + /* behaviour similar to query tab */ + tabType: 'query', + enableIpDetailsFlyout: true, + }), + [] + ); + + return ( + + + + + + {/* ^_^ Needed for notes addition */} + + + {/* ^_^ Needed for Cell Actions since it gives errors when CellActionsContext is used */} + + {/* ^_^ Needed for Alert Preview from Expanded Section of Entity Flyout */} + + + + {/* ^_^ Needed for AlertPreview -> Alert Details Flyout Action */} + + {/* ^_^ Needed for AlertPreview -> Alert Details Flyout Action */} + + {/* ^_^ Needed for Add to Timeline action by `useRiskInputActions`*/} + + + {/* vv below context should not be here and should be removed */} + + {children} + + + + + + + + + + + + + + + + ); + }; + }; + + return getSecuritySolutionDiscoverAppWrapper; +}; diff --git a/x-pack/plugins/security_solution/public/one_discover/cell_renderers/cell_renderer.test.tsx b/x-pack/plugins/security_solution/public/one_discover/cell_renderers/cell_renderer.test.tsx new file mode 100644 index 0000000000000..4bb1eec75cc26 --- /dev/null +++ b/x-pack/plugins/security_solution/public/one_discover/cell_renderers/cell_renderer.test.tsx @@ -0,0 +1,105 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { DefaultCellRenderer } from '../../timelines/components/timeline/cell_rendering/default_cell_renderer'; +import { render } from '@testing-library/react'; +import { getCellRendererForGivenRecord } from './cell_renderers'; +import type { DataGridCellValueElementProps } from '@kbn/unified-data-table'; +import type { DataViewField } from '@kbn/data-views-plugin/common'; +import { dataViewMock } from '@kbn/discover-utils/src/__mocks__'; +import { fieldFormatsMock } from '@kbn/field-formats-plugin/common/mocks'; + +jest.mock('../../timelines/components/timeline/cell_rendering/default_cell_renderer'); + +const DefaultCellRendererMock = DefaultCellRenderer as unknown as jest.Mock; + +/** + * Mocking DefaultCellRenderer here because it will be renderered + * in Discover's environment and context and we cannot test that here in jest. + * + * Actual working of Cell Renderer will be tested in Discover's functional tests + * + * */ +const mockDefaultCellRenderer = jest.fn((props) => { + return
        ; +}); + +const mockDataView = dataViewMock; +mockDataView.getFieldByName = jest.fn().mockReturnValue({ type: 'string' } as DataViewField); + +describe('getCellRendererForGivenRecord', () => { + beforeEach(() => { + DefaultCellRendererMock.mockImplementation(mockDefaultCellRenderer); + }); + + afterEach(() => { + jest.clearAllMocks(); + }); + + it('should return cell renderer correctly for allowed fields with correct data format', () => { + const cellRenderer = getCellRendererForGivenRecord('host.name'); + expect(cellRenderer).toBeDefined(); + const props: DataGridCellValueElementProps = { + columnId: 'host.name', + isDetails: false, + isExpanded: false, + row: { + id: '1', + raw: {}, + flattened: { + 'host.name': 'host1', + 'user.name': 'user1', + }, + }, + dataView: mockDataView, + setCellProps: jest.fn(), + isExpandable: false, + rowIndex: 0, + colIndex: 0, + fieldFormats: fieldFormatsMock, + closePopover: jest.fn(), + }; + const CellRenderer = cellRenderer as React.FC; + const { getByTestId } = render(); + expect(getByTestId('mocked-default-cell-render')).toBeVisible(); + expect(mockDefaultCellRenderer).toHaveBeenCalledWith( + { + isDraggable: false, + isTimeline: false, + isDetails: false, + data: [ + { field: 'host.name', value: ['host1'] }, + { field: 'user.name', value: ['user1'] }, + ], + eventId: '1', + scopeId: 'one-discover', + linkValues: undefined, + header: { + id: 'host.name', + columnHeaderType: 'not-filtered', + type: 'string', + }, + asPlainText: false, + context: undefined, + rowRenderers: undefined, + ecsData: undefined, + colIndex: 0, + rowIndex: 0, + isExpandable: false, + isExpanded: false, + setCellProps: props.setCellProps, + columnId: 'host.name', + }, + {} + ); + }); + it('should return undefined for non-allowedFields', () => { + const cellRenderer = getCellRendererForGivenRecord('non-allowed-field'); + expect(cellRenderer).toBeUndefined(); + }); +}); diff --git a/x-pack/plugins/security_solution/public/one_discover/cell_renderers/cell_renderers.tsx b/x-pack/plugins/security_solution/public/one_discover/cell_renderers/cell_renderers.tsx new file mode 100644 index 0000000000000..7ecc73e404160 --- /dev/null +++ b/x-pack/plugins/security_solution/public/one_discover/cell_renderers/cell_renderers.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, { useMemo } from 'react'; +import type { DataGridCellValueElementProps } from '@kbn/unified-data-table'; +import type { TimelineNonEcsData } from '@kbn/timelines-plugin/common'; +import type { SecuritySolutionCellRendererFeature } from '@kbn/discover-shared-plugin/public'; +import type { ColumnHeaderType } from '../../../common/types'; +import type { Maybe } from '../../../common/search_strategy'; +import { DefaultCellRenderer } from '../../timelines/components/timeline/cell_rendering/default_cell_renderer'; +import { ONE_DISCOVER_SCOPE_ID } from '../constants'; + +export type SecuritySolutionRowCellRendererGetter = Awaited< + ReturnType +>; + +const ALLOWED_DISCOVER_RENDERED_FIELDS = ['host.name', 'user.name', 'source.ip', 'destination.ip']; + +export const getCellRendererForGivenRecord: SecuritySolutionRowCellRendererGetter = ( + fieldName: string +) => { + if (!ALLOWED_DISCOVER_RENDERED_FIELDS.includes(fieldName)) return undefined; + return function UnifiedFieldRenderBySecuritySolution(props: DataGridCellValueElementProps) { + // convert discover data format to timeline data format + const data: TimelineNonEcsData[] = useMemo( + () => + Object.keys(props.row.flattened).map((field) => ({ + field, + value: Array.isArray(props.row.flattened[field]) + ? (props.row.flattened[field] as Maybe) + : ([props.row.flattened[field]] as Maybe), + })), + [props.row.flattened] + ); + + const header = useMemo(() => { + return { + id: props.columnId, + columnHeaderType: 'not-filtered' as ColumnHeaderType, + type: props.dataView.getFieldByName(props.columnId)?.type, + }; + }, [props.columnId, props.dataView]); + + return ( + + ); + }; +}; diff --git a/x-pack/plugins/security_solution/public/one_discover/cell_renderers/index.ts b/x-pack/plugins/security_solution/public/one_discover/cell_renderers/index.ts new file mode 100644 index 0000000000000..2ec3ff99073df --- /dev/null +++ b/x-pack/plugins/security_solution/public/one_discover/cell_renderers/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 { getCellRendererForGivenRecord } from './cell_renderers'; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/error_connecting/index.ts b/x-pack/plugins/security_solution/public/one_discover/constants.ts similarity index 82% rename from x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/error_connecting/index.ts rename to x-pack/plugins/security_solution/public/one_discover/constants.ts index 59ac4e0e37efe..f4e779c62cc3d 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/error_connecting/index.ts +++ b/x-pack/plugins/security_solution/public/one_discover/constants.ts @@ -5,4 +5,4 @@ * 2.0. */ -export { ErrorConnecting } from './error_connecting'; +export const ONE_DISCOVER_SCOPE_ID = 'one-discover'; diff --git a/x-pack/plugins/index_management/public/application/components/enrich_policies/index.ts b/x-pack/plugins/security_solution/public/one_discover/index.tsx similarity index 64% rename from x-pack/plugins/index_management/public/application/components/enrich_policies/index.ts rename to x-pack/plugins/security_solution/public/one_discover/index.tsx index de8fa4ebf5ac7..a7aefd28551bf 100644 --- a/x-pack/plugins/index_management/public/application/components/enrich_policies/index.ts +++ b/x-pack/plugins/security_solution/public/one_discover/index.tsx @@ -5,5 +5,5 @@ * 2.0. */ -export { EnrichPoliciesWithPrivileges } from './with_privileges'; -export { EnrichPoliciesAuthProvider } from './auth_provider'; +export { getCellRendererForGivenRecord } from './cell_renderers'; +export { createSecuritySolutionDiscoverAppWrapperGetter } from './app_wrapper'; diff --git a/x-pack/plugins/security_solution/public/one_discover/jest.config.js b/x-pack/plugins/security_solution/public/one_discover/jest.config.js new file mode 100644 index 0000000000000..7e4552f72e98f --- /dev/null +++ b/x-pack/plugins/security_solution/public/one_discover/jest.config.js @@ -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. + */ + +module.exports = { + preset: '@kbn/test', + rootDir: '../../../../..', + roots: ['/x-pack/plugins/security_solution/public/one_discover'], + coverageDirectory: + '/target/kibana-coverage/jest/x-pack/plugins/security_solution/public/one_discover', + coverageReporters: ['text', 'html'], + collectCoverageFrom: [ + '/x-pack/plugins/security_solution/public/one_discover/**/*.{ts,tsx}', + ], + moduleNameMapper: require('../../server/__mocks__/module_name_map'), +}; diff --git a/x-pack/plugins/security_solution/public/plugin.tsx b/x-pack/plugins/security_solution/public/plugin.tsx index f933832264247..497b92637dad5 100644 --- a/x-pack/plugins/security_solution/public/plugin.tsx +++ b/x-pack/plugins/security_solution/public/plugin.tsx @@ -21,6 +21,10 @@ import { AppStatus, DEFAULT_APP_CATEGORIES } from '@kbn/core/public'; import { Storage } from '@kbn/kibana-utils-plugin/public'; import type { TriggersAndActionsUIPublicPluginSetup } from '@kbn/triggers-actions-ui-plugin/public'; import { uiMetricService } from '@kbn/cloud-security-posture-common/utils/ui_metrics'; +import type { + SecuritySolutionAppWrapperFeature, + SecuritySolutionCellRendererFeature, +} from '@kbn/discover-shared-plugin/public/services/discover_features'; import { getLazyCloudSecurityPosturePliAuthBlockExtension } from './cloud_security_posture/lazy_cloud_security_posture_pli_auth_block_extension'; import { getLazyEndpointAgentTamperProtectionExtension } from './management/pages/policy/view/ingest_manager_integration/lazy_endpoint_agent_tamper_protection_extension'; import type { @@ -70,6 +74,7 @@ export class Plugin implements IPlugin, + plugins: SetupPlugins + ) { + const { discoverShared } = plugins; + const discoverFeatureRegistry = discoverShared.features.registry; + const cellRendererFeature: SecuritySolutionCellRendererFeature = { + id: 'security-solution-cell-renderer', + getRenderer: async () => { + const { getCellRendererForGivenRecord } = await this.getLazyDiscoverSharedDeps(); + return getCellRendererForGivenRecord; + }, + }; + + const appWrapperFeature: SecuritySolutionAppWrapperFeature = { + id: 'security-solution-app-wrapper', + getWrapper: async () => { + const [coreStart, startPlugins] = await core.getStartServices(); + + const services = await this.services.generateServices(coreStart, startPlugins); + const subPlugins = await this.startSubPlugins(this.storage, coreStart, startPlugins); + const securityStoreForDiscover = await this.getStoreForDiscover( + coreStart, + startPlugins, + subPlugins + ); + + const { createSecuritySolutionDiscoverAppWrapperGetter } = + await this.getLazyDiscoverSharedDeps(); + + return createSecuritySolutionDiscoverAppWrapperGetter({ + core: coreStart, + services, + plugins: startPlugins, + store: securityStoreForDiscover, + }); + }, + }; + + discoverFeatureRegistry.register(cellRendererFeature); + discoverFeatureRegistry.register(appWrapperFeature); + } + + public async getLazyDiscoverSharedDeps() { + /** + * The specially formatted comment in the `import` expression causes the corresponding webpack chunk to be named. This aids us in debugging chunk size issues. + * See https://webpack.js.org/api/module-methods/#magic-comments + */ + return import( + /* webpackChunkName: "one_discover_shared_deps" */ + './one_discover' + ); + } + /** * SubPlugins are the individual building blocks of the Security Solution plugin. * They are lazily instantiated to improve startup time. @@ -311,6 +372,31 @@ export class Plugin implements IPlugin { + if (!this._securityStoreForDiscover) { + const { createStoreFactory } = await this.lazyApplicationDependencies(); + + this._securityStoreForDiscover = await createStoreFactory( + coreStart, + startPlugins, + subPlugins, + this.storage, + this.experimentalFeatures + ); + } + if (startPlugins.timelines) { + startPlugins.timelines.setTimelineEmbeddedStore(this._securityStoreForDiscover); + } + return this._securityStoreForDiscover; + } + private async registerActions( store: SecurityAppStore, history: H.History, diff --git a/x-pack/plugins/security_solution/public/plugin_services.ts b/x-pack/plugins/security_solution/public/plugin_services.ts index 92b4bc586a5b6..cd066da31f549 100644 --- a/x-pack/plugins/security_solution/public/plugin_services.ts +++ b/x-pack/plugins/security_solution/public/plugin_services.ts @@ -153,7 +153,7 @@ export class PluginServices { customDataService, timelineDataService, topValuesPopover: new TopValuesPopoverService(), - siemMigrations: await createSiemMigrationsService(coreStart), + siemMigrations: await createSiemMigrationsService(coreStart, startPlugins), ...(params && { onAppLeave: params.onAppLeave, setHeaderActionMenu: params.setHeaderActionMenu, diff --git a/x-pack/plugins/security_solution/public/siem_migrations/rules/api/api.ts b/x-pack/plugins/security_solution/public/siem_migrations/rules/api/api.ts index 7232cb722bd1a..3b7605e032259 100644 --- a/x-pack/plugins/security_solution/public/siem_migrations/rules/api/api.ts +++ b/x-pack/plugins/security_solution/public/siem_migrations/rules/api/api.ts @@ -11,12 +11,19 @@ import { KibanaServices } from '../../../common/lib/kibana'; import { SIEM_RULE_MIGRATIONS_ALL_STATS_PATH, + SIEM_RULE_MIGRATION_INSTALL_TRANSLATED_PATH, + SIEM_RULE_MIGRATION_INSTALL_PATH, SIEM_RULE_MIGRATION_PATH, + SIEM_RULE_MIGRATION_START_PATH, } from '../../../../common/siem_migrations/constants'; import type { GetAllStatsRuleMigrationResponse, GetRuleMigrationResponse, + InstallTranslatedMigrationRulesResponse, + InstallMigrationRulesResponse, + StartRuleMigrationRequestBody, } from '../../../../common/siem_migrations/model/api/rules/rule_migration.gen'; +import type { InstallTranslatedRulesProps, InstallRulesProps } from '../types'; /** * Retrieves the stats for all the existing migrations, aggregated by `migration_id`. @@ -32,11 +39,31 @@ export const getRuleMigrationsStatsAll = async ({ }): Promise => { return KibanaServices.get().http.fetch( SIEM_RULE_MIGRATIONS_ALL_STATS_PATH, - { - method: 'GET', - version: '1', - signal, - } + { method: 'GET', version: '1', signal } + ); +}; + +/** + * Starts a new migration with the provided rules. + * + * @param migrationId `id` of the migration to start + * @param body The body containing the `connectorId` to use for the migration + * @param signal AbortSignal for cancelling request + * + * @throws An error if response is not OK + */ +export const startRuleMigration = async ({ + migrationId, + body, + signal, +}: { + migrationId: string; + body: StartRuleMigrationRequestBody; + signal: AbortSignal | undefined; +}): Promise => { + return KibanaServices.get().http.put( + replaceParams(SIEM_RULE_MIGRATION_START_PATH, { migration_id: migrationId }), + { body: JSON.stringify(body), version: '1', signal } ); }; @@ -57,8 +84,34 @@ export const getRuleMigrations = async ({ }): Promise => { return KibanaServices.get().http.fetch( replaceParams(SIEM_RULE_MIGRATION_PATH, { migration_id: migrationId }), + { method: 'GET', version: '1', signal } + ); +}; + +export const installMigrationRules = async ({ + migrationId, + ids, + signal, +}: InstallRulesProps): Promise => { + return KibanaServices.get().http.fetch( + replaceParams(SIEM_RULE_MIGRATION_INSTALL_PATH, { migration_id: migrationId }), + { + method: 'POST', + version: '1', + body: JSON.stringify(ids), + signal, + } + ); +}; + +export const installTranslatedMigrationRules = async ({ + migrationId, + signal, +}: InstallTranslatedRulesProps): Promise => { + return KibanaServices.get().http.fetch( + replaceParams(SIEM_RULE_MIGRATION_INSTALL_TRANSLATED_PATH, { migration_id: migrationId }), { - method: 'GET', + method: 'POST', version: '1', signal, } diff --git a/x-pack/plugins/security_solution/public/siem_migrations/rules/api/hooks/use_get_rule_migrations.ts b/x-pack/plugins/security_solution/public/siem_migrations/rules/api/hooks/use_get_migration_rules_query.ts similarity index 58% rename from x-pack/plugins/security_solution/public/siem_migrations/rules/api/hooks/use_get_rule_migrations.ts rename to x-pack/plugins/security_solution/public/siem_migrations/rules/api/hooks/use_get_migration_rules_query.ts index 76cf01c6c35d0..fece8f8c3ca07 100644 --- a/x-pack/plugins/security_solution/public/siem_migrations/rules/api/hooks/use_get_rule_migrations.ts +++ b/x-pack/plugins/security_solution/public/siem_migrations/rules/api/hooks/use_get_migration_rules_query.ts @@ -6,14 +6,15 @@ */ import type { UseQueryOptions } from '@tanstack/react-query'; -import { useQuery } from '@tanstack/react-query'; +import { useQuery, useQueryClient } from '@tanstack/react-query'; import { replaceParams } from '@kbn/openapi-common/shared'; +import { useCallback } from 'react'; import { DEFAULT_QUERY_OPTIONS } from './constants'; import { getRuleMigrations } from '../api'; import type { GetRuleMigrationResponse } from '../../../../../common/siem_migrations/model/api/rules/rule_migration.gen'; import { SIEM_RULE_MIGRATION_PATH } from '../../../../../common/siem_migrations/constants'; -export const useGetRuleMigrationsQuery = ( +export const useGetMigrationRulesQuery = ( migrationId: string, options?: UseQueryOptions ) => { @@ -31,3 +32,23 @@ export const useGetRuleMigrationsQuery = ( } ); }; + +/** + * We should use this hook to invalidate the rule migrations cache. For + * example, rule migrations mutations, like installing a rule, should lead to cache invalidation. + * + * @returns A rule migrations cache invalidation callback + */ +export const useInvalidateGetMigrationRulesQuery = (migrationId: string) => { + const queryClient = useQueryClient(); + + const SPECIFIC_MIGRATION_PATH = replaceParams(SIEM_RULE_MIGRATION_PATH, { + migration_id: migrationId, + }); + + return useCallback(() => { + queryClient.invalidateQueries(['GET', SPECIFIC_MIGRATION_PATH], { + refetchType: 'active', + }); + }, [SPECIFIC_MIGRATION_PATH, queryClient]); +}; diff --git a/x-pack/plugins/security_solution/public/siem_migrations/rules/api/hooks/use_install_all_migration_rules_mutation.ts b/x-pack/plugins/security_solution/public/siem_migrations/rules/api/hooks/use_install_all_migration_rules_mutation.ts new file mode 100644 index 0000000000000..f946dc165450f --- /dev/null +++ b/x-pack/plugins/security_solution/public/siem_migrations/rules/api/hooks/use_install_all_migration_rules_mutation.ts @@ -0,0 +1,39 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import type { UseMutationOptions } from '@tanstack/react-query'; +import { useMutation } from '@tanstack/react-query'; +import type { InstallTranslatedMigrationRulesResponse } from '../../../../../common/siem_migrations/model/api/rules/rule_migration.gen'; +import { SIEM_RULE_MIGRATION_INSTALL_TRANSLATED_PATH } from '../../../../../common/siem_migrations/constants'; +import { installTranslatedMigrationRules } from '../api'; +import { useInvalidateGetMigrationRulesQuery } from './use_get_migration_rules_query'; + +export const INSTALL_ALL_MIGRATION_RULES_MUTATION_KEY = [ + 'POST', + SIEM_RULE_MIGRATION_INSTALL_TRANSLATED_PATH, +]; + +export const useInstallAllMigrationRulesMutation = ( + migrationId: string, + options?: UseMutationOptions +) => { + const invalidateGetRuleMigrationsQuery = useInvalidateGetMigrationRulesQuery(migrationId); + + return useMutation( + () => installTranslatedMigrationRules({ migrationId }), + { + ...options, + mutationKey: INSTALL_ALL_MIGRATION_RULES_MUTATION_KEY, + onSettled: (...args) => { + invalidateGetRuleMigrationsQuery(); + + if (options?.onSettled) { + options.onSettled(...args); + } + }, + } + ); +}; diff --git a/x-pack/plugins/security_solution/public/siem_migrations/rules/api/hooks/use_install_migration_rules_mutation.ts b/x-pack/plugins/security_solution/public/siem_migrations/rules/api/hooks/use_install_migration_rules_mutation.ts new file mode 100644 index 0000000000000..6aaff55e24513 --- /dev/null +++ b/x-pack/plugins/security_solution/public/siem_migrations/rules/api/hooks/use_install_migration_rules_mutation.ts @@ -0,0 +1,36 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import type { UseMutationOptions } from '@tanstack/react-query'; +import { useMutation } from '@tanstack/react-query'; +import type { InstallMigrationRulesResponse } from '../../../../../common/siem_migrations/model/api/rules/rule_migration.gen'; +import { SIEM_RULE_MIGRATION_INSTALL_PATH } from '../../../../../common/siem_migrations/constants'; +import { installMigrationRules } from '../api'; +import { useInvalidateGetMigrationRulesQuery } from './use_get_migration_rules_query'; + +export const INSTALL_MIGRATION_RULES_MUTATION_KEY = ['POST', SIEM_RULE_MIGRATION_INSTALL_PATH]; + +export const useInstallMigrationRulesMutation = ( + migrationId: string, + options?: UseMutationOptions +) => { + const invalidateGetRuleMigrationsQuery = useInvalidateGetMigrationRulesQuery(migrationId); + + return useMutation( + (ids: string[]) => installMigrationRules({ migrationId, ids }), + { + ...options, + mutationKey: INSTALL_MIGRATION_RULES_MUTATION_KEY, + onSettled: (...args) => { + invalidateGetRuleMigrationsQuery(); + + if (options?.onSettled) { + options.onSettled(...args); + } + }, + } + ); +}; diff --git a/x-pack/plugins/security_solution/public/siem_migrations/rules/components/rules_table/bulk_actions.tsx b/x-pack/plugins/security_solution/public/siem_migrations/rules/components/rules_table/bulk_actions.tsx new file mode 100644 index 0000000000000..df6d01d876fce --- /dev/null +++ b/x-pack/plugins/security_solution/public/siem_migrations/rules/components/rules_table/bulk_actions.tsx @@ -0,0 +1,68 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { EuiButton, EuiFlexGroup, EuiFlexItem, EuiLoadingSpinner } from '@elastic/eui'; +import * as i18n from './translations'; + +export interface BulkActionsProps { + isTableLoading: boolean; + numberOfTranslatedRules: number; + numberOfSelectedRules: number; + installTranslatedRule?: () => void; + installSelectedRule?: () => void; +} + +/** + * Collection of buttons to perform bulk actions on migration rules within the SIEM Rules Migrations table. + */ +export const BulkActions: React.FC = React.memo( + ({ + isTableLoading, + numberOfTranslatedRules, + numberOfSelectedRules, + installTranslatedRule, + installSelectedRule, + }) => { + const showInstallTranslatedRulesButton = numberOfTranslatedRules > 0; + const showInstallSelectedRulesButton = + showInstallTranslatedRulesButton && numberOfSelectedRules > 0; + return ( + + {showInstallSelectedRulesButton ? ( + + + {i18n.INSTALL_SELECTED_RULES(numberOfSelectedRules)} + {isTableLoading && } + + + ) : null} + {showInstallTranslatedRulesButton ? ( + + + {i18n.INSTALL_ALL_RULES(numberOfTranslatedRules)} + {isTableLoading && } + + + ) : null} + + ); + } +); +BulkActions.displayName = 'BulkActions'; diff --git a/x-pack/plugins/security_solution/public/siem_migrations/rules/components/rules_table/filters.tsx b/x-pack/plugins/security_solution/public/siem_migrations/rules/components/rules_table/filters.tsx index 5f4ae3098b6a3..25dffc64cccc5 100644 --- a/x-pack/plugins/security_solution/public/siem_migrations/rules/components/rules_table/filters.tsx +++ b/x-pack/plugins/security_solution/public/siem_migrations/rules/components/rules_table/filters.tsx @@ -8,15 +8,10 @@ import { EuiFlexGroup } from '@elastic/eui'; import type { Dispatch, SetStateAction } from 'react'; import React, { useCallback } from 'react'; -import styled from 'styled-components'; import * as i18n from './translations'; import { RuleSearchField } from '../../../../detection_engine/rule_management_ui/components/rules_table/rules_table_filters/rule_search_field'; import type { TableFilterOptions } from '../../hooks/use_filter_rules_to_install'; -const FilterWrapper = styled(EuiFlexGroup)` - margin-bottom: ${({ theme }) => theme.eui.euiSizeM}; -`; - export interface FiltersComponentProps { /** * Currently selected table filter @@ -45,13 +40,13 @@ const FiltersComponent: React.FC = ({ filterOptions, setF ); return ( - + - + ); }; diff --git a/x-pack/plugins/security_solution/public/siem_migrations/rules/components/rules_table/index.tsx b/x-pack/plugins/security_solution/public/siem_migrations/rules/components/rules_table/index.tsx index 0cd3e07ea11a4..16f93a1cdebaf 100644 --- a/x-pack/plugins/security_solution/public/siem_migrations/rules/components/rules_table/index.tsx +++ b/x-pack/plugins/security_solution/public/siem_migrations/rules/components/rules_table/index.tsx @@ -13,8 +13,9 @@ import { EuiSkeletonText, EuiFlexGroup, EuiFlexItem, + EuiSpacer, } from '@elastic/eui'; -import React, { useState } from 'react'; +import React, { useCallback, useMemo, useState } from 'react'; import type { RuleMigration } from '../../../../../common/siem_migrations/model/rule_migration.gen'; import { @@ -24,32 +25,26 @@ import { import { NoItemsMessage } from './no_items_message'; import { Filters } from './filters'; import { useRulesTableColumns } from '../../hooks/use_rules_table_columns'; -import { useGetRuleMigrationsQuery } from '../../api/hooks/use_get_rule_migrations'; import type { TableFilterOptions } from '../../hooks/use_filter_rules_to_install'; import { useFilterRulesToInstall } from '../../hooks/use_filter_rules_to_install'; +import { useRulePreviewFlyout } from '../../hooks/use_rule_preview_flyout'; +import { useInstallMigrationRules } from '../../logic/use_install_migration_rules'; +import { useGetMigrationRules } from '../../logic/use_get_migration_rules'; +import { useInstallAllMigrationRules } from '../../logic/use_install_all_migration_rules'; +import { BulkActions } from './bulk_actions'; export interface RulesTableComponentProps { /** * Selected rule migration id */ migrationId: string; - - /** - * Opens the flyout with the details of the rule migration - * @param rule Rule migration - * @returns - */ - openRulePreview: (rule: RuleMigration) => void; } /** * Table Component for displaying SIEM rules migrations */ -const RulesTableComponent: React.FC = ({ - migrationId, - openRulePreview, -}) => { - const { data: ruleMigrations, isLoading } = useGetRuleMigrationsQuery(migrationId); +const RulesTableComponent: React.FC = ({ migrationId }) => { + const { data: ruleMigrations, isLoading: isDataLoading } = useGetMigrationRules(migrationId); const [selectedRuleMigrations, setSelectedRuleMigrations] = useState([]); @@ -62,10 +57,60 @@ const RulesTableComponent: React.FC = ({ ruleMigrations: ruleMigrations ?? [], }); - const shouldShowProgress = isLoading; + const { mutateAsync: installMigrationRules } = useInstallMigrationRules(migrationId); + const { mutateAsync: installAllMigrationRules } = useInstallAllMigrationRules(migrationId); + + const numberOfTranslatedRules = useMemo(() => { + return filteredRuleMigrations.filter( + (rule) => + !rule.elastic_rule?.id && + (rule.elastic_rule?.prebuilt_rule_id || rule.translation_result === 'full') + ).length; + }, [filteredRuleMigrations]); + + const [isTableLoading, setTableLoading] = useState(false); + const installSingleRule = useCallback( + async (migrationRule: RuleMigration, enable?: boolean) => { + setTableLoading(true); + try { + await installMigrationRules([migrationRule.id]); + } finally { + setTableLoading(false); + } + }, + [installMigrationRules] + ); + + const installTranslatedRules = useCallback( + async (enable?: boolean) => { + setTableLoading(true); + try { + await installAllMigrationRules(); + } finally { + setTableLoading(false); + } + }, + [installAllMigrationRules] + ); + + const ruleActionsFactory = useCallback( + (ruleMigration: RuleMigration, closeRulePreview: () => void) => { + // TODO: Add flyout action buttons + return null; + }, + [] + ); + + const { rulePreviewFlyout, openRulePreview } = useRulePreviewFlyout({ + ruleActionsFactory, + }); + + const shouldShowProgress = isDataLoading; const rulesColumns = useRulesTableColumns({ - openRulePreview, + disableActions: isTableLoading, + openMigrationRulePreview: openRulePreview, + installMigrationRule: installSingleRule, }); return ( @@ -79,7 +124,7 @@ const RulesTableComponent: React.FC = ({ /> )} @@ -91,13 +136,22 @@ const RulesTableComponent: React.FC = ({ ) : ( <> - - + + + + + - + = ({ ) } /> + {rulePreviewFlyout} ); }; diff --git a/x-pack/plugins/security_solution/public/siem_migrations/rules/components/rules_table/translations.ts b/x-pack/plugins/security_solution/public/siem_migrations/rules/components/rules_table/translations.ts index 812f26f628e49..3da9886659916 100644 --- a/x-pack/plugins/security_solution/public/siem_migrations/rules/components/rules_table/translations.ts +++ b/x-pack/plugins/security_solution/public/siem_migrations/rules/components/rules_table/translations.ts @@ -34,3 +34,32 @@ export const GO_BACK_TO_RULES_TABLE_BUTTON = i18n.translate( defaultMessage: 'Go back to SIEM Migrations', } ); + +export const INSTALL_SELECTED_RULES = (numberOfSelectedRules: number) => { + return i18n.translate('xpack.securitySolution.siemMigrations.rules.table.installSelectedRules', { + defaultMessage: 'Install selected ({numberOfSelectedRules})', + values: { numberOfSelectedRules }, + }); +}; + +export const INSTALL_ALL_RULES = (numberOfAllRules: number) => { + return i18n.translate('xpack.securitySolution.siemMigrations.rules.table.installAllRules', { + defaultMessage: + 'Install translated {numberOfAllRules, plural, one {rule} other {rules}} ({numberOfAllRules})', + values: { numberOfAllRules }, + }); +}; + +export const INSTALL_SELECTED_ARIA_LABEL = i18n.translate( + 'xpack.securitySolution.siemMigrations.rules.table.installSelectedButtonAriaLabel', + { + defaultMessage: 'Install selected translated rules', + } +); + +export const INSTALL_ALL_ARIA_LABEL = i18n.translate( + 'xpack.securitySolution.siemMigrations.rules.table.installAllButtonAriaLabel', + { + defaultMessage: 'Install all translated rules', + } +); diff --git a/x-pack/plugins/security_solution/public/siem_migrations/rules/components/rules_table_columns/actions.tsx b/x-pack/plugins/security_solution/public/siem_migrations/rules/components/rules_table_columns/actions.tsx new file mode 100644 index 0000000000000..7122949dee907 --- /dev/null +++ b/x-pack/plugins/security_solution/public/siem_migrations/rules/components/rules_table_columns/actions.tsx @@ -0,0 +1,111 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor 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 { EuiLink } from '@elastic/eui'; +import { getRuleDetailsUrl } from '../../../../common/components/link_to'; +import { useKibana } from '../../../../common/lib/kibana'; +import { APP_UI_ID, SecurityPageName } from '../../../../../common'; +import type { RuleMigration } from '../../../../../common/siem_migrations/model/rule_migration.gen'; +import * as i18n from './translations'; +import type { TableColumn } from './constants'; + +interface ActionNameProps { + disableActions?: boolean; + migrationRule: RuleMigration; + openMigrationRulePreview: (migrationRule: RuleMigration) => void; + installMigrationRule: (migrationRule: RuleMigration, enable?: boolean) => void; +} + +const ActionName = ({ + disableActions, + migrationRule, + openMigrationRulePreview, + installMigrationRule, +}: ActionNameProps) => { + const { navigateToApp } = useKibana().services.application; + if (migrationRule.elastic_rule?.id) { + const ruleId = migrationRule.elastic_rule.id; + return ( + { + navigateToApp(APP_UI_ID, { + deepLinkId: SecurityPageName.rules, + path: getRuleDetailsUrl(ruleId), + }); + }} + data-test-subj="viewRule" + > + {i18n.ACTIONS_VIEW_LABEL} + + ); + } + + if (migrationRule.status === 'failed') { + return ( + {}} data-test-subj="restartRule"> + {i18n.ACTIONS_RESTART_LABEL} + + ); + } + + if (migrationRule.translation_result === 'full') { + return ( + { + installMigrationRule(migrationRule); + }} + data-test-subj="installRule" + > + {i18n.ACTIONS_INSTALL_LABEL} + + ); + } + + return ( + { + openMigrationRulePreview(migrationRule); + }} + data-test-subj="editRule" + > + {i18n.ACTIONS_EDIT_LABEL} + + ); +}; + +interface CreateActionsColumnProps { + disableActions?: boolean; + openMigrationRulePreview: (migrationRule: RuleMigration) => void; + installMigrationRule: (migrationRule: RuleMigration, enable?: boolean) => void; +} + +export const createActionsColumn = ({ + disableActions, + openMigrationRulePreview, + installMigrationRule, +}: CreateActionsColumnProps): TableColumn => { + return { + field: 'elastic_rule', + name: i18n.COLUMN_ACTIONS, + render: (value: RuleMigration['elastic_rule'], migrationRule: RuleMigration) => { + return ( + + ); + }, + width: '10%', + align: 'center', + }; +}; diff --git a/x-pack/plugins/security_solution/public/siem_migrations/rules/utils/constants.ts b/x-pack/plugins/security_solution/public/siem_migrations/rules/components/rules_table_columns/constants.tsx similarity index 53% rename from x-pack/plugins/security_solution/public/siem_migrations/rules/utils/constants.ts rename to x-pack/plugins/security_solution/public/siem_migrations/rules/components/rules_table_columns/constants.tsx index 7400d4b0bcb63..724e4dcb101a1 100644 --- a/x-pack/plugins/security_solution/public/siem_migrations/rules/utils/constants.ts +++ b/x-pack/plugins/security_solution/public/siem_migrations/rules/components/rules_table_columns/constants.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import type { Severity } from '@kbn/securitysolution-io-ts-alerting-types'; +import type { EuiBasicTableColumn } from '@elastic/eui'; +import type { RuleMigration } from '../../../../../common/siem_migrations/model/rule_migration.gen'; -export const DEFAULT_TRANSLATION_RISK_SCORE = 21; -export const DEFAULT_TRANSLATION_SEVERITY: Severity = 'low'; +export type TableColumn = EuiBasicTableColumn; diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/version_mismatch/index.ts b/x-pack/plugins/security_solution/public/siem_migrations/rules/components/rules_table_columns/index.tsx similarity index 60% rename from x-pack/plugins/enterprise_search/public/applications/shared/version_mismatch/index.ts rename to x-pack/plugins/security_solution/public/siem_migrations/rules/components/rules_table_columns/index.tsx index 90d007d1d9411..a402e61a444af 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/version_mismatch/index.ts +++ b/x-pack/plugins/security_solution/public/siem_migrations/rules/components/rules_table_columns/index.tsx @@ -5,5 +5,10 @@ * 2.0. */ -export { VersionMismatchPage } from './version_mismatch_page'; -export { VersionMismatchError } from './version_mismatch_error'; +export * from './constants'; + +export * from './actions'; +export * from './name'; +export * from './risk_score'; +export * from './severity'; +export * from './status'; diff --git a/x-pack/plugins/security_solution/public/siem_migrations/rules/components/rules_table_columns/name.tsx b/x-pack/plugins/security_solution/public/siem_migrations/rules/components/rules_table_columns/name.tsx new file mode 100644 index 0000000000000..7b7cf228895fc --- /dev/null +++ b/x-pack/plugins/security_solution/public/siem_migrations/rules/components/rules_table_columns/name.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 { EuiLink } from '@elastic/eui'; +import type { RuleMigration } from '../../../../../common/siem_migrations/model/rule_migration.gen'; +import * as i18n from './translations'; +import type { TableColumn } from './constants'; + +interface NameProps { + name: string; + rule: RuleMigration; + openMigrationRulePreview: (rule: RuleMigration) => void; +} + +const Name = ({ name, rule, openMigrationRulePreview }: NameProps) => { + return ( + { + openMigrationRulePreview(rule); + }} + data-test-subj="ruleName" + > + {name} + + ); +}; + +export const createNameColumn = ({ + openMigrationRulePreview, +}: { + openMigrationRulePreview: (rule: RuleMigration) => void; +}): TableColumn => { + return { + field: 'original_rule.title', + name: i18n.COLUMN_NAME, + render: (value: RuleMigration['original_rule']['title'], rule: RuleMigration) => ( + + ), + sortable: true, + truncateText: true, + width: '40%', + align: 'left', + }; +}; diff --git a/x-pack/plugins/security_solution/public/siem_migrations/rules/components/rules_table_columns/risk_score.tsx b/x-pack/plugins/security_solution/public/siem_migrations/rules/components/rules_table_columns/risk_score.tsx new file mode 100644 index 0000000000000..e9eca65736a51 --- /dev/null +++ b/x-pack/plugins/security_solution/public/siem_migrations/rules/components/rules_table_columns/risk_score.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 React from 'react'; +import { EuiText } from '@elastic/eui'; +import { DEFAULT_TRANSLATION_RISK_SCORE } from '../../../../../common/siem_migrations/constants'; +import * as i18n from './translations'; +import type { TableColumn } from './constants'; + +export const createRiskScoreColumn = (): TableColumn => { + return { + field: 'risk_score', + name: i18n.COLUMN_RISK_SCORE, + render: () => ( + + {DEFAULT_TRANSLATION_RISK_SCORE} + + ), + sortable: true, + truncateText: true, + width: '75px', + }; +}; diff --git a/x-pack/plugins/security_solution/public/siem_migrations/rules/components/rules_table_columns/severity.tsx b/x-pack/plugins/security_solution/public/siem_migrations/rules/components/rules_table_columns/severity.tsx new file mode 100644 index 0000000000000..4ea737844ad53 --- /dev/null +++ b/x-pack/plugins/security_solution/public/siem_migrations/rules/components/rules_table_columns/severity.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 React from 'react'; +import type { Severity } from '@kbn/securitysolution-io-ts-alerting-types'; +import { DEFAULT_TRANSLATION_SEVERITY } from '../../../../../common/siem_migrations/constants'; +import { getNormalizedSeverity } from '../../../../detection_engine/rule_management_ui/components/rules_table/helpers'; +import { SeverityBadge } from '../../../../common/components/severity_badge'; +import type { RuleMigration } from '../../../../../common/siem_migrations/model/rule_migration.gen'; +import type { TableColumn } from './constants'; +import * as i18n from './translations'; + +export const createSeverityColumn = (): TableColumn => { + return { + field: 'elastic_rule.severity', + name: i18n.COLUMN_SEVERITY, + render: (value?: Severity) => , + sortable: ({ elastic_rule: elasticRule }: RuleMigration) => + getNormalizedSeverity((elasticRule?.severity as Severity) ?? DEFAULT_TRANSLATION_SEVERITY), + truncateText: true, + width: '12%', + }; +}; diff --git a/x-pack/plugins/security_solution/public/siem_migrations/rules/components/rules_table_columns/status.tsx b/x-pack/plugins/security_solution/public/siem_migrations/rules/components/rules_table_columns/status.tsx new file mode 100644 index 0000000000000..982f6ba7580b2 --- /dev/null +++ b/x-pack/plugins/security_solution/public/siem_migrations/rules/components/rules_table_columns/status.tsx @@ -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 React from 'react'; +import type { RuleMigration } from '../../../../../common/siem_migrations/model/rule_migration.gen'; +import * as i18n from './translations'; +import type { TableColumn } from './constants'; +import { StatusBadge } from '../status_badge'; + +export const createStatusColumn = (): TableColumn => { + return { + field: 'translation_result', + name: i18n.COLUMN_STATUS, + render: (value: RuleMigration['translation_result'], rule: RuleMigration) => ( + + ), + sortable: false, + truncateText: true, + width: '12%', + }; +}; diff --git a/x-pack/plugins/security_solution/public/siem_migrations/rules/components/rules_table_columns/translations.ts b/x-pack/plugins/security_solution/public/siem_migrations/rules/components/rules_table_columns/translations.ts new file mode 100644 index 0000000000000..906e752d79aa0 --- /dev/null +++ b/x-pack/plugins/security_solution/public/siem_migrations/rules/components/rules_table_columns/translations.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 { i18n } from '@kbn/i18n'; + +export const COLUMN_ACTIONS = i18n.translate( + 'xpack.securitySolution.siemMigrations.rules.tableColumn.actionsLabel', + { + defaultMessage: 'Actions', + } +); + +export const ACTIONS_VIEW_LABEL = i18n.translate( + 'xpack.securitySolution.siemMigrations.rules.tableColumn.actionsViewLabel', + { + defaultMessage: 'View', + } +); + +export const ACTIONS_EDIT_LABEL = i18n.translate( + 'xpack.securitySolution.siemMigrations.rules.tableColumn.actionsEditLabel', + { + defaultMessage: 'Edit', + } +); + +export const ACTIONS_INSTALL_LABEL = i18n.translate( + 'xpack.securitySolution.siemMigrations.rules.tableColumn.actionsInstallLabel', + { + defaultMessage: 'Install', + } +); + +export const ACTIONS_RESTART_LABEL = i18n.translate( + 'xpack.securitySolution.siemMigrations.rules.tableColumn.actionsRestartLabel', + { + defaultMessage: 'Restart', + } +); + +export const COLUMN_NAME = i18n.translate( + 'xpack.securitySolution.siemMigrations.rules.tableColumn.nameLabel', + { + defaultMessage: 'Name', + } +); + +export const COLUMN_STATUS = i18n.translate( + 'xpack.securitySolution.siemMigrations.rules.tableColumn.statusLabel', + { + defaultMessage: 'Status', + } +); + +export const COLUMN_RISK_SCORE = i18n.translate( + 'xpack.securitySolution.siemMigrations.rules.tableColumn.riskScoreLabel', + { + defaultMessage: 'Risk score', + } +); + +export const COLUMN_SEVERITY = i18n.translate( + 'xpack.securitySolution.siemMigrations.rules.tableColumn.severityLabel', + { + defaultMessage: 'Severity', + } +); diff --git a/x-pack/plugins/security_solution/public/siem_migrations/rules/components/translation_details_flyout/index.tsx b/x-pack/plugins/security_solution/public/siem_migrations/rules/components/translation_details_flyout/index.tsx index 4aaff21281d64..b6dce09c311e1 100644 --- a/x-pack/plugins/security_solution/public/siem_migrations/rules/components/translation_details_flyout/index.tsx +++ b/x-pack/plugins/security_solution/public/siem_migrations/rules/components/translation_details_flyout/index.tsx @@ -25,6 +25,10 @@ import { } from '@elastic/eui'; import type { EuiTabbedContentTab, EuiTabbedContentProps, EuiFlyoutProps } from '@elastic/eui'; +import { + DEFAULT_TRANSLATION_RISK_SCORE, + DEFAULT_TRANSLATION_SEVERITY, +} from '../../../../../common/siem_migrations/constants'; import type { RuleMigration } from '../../../../../common/siem_migrations/model/rule_migration.gen'; import { RuleOverviewTab, @@ -41,10 +45,6 @@ import { LARGE_DESCRIPTION_LIST_COLUMN_WIDTHS, } from './constants'; import { TranslationTab } from './translation_tab'; -import { - DEFAULT_TRANSLATION_RISK_SCORE, - DEFAULT_TRANSLATION_SEVERITY, -} from '../../utils/constants'; const StyledEuiFlyoutBody = styled(EuiFlyoutBody)` .euiFlyoutBody__overflow { diff --git a/x-pack/plugins/security_solution/public/siem_migrations/rules/hooks/use_rules_table_columns.tsx b/x-pack/plugins/security_solution/public/siem_migrations/rules/hooks/use_rules_table_columns.tsx index 3b13b9e631ccb..b7e06b4ea938a 100644 --- a/x-pack/plugins/security_solution/public/siem_migrations/rules/hooks/use_rules_table_columns.tsx +++ b/x-pack/plugins/security_solution/public/siem_migrations/rules/hooks/use_rules_table_columns.tsx @@ -5,103 +5,38 @@ * 2.0. */ -import type { EuiBasicTableColumn } from '@elastic/eui'; -import { EuiText, EuiLink } from '@elastic/eui'; -import React, { useMemo } from 'react'; -import type { Severity } from '@kbn/securitysolution-io-ts-alerting-types'; +import { useMemo } from 'react'; import type { RuleMigration } from '../../../../common/siem_migrations/model/rule_migration.gen'; -import { SeverityBadge } from '../../../common/components/severity_badge'; -import * as rulesI18n from '../../../detections/pages/detection_engine/rules/translations'; -import * as i18n from './translations'; -import { getNormalizedSeverity } from '../../../detection_engine/rule_management_ui/components/rules_table/helpers'; -import { StatusBadge } from '../components/status_badge'; -import { DEFAULT_TRANSLATION_RISK_SCORE, DEFAULT_TRANSLATION_SEVERITY } from '../utils/constants'; - -export type TableColumn = EuiBasicTableColumn; - -interface RuleNameProps { - name: string; - rule: RuleMigration; - openRulePreview: (rule: RuleMigration) => void; -} - -const RuleName = ({ name, rule, openRulePreview }: RuleNameProps) => { - return ( - { - openRulePreview(rule); - }} - data-test-subj="ruleName" - > - {name} - - ); -}; - -const createRuleNameColumn = ({ - openRulePreview, -}: { - openRulePreview: (rule: RuleMigration) => void; -}): TableColumn => { - return { - field: 'original_rule.title', - name: rulesI18n.COLUMN_RULE, - render: (value: RuleMigration['original_rule']['title'], rule: RuleMigration) => ( - - ), - sortable: true, - truncateText: true, - width: '40%', - align: 'left', - }; -}; - -const STATUS_COLUMN: TableColumn = { - field: 'translation_result', - name: i18n.COLUMN_STATUS, - render: (value: RuleMigration['translation_result'], rule: RuleMigration) => ( - - ), - sortable: false, - truncateText: true, - width: '12%', -}; +import type { TableColumn } from '../components/rules_table_columns'; +import { + createActionsColumn, + createNameColumn, + createRiskScoreColumn, + createSeverityColumn, + createStatusColumn, +} from '../components/rules_table_columns'; export const useRulesTableColumns = ({ - openRulePreview, + disableActions, + openMigrationRulePreview, + installMigrationRule, }: { - openRulePreview: (rule: RuleMigration) => void; + disableActions?: boolean; + openMigrationRulePreview: (rule: RuleMigration) => void; + installMigrationRule: (migrationRule: RuleMigration, enable?: boolean) => void; }): TableColumn[] => { return useMemo( () => [ - createRuleNameColumn({ openRulePreview }), - STATUS_COLUMN, - { - field: 'risk_score', - name: rulesI18n.COLUMN_RISK_SCORE, - render: () => ( - - {DEFAULT_TRANSLATION_RISK_SCORE} - - ), - sortable: true, - truncateText: true, - width: '75px', - }, - { - field: 'elastic_rule.severity', - name: rulesI18n.COLUMN_SEVERITY, - render: (value?: Severity) => ( - - ), - sortable: ({ elastic_rule: elasticRule }: RuleMigration) => - getNormalizedSeverity( - (elasticRule?.severity as Severity) ?? DEFAULT_TRANSLATION_SEVERITY - ), - truncateText: true, - width: '12%', - }, + createNameColumn({ openMigrationRulePreview }), + createStatusColumn(), + createRiskScoreColumn(), + createSeverityColumn(), + createActionsColumn({ + disableActions, + openMigrationRulePreview, + installMigrationRule, + }), ], - [openRulePreview] + [disableActions, installMigrationRule, openMigrationRulePreview] ); }; diff --git a/x-pack/plugins/security_solution/public/siem_migrations/rules/logic/translations.ts b/x-pack/plugins/security_solution/public/siem_migrations/rules/logic/translations.ts new file mode 100644 index 0000000000000..23f5a6e3849a0 --- /dev/null +++ b/x-pack/plugins/security_solution/public/siem_migrations/rules/logic/translations.ts @@ -0,0 +1,22 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; + +export const GET_MIGRATION_RULES_FAILURE = i18n.translate( + 'xpack.securitySolution.siemMigrations.rules.getMigrationRulesFailDescription', + { + defaultMessage: 'Failed to fetch migration rules', + } +); + +export const INSTALL_MIGRATION_RULES_FAILURE = i18n.translate( + 'xpack.securitySolution.siemMigrations.rules.installMigrationRulesFailDescription', + { + defaultMessage: 'Failed to install migration rules', + } +); diff --git a/x-pack/plugins/security_solution/public/siem_migrations/rules/logic/use_get_migration_rules.ts b/x-pack/plugins/security_solution/public/siem_migrations/rules/logic/use_get_migration_rules.ts new file mode 100644 index 0000000000000..27637daf142ff --- /dev/null +++ b/x-pack/plugins/security_solution/public/siem_migrations/rules/logic/use_get_migration_rules.ts @@ -0,0 +1,20 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { useAppToasts } from '../../../common/hooks/use_app_toasts'; +import { useGetMigrationRulesQuery } from '../api/hooks/use_get_migration_rules_query'; +import * as i18n from './translations'; + +export const useGetMigrationRules = (migrationId: string) => { + const { addError } = useAppToasts(); + + return useGetMigrationRulesQuery(migrationId, { + onError: (error) => { + addError(error, { title: i18n.GET_MIGRATION_RULES_FAILURE }); + }, + }); +}; diff --git a/x-pack/plugins/security_solution/public/siem_migrations/rules/logic/use_install_all_migration_rules.ts b/x-pack/plugins/security_solution/public/siem_migrations/rules/logic/use_install_all_migration_rules.ts new file mode 100644 index 0000000000000..105ea651d0a8c --- /dev/null +++ b/x-pack/plugins/security_solution/public/siem_migrations/rules/logic/use_install_all_migration_rules.ts @@ -0,0 +1,20 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { useAppToasts } from '../../../common/hooks/use_app_toasts'; +import { useInstallAllMigrationRulesMutation } from '../api/hooks/use_install_all_migration_rules_mutation'; +import * as i18n from './translations'; + +export const useInstallAllMigrationRules = (migrationId: string) => { + const { addError } = useAppToasts(); + + return useInstallAllMigrationRulesMutation(migrationId, { + onError: (error) => { + addError(error, { title: i18n.INSTALL_MIGRATION_RULES_FAILURE }); + }, + }); +}; diff --git a/x-pack/plugins/security_solution/public/siem_migrations/rules/logic/use_install_migration_rules.ts b/x-pack/plugins/security_solution/public/siem_migrations/rules/logic/use_install_migration_rules.ts new file mode 100644 index 0000000000000..dcc19f290f87f --- /dev/null +++ b/x-pack/plugins/security_solution/public/siem_migrations/rules/logic/use_install_migration_rules.ts @@ -0,0 +1,20 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { useAppToasts } from '../../../common/hooks/use_app_toasts'; +import { useInstallMigrationRulesMutation } from '../api/hooks/use_install_migration_rules_mutation'; +import * as i18n from './translations'; + +export const useInstallMigrationRules = (migrationId: string) => { + const { addError } = useAppToasts(); + + return useInstallMigrationRulesMutation(migrationId, { + onError: (error) => { + addError(error, { title: i18n.INSTALL_MIGRATION_RULES_FAILURE }); + }, + }); +}; diff --git a/x-pack/plugins/security_solution/public/siem_migrations/rules/pages/index.tsx b/x-pack/plugins/security_solution/public/siem_migrations/rules/pages/index.tsx index 26199616b3777..dabdb83cccbab 100644 --- a/x-pack/plugins/security_solution/public/siem_migrations/rules/pages/index.tsx +++ b/x-pack/plugins/security_solution/public/siem_migrations/rules/pages/index.tsx @@ -5,12 +5,11 @@ * 2.0. */ -import React, { useCallback, useEffect, useMemo } from 'react'; +import React, { useEffect, useMemo } from 'react'; import { EuiSkeletonLoading, EuiSkeletonText, EuiSkeletonTitle } from '@elastic/eui'; import type { RouteComponentProps } from 'react-router-dom'; import { useNavigation } from '../../../common/lib/kibana'; -import type { RuleMigration } from '../../../../common/siem_migrations/model/rule_migration.gen'; import { HeaderPage } from '../../../common/components/header_page'; import { SecuritySolutionPageWrapper } from '../../../common/components/page_wrapper'; import { SecurityPageName } from '../../../app/types'; @@ -20,7 +19,6 @@ import { RulesTable } from '../components/rules_table'; import { NeedAdminForUpdateRulesCallOut } from '../../../detections/components/callouts/need_admin_for_update_callout'; import { MissingPrivilegesCallOut } from '../../../detections/components/callouts/missing_privileges_callout'; import { HeaderButtons } from '../components/header_buttons'; -import { useRulePreviewFlyout } from '../hooks/use_rule_preview_flyout'; import { UnknownMigration } from '../components/unknown_migration'; import { useLatestStats } from '../hooks/use_latest_stats'; @@ -66,24 +64,12 @@ export const RulesPage: React.FC = React.memo( navigateTo({ deepLinkId: SecurityPageName.siemMigrationsRules, path: selectedId }); }; - const ruleActionsFactory = useCallback( - (ruleMigration: RuleMigration, closeRulePreview: () => void) => { - // TODO: Add flyout action buttons - return null; - }, - [] - ); - - const { rulePreviewFlyout, openRulePreview } = useRulePreviewFlyout({ - ruleActionsFactory, - }); - const content = useMemo(() => { if (!migrationId || !migrationsIds.includes(migrationId)) { return ; } - return ; - }, [migrationId, migrationsIds, openRulePreview]); + return ; + }, [migrationId, migrationsIds]); return ( <> @@ -108,7 +94,6 @@ export const RulesPage: React.FC = React.memo( } loadedContent={content} /> - {rulePreviewFlyout} ); diff --git a/x-pack/plugins/security_solution/public/siem_migrations/rules/service/rule_migrations_service.ts b/x-pack/plugins/security_solution/public/siem_migrations/rules/service/rule_migrations_service.ts index ba6543f5171d3..a872d79a46027 100644 --- a/x-pack/plugins/security_solution/public/siem_migrations/rules/service/rule_migrations_service.ts +++ b/x-pack/plugins/security_solution/public/siem_migrations/rules/service/rule_migrations_service.ts @@ -8,28 +8,35 @@ import { BehaviorSubject, type Observable } from 'rxjs'; import type { CoreStart } from '@kbn/core/public'; import { i18n } from '@kbn/i18n'; +import { SiemMigrationTaskStatus } from '../../../../common/siem_migrations/constants'; +import type { StartPluginsDependencies } from '../../../types'; import { ExperimentalFeaturesService } from '../../../common/experimental_features_service'; import { licenseService } from '../../../common/hooks/use_license'; -import { getRuleMigrationsStatsAll } from '../api/api'; -import type { RuleMigrationStats } from '../types'; +import { getRuleMigrationsStatsAll, startRuleMigration } from '../api/api'; +import type { RuleMigrationTask } from '../types'; import { getSuccessToast } from './success_notification'; - -const POLLING_ERROR_TITLE = i18n.translate( - 'xpack.securitySolution.siemMigrations.rulesService.polling.errorTitle', - { defaultMessage: 'Error fetching rule migrations' } -); +import { RuleMigrationsStorage } from './storage'; export class SiemRulesMigrationsService { private readonly pollingInterval = 5000; - private readonly latestStats$: BehaviorSubject; + private readonly latestStats$: BehaviorSubject; + private readonly signal = new AbortController().signal; private isPolling = false; + public connectorIdStorage = new RuleMigrationsStorage('connectorId'); + + constructor( + private readonly core: CoreStart, + private readonly plugins: StartPluginsDependencies + ) { + this.latestStats$ = new BehaviorSubject([]); - constructor(private readonly core: CoreStart) { - this.latestStats$ = new BehaviorSubject([]); - this.startPolling(); + this.plugins.spaces.getActiveSpace().then((space) => { + this.connectorIdStorage.setSpaceId(space.id); + this.startPolling(); + }); } - public getLatestStats$(): Observable { + public getLatestStats$(): Observable { return this.latestStats$.asObservable(); } @@ -45,7 +52,12 @@ export class SiemRulesMigrationsService { this.isPolling = true; this.startStatsPolling() .catch((e) => { - this.core.notifications.toasts.addError(e, { title: POLLING_ERROR_TITLE }); + this.core.notifications.toasts.addError(e, { + title: i18n.translate( + 'xpack.securitySolution.siemMigrations.rulesService.polling.errorTitle', + { defaultMessage: 'Error fetching rule migrations' } + ), + }); }) .finally(() => { this.isPolling = false; @@ -55,33 +67,46 @@ export class SiemRulesMigrationsService { private async startStatsPolling(): Promise { let pendingMigrationIds: string[] = []; do { - const results = await this.fetchRuleMigrationsStats(); + const results = await this.fetchRuleMigrationTasksStats(); this.latestStats$.next(results); if (pendingMigrationIds.length > 0) { // send notifications for finished migrations pendingMigrationIds.forEach((pendingMigrationId) => { const migration = results.find((item) => item.id === pendingMigrationId); - if (migration && migration.status === 'finished') { + if (migration?.status === SiemMigrationTaskStatus.FINISHED) { this.core.notifications.toasts.addSuccess(getSuccessToast(migration, this.core)); } }); } - // reassign pending migrations - pendingMigrationIds = results.reduce((acc, item) => { - if (item.status === 'running') { - acc.push(item.id); + // reprocess pending migrations + pendingMigrationIds = []; + for (const result of results) { + if (result.status === SiemMigrationTaskStatus.RUNNING) { + pendingMigrationIds.push(result.id); } - return acc; - }, []); + + if (result.status === SiemMigrationTaskStatus.STOPPED) { + const connectorId = this.connectorIdStorage.get(); + if (connectorId) { + // automatically resume stopped migrations when connector is available + await startRuleMigration({ + migrationId: result.id, + body: { connector_id: connectorId }, + signal: this.signal, + }); + pendingMigrationIds.push(result.id); + } + } + } await new Promise((resolve) => setTimeout(resolve, this.pollingInterval)); } while (pendingMigrationIds.length > 0); } - private async fetchRuleMigrationsStats(): Promise { - const stats = await getRuleMigrationsStatsAll({ signal: new AbortController().signal }); + private async fetchRuleMigrationTasksStats(): Promise { + const stats = await getRuleMigrationsStatsAll({ signal: this.signal }); return stats.map((stat, index) => ({ ...stat, number: index + 1 })); // the array order (by creation) is guaranteed by the API } } diff --git a/x-pack/plugins/security_solution/public/siem_migrations/rules/service/storage.ts b/x-pack/plugins/security_solution/public/siem_migrations/rules/service/storage.ts new file mode 100644 index 0000000000000..bbf53ec3a5404 --- /dev/null +++ b/x-pack/plugins/security_solution/public/siem_migrations/rules/service/storage.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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { Storage } from '@kbn/kibana-utils-plugin/public'; + +export class RuleMigrationsStorage { + private readonly storage = new Storage(localStorage); + public key: string; + + constructor(private readonly objectName: string, spaceId?: string) { + this.key = this.getStorageKey(spaceId); + } + + private getStorageKey(spaceId: string = 'default') { + return `siem_migrations.rules.${this.objectName}.${spaceId}`; + } + + public setSpaceId(spaceId: string) { + this.key = this.getStorageKey(spaceId); + } + + public get = () => this.storage.get(this.key); + public set = (value: string) => this.storage.set(this.key, value); + public remove = () => this.storage.remove(this.key); +} diff --git a/x-pack/plugins/security_solution/public/siem_migrations/rules/service/success_notification.tsx b/x-pack/plugins/security_solution/public/siem_migrations/rules/service/success_notification.tsx index f87755943f830..830e3c5f4a531 100644 --- a/x-pack/plugins/security_solution/public/siem_migrations/rules/service/success_notification.tsx +++ b/x-pack/plugins/security_solution/public/siem_migrations/rules/service/success_notification.tsx @@ -17,9 +17,9 @@ import type { ToastInput } from '@kbn/core-notifications-browser'; import { toMountPoint } from '@kbn/react-kibana-mount'; import { FormattedMessage } from '@kbn/i18n-react'; import { EuiButton, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; -import type { RuleMigrationStats } from '../types'; +import type { RuleMigrationTask } from '../types'; -export const getSuccessToast = (migration: RuleMigrationStats, core: CoreStart): ToastInput => ({ +export const getSuccessToast = (migration: RuleMigrationTask, core: CoreStart): ToastInput => ({ color: 'success', iconType: 'check', toastLifeTimeMs: 1000 * 60 * 30, // 30 minutes @@ -34,7 +34,7 @@ export const getSuccessToast = (migration: RuleMigrationStats, core: CoreStart): ), }); -const SuccessToastContent: React.FC<{ migration: RuleMigrationStats }> = ({ migration }) => { +const SuccessToastContent: React.FC<{ migration: RuleMigrationTask }> = ({ migration }) => { const navigation = { deepLinkId: SecurityPageName.siemMigrationsRules, path: migration.id }; const { navigateTo, getAppUrl } = useNavigation(); diff --git a/x-pack/plugins/security_solution/public/siem_migrations/rules/types.ts b/x-pack/plugins/security_solution/public/siem_migrations/rules/types.ts index db9ca9507702f..b395fa0199de8 100644 --- a/x-pack/plugins/security_solution/public/siem_migrations/rules/types.ts +++ b/x-pack/plugins/security_solution/public/siem_migrations/rules/types.ts @@ -7,7 +7,18 @@ import type { RuleMigrationTaskStats } from '../../../common/siem_migrations/model/rule_migration.gen'; -export interface RuleMigrationStats extends RuleMigrationTaskStats { +export interface RuleMigrationTask extends RuleMigrationTaskStats { /** The sequential number of the migration */ number: number; } + +export interface InstallRulesProps { + migrationId: string; + ids: string[]; + signal?: AbortSignal; +} + +export interface InstallTranslatedRulesProps { + migrationId: string; + signal?: AbortSignal; +} diff --git a/x-pack/plugins/security_solution/public/siem_migrations/service/index.ts b/x-pack/plugins/security_solution/public/siem_migrations/service/index.ts index 08a50d018976b..dbea3624c7c1d 100644 --- a/x-pack/plugins/security_solution/public/siem_migrations/service/index.ts +++ b/x-pack/plugins/security_solution/public/siem_migrations/service/index.ts @@ -6,13 +6,17 @@ */ import type { CoreStart } from '@kbn/core-lifecycle-browser'; +import type { StartPluginsDependencies } from '../../types'; export type { SiemMigrationsService } from './siem_migrations_service'; -export const createSiemMigrationsService = async (coreStart: CoreStart) => { +export const createSiemMigrationsService = async ( + coreStart: CoreStart, + plugins: StartPluginsDependencies +) => { const { SiemMigrationsService } = await import( /* webpackChunkName: "lazySiemMigrationsService" */ './siem_migrations_service' ); - return new SiemMigrationsService(coreStart); + return new SiemMigrationsService(coreStart, plugins); }; diff --git a/x-pack/plugins/security_solution/public/siem_migrations/service/siem_migrations_service.ts b/x-pack/plugins/security_solution/public/siem_migrations/service/siem_migrations_service.ts index 1775296f6e230..da733bf5926e3 100644 --- a/x-pack/plugins/security_solution/public/siem_migrations/service/siem_migrations_service.ts +++ b/x-pack/plugins/security_solution/public/siem_migrations/service/siem_migrations_service.ts @@ -6,12 +6,13 @@ */ import type { CoreStart } from '@kbn/core/public'; +import type { StartPluginsDependencies } from '../../types'; import { SiemRulesMigrationsService } from '../rules/service/rule_migrations_service'; export class SiemMigrationsService { public rules: SiemRulesMigrationsService; - constructor(coreStart: CoreStart) { - this.rules = new SiemRulesMigrationsService(coreStart); + constructor(coreStart: CoreStart, plugins: StartPluginsDependencies) { + this.rules = new SiemRulesMigrationsService(coreStart, plugins); } } diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/host_name.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/host_name.test.tsx index 52344857a07c1..a7769069ff197 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/host_name.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/host_name.test.tsx @@ -12,30 +12,14 @@ import { HostName } from './host_name'; import { TestProviders } from '../../../../../common/mock'; import { TimelineId, TimelineTabs } from '../../../../../../common/types/timeline'; import { StatefulEventContext } from '../../../../../common/components/events_viewer/stateful_event_context'; -import { createTelemetryServiceMock } from '../../../../../common/lib/telemetry/telemetry_service.mock'; import { TableId } from '@kbn/securitysolution-data-table'; import { createExpandableFlyoutApiMock } from '../../../../../common/mock/expandable_flyout'; import { useExpandableFlyoutApi } from '@kbn/expandable-flyout'; -const mockedTelemetry = createTelemetryServiceMock(); const mockOpenRightPanel = jest.fn(); jest.mock('@kbn/expandable-flyout'); -jest.mock('../../../../../common/lib/kibana/kibana_react', () => { - return { - useKibana: () => ({ - services: { - application: { - getUrlForApp: jest.fn(), - navigateToApp: jest.fn(), - }, - telemetry: mockedTelemetry, - }, - }), - }; -}); - jest.mock('../../../../../common/components/draggables', () => ({ DefaultDraggable: () =>
        , })); diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/host_name.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/host_name.tsx index 845b826e5866e..41d403b3f2c5b 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/host_name.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/host_name.tsx @@ -15,6 +15,7 @@ import { HostDetailsLink } from '../../../../../common/components/links'; import { DefaultDraggable } from '../../../../../common/components/draggables'; import { getEmptyTagValue } from '../../../../../common/components/empty_value'; import { TruncatableText } from '../../../../../common/components/truncatable_text'; +import { useIsInSecurityApp } from '../../../../../common/hooks/is_in_security_app'; interface Props { contextId: string; @@ -45,6 +46,8 @@ const HostNameComponent: React.FC = ({ }) => { const { openRightPanel } = useExpandableFlyoutApi(); + const isInSecurityApp = useIsInSecurityApp(); + const eventContext = useContext(StatefulEventContext); const hostName = `${value}`; const isInTimelineContext = @@ -58,6 +61,10 @@ const HostNameComponent: React.FC = ({ onClick(); } + /* + * if and only if renderer is running inside security solution app + * we check for event and timeline context + * */ if (!eventContext || !isInTimelineContext) { return; } @@ -85,13 +92,21 @@ const HostNameComponent: React.FC = ({ Component={Component} hostName={hostName} isButton={isButton} - onClick={isInTimelineContext ? openHostDetailsSidePanel : undefined} + onClick={isInTimelineContext || !isInSecurityApp ? openHostDetailsSidePanel : undefined} title={title} > {hostName} ), - [Component, hostName, isButton, isInTimelineContext, openHostDetailsSidePanel, title] + [ + Component, + hostName, + isButton, + isInTimelineContext, + openHostDetailsSidePanel, + title, + isInSecurityApp, + ] ); return isString(value) && hostName.length > 0 ? ( diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/user_name.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/user_name.test.tsx index 6c3dffc58ce25..bdb53f5850ec3 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/user_name.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/user_name.test.tsx @@ -12,30 +12,14 @@ import { TestProviders } from '../../../../../common/mock'; import { TimelineId, TimelineTabs } from '../../../../../../common/types/timeline'; import { UserName } from './user_name'; import { StatefulEventContext } from '../../../../../common/components/events_viewer/stateful_event_context'; -import { createTelemetryServiceMock } from '../../../../../common/lib/telemetry/telemetry_service.mock'; import { TableId } from '@kbn/securitysolution-data-table'; import { useExpandableFlyoutApi } from '@kbn/expandable-flyout'; import { createExpandableFlyoutApiMock } from '../../../../../common/mock/expandable_flyout'; -const mockedTelemetry = createTelemetryServiceMock(); const mockOpenRightPanel = jest.fn(); jest.mock('@kbn/expandable-flyout'); -jest.mock('../../../../../common/lib/kibana/kibana_react', () => { - return { - useKibana: () => ({ - services: { - application: { - getUrlForApp: jest.fn(), - navigateToApp: jest.fn(), - }, - telemetry: mockedTelemetry, - }, - }), - }; -}); - jest.mock('../../../../../common/components/draggables', () => ({ DefaultDraggable: () =>
        , })); diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/user_name.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/user_name.tsx index 1f070d52a8de9..31a8424e5ea0c 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/user_name.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/user_name.tsx @@ -15,6 +15,7 @@ import { DefaultDraggable } from '../../../../../common/components/draggables'; import { getEmptyTagValue } from '../../../../../common/components/empty_value'; import { UserDetailsLink } from '../../../../../common/components/links'; import { TruncatableText } from '../../../../../common/components/truncatable_text'; +import { useIsInSecurityApp } from '../../../../../common/hooks/is_in_security_app'; interface Props { contextId: string; @@ -48,6 +49,8 @@ const UserNameComponent: React.FC = ({ const isInTimelineContext = userName && eventContext?.timelineID; const { openRightPanel } = useExpandableFlyoutApi(); + const isInSecurityApp = useIsInSecurityApp(); + const openUserDetailsSidePanel = useCallback( (e: React.SyntheticEvent) => { e.preventDefault(); @@ -83,13 +86,21 @@ const UserNameComponent: React.FC = ({ Component={Component} userName={userName} isButton={isButton} - onClick={isInTimelineContext ? openUserDetailsSidePanel : undefined} + onClick={isInTimelineContext || !isInSecurityApp ? openUserDetailsSidePanel : undefined} title={title} > {userName} ), - [userName, isButton, isInTimelineContext, openUserDetailsSidePanel, Component, title] + [ + userName, + isButton, + isInTimelineContext, + openUserDetailsSidePanel, + Component, + title, + isInSecurityApp, + ] ); return isString(value) && userName.length > 0 ? ( diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/unified_timeline_body.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/unified_timeline_body.test.tsx index 41cdec6d6d4bb..77f26075581e0 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/unified_timeline_body.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/unified_timeline_body.test.tsx @@ -12,7 +12,7 @@ import { UnifiedTimeline } from '../unified_components'; import { defaultUdtHeaders } from './column_headers/default_headers'; import type { UnifiedTimelineBodyProps } from './unified_timeline_body'; import { UnifiedTimelineBody } from './unified_timeline_body'; -import { render, screen } from '@testing-library/react'; +import { render } from '@testing-library/react'; import { defaultHeaders, mockTimelineData, TestProviders } from '../../../../common/mock'; jest.mock('../unified_components', () => { @@ -32,17 +32,14 @@ const defaultProps: UnifiedTimelineBodyProps = { isTextBasedQuery: false, itemsPerPage: 25, itemsPerPageOptions: [10, 25, 50], - onChangePage: jest.fn(), + onFetchMoreRecords: jest.fn(), refetch: jest.fn(), rowRenderers: [], sort: [], timelineId: 'timeline-1', totalCount: 0, updatedAt: 0, - pageInfo: { - activePage: 0, - querySize: 0, - }, + onUpdatePageIndex: jest.fn(), }; const renderTestComponents = (props?: UnifiedTimelineBodyProps) => { @@ -57,39 +54,6 @@ describe('UnifiedTimelineBody', () => { beforeEach(() => { (UnifiedTimeline as unknown as jest.Mock).mockImplementation(MockUnifiedTimelineComponent); }); - it('should pass correct page rows', () => { - const { rerender } = renderTestComponents(); - - expect(screen.getByTestId('unifiedTimelineBody')).toBeVisible(); - expect(MockUnifiedTimelineComponent).toHaveBeenCalledTimes(2); - - expect(MockUnifiedTimelineComponent).toHaveBeenLastCalledWith( - expect.objectContaining({ - events: mockEventsData.flat(), - }), - {} - ); - - const newEventsData = structuredClone([mockEventsData[0]]); - - const newProps = { - ...defaultProps, - pageInfo: { - activePage: 1, - querySize: 0, - }, - events: newEventsData, - }; - - MockUnifiedTimelineComponent.mockClear(); - rerender(); - expect(MockUnifiedTimelineComponent).toHaveBeenLastCalledWith( - expect.objectContaining({ - events: [...mockEventsData, ...newEventsData].flat(), - }), - {} - ); - }); it('should pass default columns when empty column list is supplied', () => { const newProps = { ...defaultProps, columns: [] }; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/unified_timeline_body.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/unified_timeline_body.tsx index 95feab8543617..b705717fc437f 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/unified_timeline_body.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/unified_timeline_body.tsx @@ -6,23 +6,20 @@ */ import type { ComponentProps, ReactElement } from 'react'; -import React, { useEffect, useState, useMemo } from 'react'; +import React, { useMemo } from 'react'; import { RootDragDropProvider } from '@kbn/dom-drag-drop'; import { StyledTableFlexGroup, StyledUnifiedTableFlexItem } from '../unified_components/styles'; import { UnifiedTimeline } from '../unified_components'; import { defaultUdtHeaders } from './column_headers/default_headers'; -import type { PaginationInputPaginated, TimelineItem } from '../../../../../common/search_strategy'; export interface UnifiedTimelineBodyProps extends ComponentProps { header: ReactElement; - pageInfo: Pick; } export const UnifiedTimelineBody = (props: UnifiedTimelineBodyProps) => { const { header, isSortEnabled, - pageInfo, columns, rowRenderers, timelineId, @@ -33,28 +30,14 @@ export const UnifiedTimelineBody = (props: UnifiedTimelineBodyProps) => { refetch, dataLoadingState, totalCount, - onChangePage, + onFetchMoreRecords, activeTab, updatedAt, trailingControlColumns, leadingControlColumns, + onUpdatePageIndex, } = props; - const [pageRows, setPageRows] = useState([]); - - const rows = useMemo(() => pageRows.flat(), [pageRows]); - - useEffect(() => { - setPageRows((currentPageRows) => { - if (pageInfo.activePage !== 0 && currentPageRows[pageInfo.activePage]?.length) { - return currentPageRows; - } - const newPageRows = pageInfo.activePage === 0 ? [] : [...currentPageRows]; - newPageRows[pageInfo.activePage] = events; - return newPageRows; - }); - }, [events, pageInfo.activePage]); - const columnsHeader = useMemo(() => columns ?? defaultUdtHeaders, [columns]); return ( @@ -73,16 +56,17 @@ export const UnifiedTimelineBody = (props: UnifiedTimelineBodyProps) => { itemsPerPage={itemsPerPage} itemsPerPageOptions={itemsPerPageOptions} sort={sort} - events={rows} + events={events} refetch={refetch} dataLoadingState={dataLoadingState} totalCount={totalCount} - onChangePage={onChangePage} + onFetchMoreRecords={onFetchMoreRecords} activeTab={activeTab} updatedAt={updatedAt} isTextBasedQuery={false} trailingControlColumns={trailingControlColumns} leadingControlColumns={leadingControlColumns} + onUpdatePageIndex={onUpdatePageIndex} /> diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/events.ts b/x-pack/plugins/security_solution/public/timelines/components/timeline/events.ts index 14046b853a235..c48e38ba69a21 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/events.ts +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/events.ts @@ -13,7 +13,7 @@ export type { OnColumnsSorted, OnColumnRemoved, OnColumnResized, - OnChangePage, + OnFetchMoreRecords as OnChangePage, OnPinEvent, OnRowSelected, OnSelectAll, diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs/eql/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs/eql/index.test.tsx index 23fb44d04910f..a71f99715131e 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs/eql/index.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs/eql/index.test.tsx @@ -5,18 +5,16 @@ * 2.0. */ -import React from 'react'; +import type { ComponentProps } from 'react'; +import React, { useEffect } from 'react'; import useResizeObserver from 'use-resize-observer/polyfilled'; -import type { Dispatch } from 'redux'; -import { defaultRowRenderers } from '../../body/renderers'; -import { DefaultCellRenderer } from '../../cell_rendering/default_cell_renderer'; -import { defaultHeaders, mockTimelineData } from '../../../../../common/mock'; +import { createMockStore, mockGlobalState, mockTimelineData } from '../../../../../common/mock'; import { TestProviders } from '../../../../../common/mock/test_providers'; import type { Props as EqlTabContentComponentProps } from '.'; -import { EqlTabContentComponent } from '.'; -import { TimelineId, TimelineTabs } from '../../../../../../common/types/timeline'; +import EqlTabContentComponent from '.'; +import { TimelineId } from '../../../../../../common/types/timeline'; import { useTimelineEvents } from '../../../../containers'; import { useTimelineEventsDetails } from '../../../../containers/details'; import { useSourcererDataView } from '../../../../../sourcerer/containers'; @@ -24,7 +22,15 @@ import { mockSourcererScope } from '../../../../../sourcerer/containers/mocks'; import { useIsExperimentalFeatureEnabled } from '../../../../../common/hooks/use_experimental_features'; import type { ExperimentalFeatures } from '../../../../../../common'; import { allowedExperimentalValues } from '../../../../../../common'; -import { render, screen } from '@testing-library/react'; +import { fireEvent, render, screen, waitFor } from '@testing-library/react'; +import * as notesApi from '../../../../../notes/api/api'; +import { timelineActions } from '../../../../store'; +import { DefaultCellRenderer } from '../../cell_rendering/default_cell_renderer'; +import { defaultRowRenderers } from '../../body/renderers'; +import { useDispatch } from 'react-redux'; +import { TimelineTabs } from '@kbn/securitysolution-data-table'; + +const SPECIAL_TEST_TIMEOUT = 30000; jest.mock('../../../../containers', () => ({ useTimelineEvents: jest.fn(), @@ -50,10 +56,43 @@ mockUseResizeObserver.mockImplementation(() => ({})); jest.mock('../../../../../common/lib/kibana'); +let useTimelineEventsMock = jest.fn(); + +const loadPageMock = jest.fn(); + +const mockState = { + ...structuredClone(mockGlobalState), +}; +mockState.timeline.timelineById[TimelineId.test].activeTab = TimelineTabs.eql; + +const TestComponent = (props: Partial>) => { + const testComponentDefaultProps: ComponentProps = { + timelineId: TimelineId.test, + renderCellValue: DefaultCellRenderer, + rowRenderers: defaultRowRenderers, + }; + + const dispatch = useDispatch(); + + useEffect(() => { + // Unified field list can be a culprit for long load times, so we wait for the timeline to be interacted with to load + dispatch(timelineActions.showTimeline({ id: TimelineId.test, show: true })); + + // populating timeline so that it is not blank + dispatch( + timelineActions.updateEqlOptions({ + id: TimelineId.test, + field: 'query', + value: 'any where true', + }) + ); + }, [dispatch]); + + return ; +}; + describe('EQL Tab', () => { - let props = {} as EqlTabContentComponentProps; - const startDate = '2018-03-23T18:49:23.132Z'; - const endDate = '2018-03-24T03:33:52.253Z'; + const props = {} as EqlTabContentComponentProps; beforeAll(() => { // https://github.com/atlassian/react-beautiful-dnd/blob/4721a518356f72f1dac45b5fd4ee9d466aa2996b/docs/guides/setup-problem-detection-and-error-recovery.md#disable-logging @@ -65,7 +104,7 @@ describe('EQL Tab', () => { }); beforeEach(() => { - (useTimelineEvents as jest.Mock).mockReturnValue([ + useTimelineEventsMock = jest.fn(() => [ false, { events: mockTimelineData.slice(0, 1), @@ -75,6 +114,7 @@ describe('EQL Tab', () => { }, }, ]); + (useTimelineEvents as jest.Mock).mockImplementation(useTimelineEventsMock); (useTimelineEventsDetails as jest.Mock).mockReturnValue([false, {}]); (useSourcererDataView as jest.Mock).mockReturnValue(mockSourcererScope); @@ -85,30 +125,23 @@ describe('EQL Tab', () => { } ); - props = { - dispatch: {} as Dispatch, - activeTab: TimelineTabs.eql, - columns: defaultHeaders, - end: endDate, - eqlOptions: {}, - isLive: false, - itemsPerPage: 5, - itemsPerPageOptions: [5, 10, 20], - renderCellValue: DefaultCellRenderer, - rowRenderers: defaultRowRenderers, - start: startDate, - timelineId: TimelineId.test, - timerangeKind: 'absolute', - pinnedEventIds: {}, - eventIdToNoteIds: {}, - }; + HTMLElement.prototype.getBoundingClientRect = jest.fn(() => { + return { + width: 1000, + height: 1000, + x: 0, + y: 0, + } as DOMRect; + }); }); describe('rendering', () => { + const fetchNotesMock = jest.spyOn(notesApi, 'fetchNotesByDocumentIds'); test('should render the timeline table', async () => { + fetchNotesMock.mockImplementation(jest.fn()); render( - - + + ); @@ -117,8 +150,8 @@ describe('EQL Tab', () => { test('it renders the timeline column headers', async () => { render( - - + + ); @@ -138,12 +171,175 @@ describe('EQL Tab', () => { ]); render( - - + + ); expect(await screen.findByText('No results found')).toBeVisible(); }); + + describe('pagination', () => { + beforeEach(() => { + // pagination tests need more than 1 record so here + // we return 5 records instead of just 1. + useTimelineEventsMock = jest.fn(() => [ + false, + { + events: structuredClone(mockTimelineData.slice(0, 5)), + pageInfo: { + activePage: 0, + totalPages: 5, + }, + refreshedAt: Date.now(), + /* + * `totalCount` could be any number w.r.t this test + * and actually means total hits on elastic search + * and not the fecthed number of records. + * + * This helps in testing `sampleSize` and `loadMore` + */ + totalCount: 50, + loadPage: loadPageMock, + }, + ]); + + (useTimelineEvents as jest.Mock).mockImplementation(useTimelineEventsMock); + }); + + afterEach(() => { + jest.clearAllMocks(); + }); + + it( + 'should load notes for current page only', + async () => { + const mockStateWithNoteInTimeline = { + ...mockGlobalState, + timeline: { + ...mockGlobalState.timeline, + timelineById: { + [TimelineId.test]: { + ...mockGlobalState.timeline.timelineById[TimelineId.test], + /* 1 record for each page */ + activeTab: TimelineTabs.eql, + itemsPerPage: 1, + itemsPerPageOptions: [1, 2, 3, 4, 5], + savedObjectId: 'timeline-1', // match timelineId in mocked notes data + pinnedEventIds: { '1': true }, + }, + }, + }, + }; + + render( + + + + ); + + expect(await screen.findByTestId('discoverDocTable')).toBeVisible(); + + expect(screen.getByTestId('pagination-button-previous')).toBeVisible(); + + expect(screen.getByTestId('pagination-button-0')).toHaveAttribute('aria-current', 'true'); + expect(fetchNotesMock).toHaveBeenCalledWith(['1']); + + // Page : 2 + + fetchNotesMock.mockClear(); + expect(screen.getByTestId('pagination-button-1')).toBeVisible(); + + fireEvent.click(screen.getByTestId('pagination-button-1')); + + await waitFor(() => { + expect(screen.getByTestId('pagination-button-1')).toHaveAttribute( + 'aria-current', + 'true' + ); + + expect(fetchNotesMock).toHaveBeenNthCalledWith(1, [mockTimelineData[1]._id]); + }); + + // Page : 3 + + fetchNotesMock.mockClear(); + expect(screen.getByTestId('pagination-button-2')).toBeVisible(); + fireEvent.click(screen.getByTestId('pagination-button-2')); + + await waitFor(() => { + expect(screen.getByTestId('pagination-button-2')).toHaveAttribute( + 'aria-current', + 'true' + ); + + expect(fetchNotesMock).toHaveBeenNthCalledWith(1, [mockTimelineData[2]._id]); + }); + }, + SPECIAL_TEST_TIMEOUT + ); + + it( + 'should load notes for correct page size', + async () => { + const mockStateWithNoteInTimeline = { + ...mockGlobalState, + timeline: { + ...mockGlobalState.timeline, + timelineById: { + [TimelineId.test]: { + ...mockGlobalState.timeline.timelineById[TimelineId.test], + /* 1 record for each page */ + itemsPerPage: 1, + pageIndex: 0, + itemsPerPageOptions: [1, 2, 3, 4, 5], + savedObjectId: 'timeline-1', // match timelineId in mocked notes data + pinnedEventIds: { '1': true }, + }, + }, + }, + }; + + render( + + + + ); + + expect(await screen.findByTestId('discoverDocTable')).toBeVisible(); + + expect(screen.getByTestId('pagination-button-previous')).toBeVisible(); + + expect(screen.getByTestId('pagination-button-0')).toHaveAttribute('aria-current', 'true'); + expect(screen.getByTestId('tablePaginationPopoverButton')).toHaveTextContent( + 'Rows per page: 1' + ); + fireEvent.click(screen.getByTestId('tablePaginationPopoverButton')); + + await waitFor(() => { + expect(screen.getByTestId('tablePagination-2-rows')).toBeVisible(); + }); + + fetchNotesMock.mockClear(); + fireEvent.click(screen.getByTestId('tablePagination-2-rows')); + + await waitFor(() => { + expect(fetchNotesMock).toHaveBeenNthCalledWith(1, [ + mockTimelineData[0]._id, + mockTimelineData[1]._id, + ]); + }); + }, + SPECIAL_TEST_TIMEOUT + ); + }); }); }); diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs/eql/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs/eql/index.tsx index 22289d090ab39..0b2de48e89693 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs/eql/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs/eql/index.tsx @@ -7,7 +7,7 @@ import { EuiFlexGroup } from '@elastic/eui'; import { isEmpty } from 'lodash/fp'; -import React, { useCallback, useMemo } from 'react'; +import React, { useCallback, useEffect, useMemo, useState } from 'react'; import type { ConnectedProps } from 'react-redux'; import { connect } from 'react-redux'; import deepEqual from 'fast-deep-equal'; @@ -17,6 +17,7 @@ import type { EuiDataGridControlColumn } from '@elastic/eui'; import { DataLoadingState } from '@kbn/unified-data-table'; import { useExpandableFlyoutApi } from '@kbn/expandable-flyout'; import type { RunTimeMappings } from '@kbn/timelines-plugin/common/search_strategy'; +import { useFetchNotes } from '../../../../../notes/hooks/use_fetch_notes'; import { InputsModelId } from '../../../../../common/store/inputs/constants'; import { useKibana } from '../../../../../common/lib/kibana'; import { @@ -65,6 +66,13 @@ export const EqlTabContentComponent: React.FC = ({ pinnedEventIds, eventIdToNoteIds, }) => { + /* + * Needs to be maintained for each table in each tab independently + * and consequently it cannot be the part of common redux state + * of the timeline. + * + */ + const [pageIndex, setPageIndex] = useState(0); const { telemetry } = useKibana().services; const { query: eqlQuery = '', ...restEqlOption } = eqlOptions; const { portalNode: eqlEventsCountPortalNode } = useEqlEventsCountPortal(); @@ -97,24 +105,42 @@ export const EqlTabContentComponent: React.FC = ({ [end, isBlankTimeline, loadingSourcerer, start] ); - const [ - dataLoadingState, - { events, inspect, totalCount, pageInfo, loadPage, refreshedAt, refetch }, - ] = useTimelineEvents({ - dataViewId, - endDate: end, - eqlOptions: restEqlOption, - fields: timelineQueryFieldsFromColumns, - filterQuery: eqlQuery ?? '', - id: timelineId, - indexNames: selectedPatterns, - language: 'eql', - limit: sampleSize, - runtimeMappings: sourcererDataView.runtimeFieldMap as RunTimeMappings, - skip: !canQueryTimeline(), - startDate: start, - timerangeKind, - }); + const [dataLoadingState, { events, inspect, totalCount, loadPage, refreshedAt, refetch }] = + useTimelineEvents({ + dataViewId, + endDate: end, + eqlOptions: restEqlOption, + fields: timelineQueryFieldsFromColumns, + filterQuery: eqlQuery ?? '', + id: timelineId, + indexNames: selectedPatterns, + language: 'eql', + limit: sampleSize, + runtimeMappings: sourcererDataView.runtimeFieldMap as RunTimeMappings, + skip: !canQueryTimeline(), + startDate: start, + timerangeKind, + }); + + const { onLoad: loadNotesOnEventsLoad } = useFetchNotes(); + + useEffect(() => { + // This useEffect loads the notes only for the events on the current + // page. + const eventsOnCurrentPage = events.slice( + itemsPerPage * pageIndex, + itemsPerPage * (pageIndex + 1) + ); + + loadNotesOnEventsLoad(eventsOnCurrentPage); + }, [events, pageIndex, itemsPerPage, loadNotesOnEventsLoad]); + + /** + * + * Triggers on Datagrid page change + * + */ + const onUpdatePageIndex = useCallback((newPageIndex: number) => setPageIndex(newPageIndex), []); const { openFlyout } = useExpandableFlyoutApi(); const securitySolutionNotesDisabled = useIsExperimentalFeatureEnabled( @@ -263,12 +289,12 @@ export const EqlTabContentComponent: React.FC = ({ refetch={refetch} dataLoadingState={dataLoadingState} totalCount={isBlankTimeline ? 0 : totalCount} - onChangePage={loadPage} + onFetchMoreRecords={loadPage} activeTab={activeTab} updatedAt={refreshedAt} isTextBasedQuery={false} - pageInfo={pageInfo} leadingControlColumns={leadingControlColumns as EuiDataGridControlColumn[]} + onUpdatePageIndex={onUpdatePageIndex} /> diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs/pinned/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs/pinned/index.tsx index 0b2553d23ac5e..8c0ecbeecfdcc 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs/pinned/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs/pinned/index.tsx @@ -6,13 +6,14 @@ */ import { isEmpty } from 'lodash/fp'; -import React, { useMemo, useCallback, memo } from 'react'; +import React, { useMemo, useCallback, memo, useState, useEffect } from 'react'; import type { ConnectedProps } from 'react-redux'; import { connect } from 'react-redux'; import deepEqual from 'fast-deep-equal'; import type { EuiDataGridControlColumn } from '@elastic/eui'; import { useExpandableFlyoutApi } from '@kbn/expandable-flyout'; import type { RunTimeMappings } from '@kbn/timelines-plugin/common/search_strategy'; +import { useFetchNotes } from '../../../../../notes/hooks/use_fetch_notes'; import { DocumentDetailsLeftPanelKey, DocumentDetailsRightPanelKey, @@ -68,6 +69,14 @@ export const PinnedTabContentComponent: React.FC = ({ sort, eventIdToNoteIds, }) => { + /* + * Needs to be maintained for each table in each tab independently + * and consequently it cannot be the part of common redux state + * of the timeline. + * + */ + const [pageIndex, setPageIndex] = useState(0); + const { telemetry } = useKibana().services; const { dataViewId, sourcererDataView, selectedPatterns } = useSourcererDataView( SourcererScopeName.timeline @@ -130,7 +139,7 @@ export const PinnedTabContentComponent: React.FC = ({ ); const { augmentedColumnHeaders } = useTimelineColumns(columns); - const [queryLoadingState, { events, totalCount, pageInfo, loadPage, refreshedAt, refetch }] = + const [queryLoadingState, { events, totalCount, loadPage, refreshedAt, refetch }] = useTimelineEvents({ endDate: '', id: `pinned-${timelineId}`, @@ -146,6 +155,26 @@ export const PinnedTabContentComponent: React.FC = ({ timerangeKind: undefined, }); + const { onLoad: loadNotesOnEventsLoad } = useFetchNotes(); + + useEffect(() => { + // This useEffect loads the notes only for the events on the current + // page. + const eventsOnCurrentPage = events.slice( + itemsPerPage * pageIndex, + itemsPerPage * (pageIndex + 1) + ); + + loadNotesOnEventsLoad(eventsOnCurrentPage); + }, [events, pageIndex, itemsPerPage, loadNotesOnEventsLoad]); + + /** + * + * Triggers on Datagrid page change + * + */ + const onUpdatePageIndex = useCallback((newPageIndex: number) => setPageIndex(newPageIndex), []); + const { openFlyout } = useExpandableFlyoutApi(); const securitySolutionNotesDisabled = useIsExperimentalFeatureEnabled( 'securitySolutionNotesDisabled' @@ -257,13 +286,13 @@ export const PinnedTabContentComponent: React.FC = ({ refetch={refetch} dataLoadingState={queryLoadingState} totalCount={totalCount} - onChangePage={loadPage} + onFetchMoreRecords={loadPage} activeTab={TimelineTabs.pinned} updatedAt={refreshedAt} isTextBasedQuery={false} - pageInfo={pageInfo} leadingControlColumns={leadingControlColumns as EuiDataGridControlColumn[]} trailingControlColumns={rowDetailColumn} + onUpdatePageIndex={onUpdatePageIndex} /> ); diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs/query/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs/query/index.test.tsx index f0a2c06bbffb4..cfd8f86af9dac 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs/query/index.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs/query/index.test.tsx @@ -41,6 +41,7 @@ import { useExpandableFlyoutApi } from '@kbn/expandable-flyout'; import { createExpandableFlyoutApiMock } from '../../../../../common/mock/expandable_flyout'; import { OPEN_FLYOUT_BUTTON_TEST_ID } from '../../../../../notes/components/test_ids'; import { userEvent } from '@testing-library/user-event'; +import * as notesApi from '../../../../../notes/api/api'; jest.mock('../../../../../common/components/user_privileges'); @@ -154,7 +155,9 @@ const { storage: storageMock } = createSecuritySolutionStorageMock(); let useTimelineEventsMock = jest.fn(); describe('query tab with unified timeline', () => { + const fetchNotesMock = jest.spyOn(notesApi, 'fetchNotesByDocumentIds'); beforeAll(() => { + fetchNotesMock.mockImplementation(jest.fn()); jest.mocked(useExpandableFlyoutApi).mockImplementation(() => ({ ...createExpandableFlyoutApiMock(), openFlyout: mockOpenFlyout, @@ -176,6 +179,7 @@ describe('query tab with unified timeline', () => { afterEach(() => { jest.clearAllMocks(); storageMock.clear(); + fetchNotesMock.mockClear(); cleanup(); localStorage.clear(); }); @@ -424,6 +428,130 @@ describe('query tab with unified timeline', () => { }, SPECIAL_TEST_TIMEOUT ); + + it( + 'should load notes for current page only', + async () => { + const mockStateWithNoteInTimeline = { + ...mockGlobalState, + timeline: { + ...mockGlobalState.timeline, + timelineById: { + [TimelineId.test]: { + ...mockGlobalState.timeline.timelineById[TimelineId.test], + /* 1 record for each page */ + itemsPerPage: 1, + pageIndex: 0, + itemsPerPageOptions: [1, 2, 3, 4, 5], + savedObjectId: 'timeline-1', // match timelineId in mocked notes data + pinnedEventIds: { '1': true }, + }, + }, + }, + }; + + render( + + + + ); + + expect(await screen.findByTestId('discoverDocTable')).toBeVisible(); + + expect(screen.getByTestId('pagination-button-previous')).toBeVisible(); + + expect(screen.getByTestId('pagination-button-0')).toHaveAttribute('aria-current', 'true'); + expect(fetchNotesMock).toHaveBeenCalledWith(['1']); + + // Page : 2 + + fetchNotesMock.mockClear(); + expect(screen.getByTestId('pagination-button-1')).toBeVisible(); + + fireEvent.click(screen.getByTestId('pagination-button-1')); + + await waitFor(() => { + expect(screen.getByTestId('pagination-button-1')).toHaveAttribute('aria-current', 'true'); + + expect(fetchNotesMock).toHaveBeenNthCalledWith(1, [mockTimelineData[1]._id]); + }); + + // Page : 3 + + fetchNotesMock.mockClear(); + expect(screen.getByTestId('pagination-button-2')).toBeVisible(); + fireEvent.click(screen.getByTestId('pagination-button-2')); + + await waitFor(() => { + expect(screen.getByTestId('pagination-button-2')).toHaveAttribute('aria-current', 'true'); + + expect(fetchNotesMock).toHaveBeenNthCalledWith(1, [mockTimelineData[2]._id]); + }); + }, + SPECIAL_TEST_TIMEOUT + ); + + it( + 'should load notes for correct page size', + async () => { + const mockStateWithNoteInTimeline = { + ...mockGlobalState, + timeline: { + ...mockGlobalState.timeline, + timelineById: { + [TimelineId.test]: { + ...mockGlobalState.timeline.timelineById[TimelineId.test], + /* 1 record for each page */ + itemsPerPage: 1, + pageIndex: 0, + itemsPerPageOptions: [1, 2, 3, 4, 5], + savedObjectId: 'timeline-1', // match timelineId in mocked notes data + pinnedEventIds: { '1': true }, + }, + }, + }, + }; + + render( + + + + ); + + expect(await screen.findByTestId('discoverDocTable')).toBeVisible(); + + expect(screen.getByTestId('pagination-button-previous')).toBeVisible(); + + expect(screen.getByTestId('pagination-button-0')).toHaveAttribute('aria-current', 'true'); + expect(screen.getByTestId('tablePaginationPopoverButton')).toHaveTextContent( + 'Rows per page: 1' + ); + fireEvent.click(screen.getByTestId('tablePaginationPopoverButton')); + + await waitFor(() => { + expect(screen.getByTestId('tablePagination-2-rows')).toBeVisible(); + }); + + fetchNotesMock.mockClear(); + fireEvent.click(screen.getByTestId('tablePagination-2-rows')); + + await waitFor(() => { + expect(fetchNotesMock).toHaveBeenNthCalledWith(1, [ + mockTimelineData[0]._id, + mockTimelineData[1]._id, + ]); + }); + }, + SPECIAL_TEST_TIMEOUT + ); }); describe('columns', () => { diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs/query/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs/query/index.tsx index 967253a34a71a..f614290fd6a5a 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs/query/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs/query/index.tsx @@ -6,7 +6,7 @@ */ import { isEmpty } from 'lodash/fp'; -import React, { useMemo, useEffect, useCallback } from 'react'; +import React, { useMemo, useEffect, useCallback, useState } from 'react'; import type { ConnectedProps } from 'react-redux'; import { connect, useDispatch } from 'react-redux'; import deepEqual from 'fast-deep-equal'; @@ -15,6 +15,7 @@ import { getEsQueryConfig } from '@kbn/data-plugin/common'; import { DataLoadingState } from '@kbn/unified-data-table'; import { useExpandableFlyoutApi } from '@kbn/expandable-flyout'; import type { RunTimeMappings } from '@kbn/timelines-plugin/common/search_strategy'; +import { useFetchNotes } from '../../../../../notes/hooks/use_fetch_notes'; import { DocumentDetailsLeftPanelKey, DocumentDetailsRightPanelKey, @@ -92,6 +93,13 @@ export const QueryTabContentComponent: React.FC = ({ selectedPatterns, sourcererDataView, } = useSourcererDataView(SourcererScopeName.timeline); + /* + * `pageIndex` needs to be maintained for each table in each tab independently + * and consequently it cannot be the part of common redux state + * of the timeline. + * + */ + const [pageIndex, setPageIndex] = useState(0); const { uiSettings, telemetry, timelineDataService } = useKibana().services; const { @@ -167,7 +175,7 @@ export const QueryTabContentComponent: React.FC = ({ const [ dataLoadingState, - { events, inspect, totalCount, pageInfo, loadPage, refreshedAt, refetch }, + { events, inspect, totalCount, loadPage: loadNextEventBatch, refreshedAt, refetch }, ] = useTimelineEvents({ dataViewId, endDate: end, @@ -184,6 +192,26 @@ export const QueryTabContentComponent: React.FC = ({ timerangeKind, }); + const { onLoad: loadNotesOnEventsLoad } = useFetchNotes(); + + useEffect(() => { + // This useEffect loads the notes only for the events on the current + // page. + const eventsOnCurrentPage = events.slice( + itemsPerPage * pageIndex, + itemsPerPage * (pageIndex + 1) + ); + + loadNotesOnEventsLoad(eventsOnCurrentPage); + }, [events, pageIndex, itemsPerPage, loadNotesOnEventsLoad]); + + /** + * + * Triggers on Datagrid page change + * + */ + const onUpdatePageIndex = useCallback((newPageIndex: number) => setPageIndex(newPageIndex), []); + const { openFlyout } = useExpandableFlyoutApi(); const securitySolutionNotesDisabled = useIsExperimentalFeatureEnabled( 'securitySolutionNotesDisabled' @@ -355,11 +383,11 @@ export const QueryTabContentComponent: React.FC = ({ dataLoadingState={dataLoadingState} totalCount={isBlankTimeline ? 0 : totalCount} leadingControlColumns={leadingControlColumns as EuiDataGridControlColumn[]} - onChangePage={loadPage} + onFetchMoreRecords={loadNextEventBatch} activeTab={activeTab} updatedAt={refreshedAt} isTextBasedQuery={false} - pageInfo={pageInfo} + onUpdatePageIndex={onUpdatePageIndex} /> ); diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/unified_components/data_table/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/unified_components/data_table/index.test.tsx index 649817d5f8ef2..3f24fc8df4aa9 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/unified_components/data_table/index.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/unified_components/data_table/index.test.tsx @@ -72,7 +72,7 @@ const TestComponent = (props: TestComponentProps) => { refetch={refetchMock} dataLoadingState={DataLoadingState.loaded} totalCount={mockTimelineData.length} - onChangePage={onChangePageMock} + onFetchMoreRecords={onChangePageMock} updatedAt={Date.now()} onSetColumns={jest.fn()} onFilter={jest.fn()} diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/unified_components/data_table/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/unified_components/data_table/index.tsx index fa5b83f23576a..99e00547f1c33 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/unified_components/data_table/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/unified_components/data_table/index.tsx @@ -30,7 +30,7 @@ import type { TimelineItem } from '../../../../../../common/search_strategy'; import { useKibana } from '../../../../../common/lib/kibana'; import type { ColumnHeaderOptions, - OnChangePage, + OnFetchMoreRecords, RowRenderer, TimelineTabs, } from '../../../../../../common/types/timeline'; @@ -64,7 +64,7 @@ type CommonDataTableProps = { refetch: inputsModel.Refetch; onFieldEdited: () => void; totalCount: number; - onChangePage: OnChangePage; + onFetchMoreRecords: OnFetchMoreRecords; activeTab: TimelineTabs; dataLoadingState: DataLoadingState; updatedAt: number; @@ -79,6 +79,7 @@ type CommonDataTableProps = { | 'renderCustomGridBody' | 'trailingControlColumns' | 'isSortEnabled' + | 'onUpdatePageIndex' >; interface DataTableProps extends CommonDataTableProps { @@ -102,13 +103,14 @@ export const TimelineDataTableComponent: React.FC = memo( refetch, dataLoadingState, totalCount, - onChangePage, + onFetchMoreRecords, updatedAt, isTextBasedQuery = false, onSetColumns, onSort, onFilter, leadingControlColumns, + onUpdatePageIndex, }) { const dispatch = useDispatch(); @@ -235,9 +237,9 @@ export const TimelineDataTableComponent: React.FC = memo( ); const handleFetchMoreRecords = useCallback(() => { - onChangePage(fetchedPage + 1); + onFetchMoreRecords(fetchedPage + 1); setFechedPage(fetchedPage + 1); - }, [fetchedPage, onChangePage]); + }, [fetchedPage, onFetchMoreRecords]); const additionalControls = useMemo( () => , @@ -424,6 +426,7 @@ export const TimelineDataTableComponent: React.FC = memo( renderCustomGridBody={finalRenderCustomBodyCallback} trailingControlColumns={finalTrailControlColumns} externalControlColumns={leadingControlColumns} + onUpdatePageIndex={onUpdatePageIndex} /> diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/unified_components/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/unified_components/index.test.tsx index c660893ba379e..7d9bde02259a4 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/unified_components/index.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/unified_components/index.test.tsx @@ -107,10 +107,11 @@ const TestComponent = ( events: localMockedTimelineData, refetch: jest.fn(), totalCount: localMockedTimelineData.length, - onChangePage: jest.fn(), + onFetchMoreRecords: jest.fn(), dataLoadingState: DataLoadingState.loaded, updatedAt: Date.now(), isTextBasedQuery: false, + onUpdatePageIndex: jest.fn(), }; const dispatch = useDispatch(); diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/unified_components/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/unified_components/index.tsx index 112886f93ca32..d350b4b530808 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/unified_components/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/unified_components/index.tsx @@ -12,7 +12,7 @@ import { useDispatch } from 'react-redux'; import { generateFilters } from '@kbn/data-plugin/public'; import type { DataView, DataViewField } from '@kbn/data-plugin/common'; import type { SortOrder } from '@kbn/saved-search-plugin/public'; -import type { DataLoadingState } from '@kbn/unified-data-table'; +import type { DataLoadingState, UnifiedDataTableProps } from '@kbn/unified-data-table'; import { useColumns } from '@kbn/unified-data-table'; import { popularizeField } from '@kbn/unified-data-table/src/utils/popularize_field'; import type { DropType } from '@kbn/dom-drag-drop'; @@ -33,7 +33,7 @@ import type { TimelineItem } from '../../../../../common/search_strategy'; import { useKibana } from '../../../../common/lib/kibana'; import type { ColumnHeaderOptions, - OnChangePage, + OnFetchMoreRecords, RowRenderer, SortColumnTimeline, TimelineTabs, @@ -106,7 +106,7 @@ interface Props { events: TimelineItem[]; refetch: inputsModel.Refetch; totalCount: number; - onChangePage: OnChangePage; + onFetchMoreRecords: OnFetchMoreRecords; activeTab: TimelineTabs; dataLoadingState: DataLoadingState; updatedAt: number; @@ -114,6 +114,7 @@ interface Props { dataView: DataView; trailingControlColumns?: EuiDataGridProps['trailingControlColumns']; leadingControlColumns?: EuiDataGridProps['leadingControlColumns']; + onUpdatePageIndex?: UnifiedDataTableProps['onUpdatePageIndex']; } const UnifiedTimelineComponent: React.FC = ({ @@ -129,12 +130,13 @@ const UnifiedTimelineComponent: React.FC = ({ refetch, dataLoadingState, totalCount, - onChangePage, + onFetchMoreRecords, updatedAt, isTextBasedQuery, dataView, trailingControlColumns, leadingControlColumns, + onUpdatePageIndex, }) => { const dispatch = useDispatch(); const unifiedFieldListContainerRef = useRef(null); @@ -435,13 +437,14 @@ const UnifiedTimelineComponent: React.FC = ({ onFieldEdited={onFieldEdited} dataLoadingState={dataLoadingState} totalCount={totalCount} - onChangePage={onChangePage} + onFetchMoreRecords={onFetchMoreRecords} activeTab={activeTab} updatedAt={updatedAt} isTextBasedQuery={isTextBasedQuery} onFilter={onAddFilter as DocViewFilterFn} trailingControlColumns={trailingControlColumns} leadingControlColumns={leadingControlColumns} + onUpdatePageIndex={onUpdatePageIndex} /> diff --git a/x-pack/plugins/security_solution/public/timelines/containers/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/containers/index.test.tsx index f00ca0551a9a3..822740f3b9978 100644 --- a/x-pack/plugins/security_solution/public/timelines/containers/index.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/containers/index.test.tsx @@ -30,7 +30,7 @@ jest.mock('../../notes/hooks/use_fetch_notes'); const onLoadMock = jest.fn(); const useFetchNotesMock = useFetchNotes as jest.Mock; -const mockEvents = mockTimelineData.filter((i, index) => index <= 11); +const mockEvents = mockTimelineData.slice(0, 10); const mockSearch = jest.fn(); @@ -70,13 +70,13 @@ jest.mock('../../common/lib/kibana', () => ({ }, edges: mockEvents.map((item) => ({ node: item })), pageInfo: { - activePage: 0, + activePage: args.pagination.activePage, totalPages: 10, }, rawResponse: {}, totalCount: mockTimelineData.length, }); - }, 0); + }, 50); return { unsubscribe: jest.fn() }; }), }; @@ -124,12 +124,12 @@ describe('useTimelineEvents', () => { const endDate: string = '3000-01-01T00:00:00.000Z'; const props: UseTimelineEventsProps = { dataViewId: 'data-view-id', - endDate: '', + endDate, id: TimelineId.active, indexNames: ['filebeat-*'], fields: ['@timestamp', 'event.kind'], filterQuery: '', - startDate: '', + startDate, limit: 25, runtimeMappings: {}, sort: initSortDefault, @@ -166,10 +166,9 @@ describe('useTimelineEvents', () => { >((args) => useTimelineEvents(args), { initialProps: props, }); - // useEffect on params request await waitFor(() => new Promise((resolve) => resolve(null))); - rerender({ ...props, startDate, endDate }); + rerender({ ...props, startDate: '', endDate: '' }); // useEffect on params request await waitFor(() => { expect(mockSearch).toHaveBeenCalledTimes(2); @@ -197,12 +196,6 @@ describe('useTimelineEvents', () => { initialProps: props, }); - // useEffect on params request - await waitFor(() => new Promise((resolve) => resolve(null))); - rerender({ ...props, startDate, endDate }); - // useEffect on params request - await waitFor(() => new Promise((resolve) => resolve(null))); - mockUseRouteSpy.mockReturnValue([ { pageName: SecurityPageName.timelines, @@ -213,7 +206,13 @@ describe('useTimelineEvents', () => { }, ]); - expect(mockSearch).toHaveBeenCalledTimes(2); + rerender({ ...props, startDate, endDate }); + + await waitFor(() => { + expect(result.current[0]).toEqual(DataLoadingState.loaded); + }); + + expect(mockSearch).toHaveBeenCalledTimes(1); expect(result.current).toEqual([ DataLoadingState.loaded, @@ -283,7 +282,7 @@ describe('useTimelineEvents', () => { // useEffect on params request await waitFor(() => new Promise((resolve) => resolve(null))); - expect(mockSearch).toHaveBeenCalledTimes(2); + expect(mockSearch).toHaveBeenCalledTimes(1); mockSearch.mockClear(); rerender({ @@ -307,7 +306,7 @@ describe('useTimelineEvents', () => { // useEffect on params request await waitFor(() => new Promise((resolve) => resolve(null))); - expect(mockSearch).toHaveBeenCalledTimes(2); + expect(mockSearch).toHaveBeenCalledTimes(1); mockSearch.mockClear(); rerender({ ...props, startDate, endDate, fields: ['@timestamp'] }); @@ -325,7 +324,7 @@ describe('useTimelineEvents', () => { // useEffect on params request await waitFor(() => new Promise((resolve) => resolve(null))); - expect(mockSearch).toHaveBeenCalledTimes(2); + expect(mockSearch).toHaveBeenCalledTimes(1); mockSearch.mockClear(); // remove `event.kind` from default fields @@ -343,16 +342,22 @@ describe('useTimelineEvents', () => { await waitFor(() => expect(mockSearch).toHaveBeenCalledTimes(0)); }); - describe('Fetch Notes', () => { - test('should call onLoad for notes when events are fetched', async () => { - renderHook((args) => useTimelineEvents(args), { - initialProps: props, - }); + test('should return the combined list of events for all the pages when multiple pages are queried', async () => { + const { result } = renderHook((args) => useTimelineEvents(args), { + initialProps: { ...props }, + }); + await waitFor(() => { + expect(result.current[1].events).toHaveLength(10); + }); - await waitFor(() => { - expect(mockSearch).toHaveBeenCalledTimes(1); - expect(onLoadMock).toHaveBeenNthCalledWith(1, expect.objectContaining(mockEvents)); - }); + result.current[1].loadPage(1); + + await waitFor(() => { + expect(result.current[0]).toEqual(DataLoadingState.loadingMore); + }); + + await waitFor(() => { + expect(result.current[1].events).toHaveLength(20); }); }); }); diff --git a/x-pack/plugins/security_solution/public/timelines/containers/index.tsx b/x-pack/plugins/security_solution/public/timelines/containers/index.tsx index 0301f0123c30f..baaed281c7393 100644 --- a/x-pack/plugins/security_solution/public/timelines/containers/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/containers/index.tsx @@ -7,7 +7,7 @@ import deepEqual from 'fast-deep-equal'; import { isEmpty, noop } from 'lodash/fp'; -import { useCallback, useEffect, useRef, useState } from 'react'; +import { useCallback, useEffect, useRef, useState, useMemo } from 'react'; import { useDispatch } from 'react-redux'; import { Subscription } from 'rxjs'; @@ -46,12 +46,21 @@ import type { } from '../../../common/search_strategy/timeline/events/eql'; import { useTrackHttpRequest } from '../../common/lib/apm/use_track_http_request'; import { APP_UI_ID } from '../../../common/constants'; -import { useFetchNotes } from '../../notes/hooks/use_fetch_notes'; export interface TimelineArgs { events: TimelineItem[]; id: string; inspect: InspectResponse; + + /** + * `loadPage` loads the next page/batch of records. + * This is different from the data grid pages. Data grid pagination is only + * client side and changing data grid pages does not impact this function. + * + * When user manually requests next batch of records, then a next batch is fetched + * irrespective of where user is in Data grid pagination. + * + */ loadPage: LoadPage; pageInfo: Pick; refetch: inputsModel.Refetch; @@ -174,6 +183,15 @@ export const useTimelineEventsHandler = ({ } }, [dispatch, id]); + /** + * `wrappedLoadPage` loads the next page/batch of records. + * This is different from the data grid pages. Data grid pagination is only + * client side and changing data grid pages does not impact this function. + * + * When user manually requests next batch of records, then a next batch is fetched + * irrespective of where user is in Data grid pagination. + * + */ const wrappedLoadPage = useCallback( (newActivePage: number) => { clearSignalsState(); @@ -186,6 +204,12 @@ export const useTimelineEventsHandler = ({ [clearSignalsState, id] ); + useEffect(() => { + return () => { + searchSubscription$.current?.unsubscribe(); + }; + }, []); + const refetchGrid = useCallback(() => { if (refetch.current != null) { refetch.current(); @@ -240,10 +264,12 @@ export const useTimelineEventsHandler = ({ next: (response) => { if (!isRunningResponse(response)) { endTracking('success'); + setLoading(DataLoadingState.loaded); setTimelineResponse((prevResponse) => { const newTimelineResponse = { ...prevResponse, + /**/ events: getTimelineEvents(response.edges), inspect: getInspectResponse(response, prevResponse.inspect), pageInfo: response.pageInfo, @@ -269,6 +295,7 @@ export const useTimelineEventsHandler = ({ }, error: (msg) => { endTracking(abortCtrl.current.signal.aborted ? 'aborted' : 'error'); + setLoading(DataLoadingState.loaded); data.search.showError(msg); searchSubscription$.current.unsubscribe(); @@ -483,8 +510,8 @@ export const useTimelineEvents = ({ sort = initSortDefault, skip = false, timerangeKind, - fetchNotes = true, }: UseTimelineEventsProps): [DataLoadingState, TimelineArgs] => { + const [eventsPerPage, setEventsPerPage] = useState([[]]); const [dataLoadingState, timelineResponse, timelineSearchHandler] = useTimelineEventsHandler({ dataViewId, endDate, @@ -501,19 +528,35 @@ export const useTimelineEvents = ({ skip, timerangeKind, }); - const { onLoad } = useFetchNotes(); - const onTimelineSearchComplete: OnNextResponseHandler = useCallback( - (response) => { - if (fetchNotes) onLoad(response.events); - }, - [fetchNotes, onLoad] - ); + useEffect(() => { + /* + * `timelineSearchHandler` only returns the events for the current page. + * This effect is responsible for storing the events for each page so that + * the combined list of events can be supplied to DataGrid. + * + * */ + setEventsPerPage((prev) => { + const result = [...prev]; + result[timelineResponse.pageInfo.activePage] = timelineResponse.events; + return result; + }); + }, [timelineResponse.events, timelineResponse.pageInfo.activePage]); useEffect(() => { if (!timelineSearchHandler) return; - timelineSearchHandler(onTimelineSearchComplete); - }, [timelineSearchHandler, onTimelineSearchComplete]); + timelineSearchHandler(); + }, [timelineSearchHandler]); + + const combinedEvents = useMemo(() => eventsPerPage.flat(), [eventsPerPage]); + + const combinedResponse = useMemo( + () => ({ + ...timelineResponse, + events: combinedEvents, + }), + [timelineResponse, combinedEvents] + ); - return [dataLoadingState, timelineResponse]; + return [dataLoadingState, combinedResponse]; }; diff --git a/x-pack/plugins/security_solution/public/types.ts b/x-pack/plugins/security_solution/public/types.ts index d0387c5d3abe0..2380c5a7cb08e 100644 --- a/x-pack/plugins/security_solution/public/types.ts +++ b/x-pack/plugins/security_solution/public/types.ts @@ -61,6 +61,7 @@ import type { PluginStartContract } from '@kbn/alerting-plugin/public/plugin'; import type { MapsStartApi } from '@kbn/maps-plugin/public'; import type { IntegrationAssistantPluginStart } from '@kbn/integration-assistant-plugin/public'; import type { ServerlessPluginStart } from '@kbn/serverless/public'; +import type { DiscoverSharedPublicStart } from '@kbn/discover-shared-plugin/public'; import type { ResolverPluginSetup } from './resolver/types'; import type { Inspect } from '../common/search_strategy'; import type { Detections } from './detections'; @@ -107,6 +108,7 @@ export interface SetupPlugins { ml?: MlPluginSetup; cases?: CasesPublicSetup; data: DataPublicPluginSetup; + discoverShared: DiscoverSharedPublicStart; } /** @@ -138,7 +140,7 @@ export interface StartPlugins { uiActions: UiActionsStart; maps: MapsStartApi; ml?: MlPluginStart; - spaces?: SpacesPluginStart; + spaces: SpacesPluginStart; dataViewFieldEditor: IndexPatternFieldEditorStart; osquery: OsqueryPluginStart; security: SecurityPluginStart; diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/error_state/index.ts b/x-pack/plugins/security_solution/scripts/siem_migration/draw_graphs.js similarity index 74% rename from x-pack/plugins/enterprise_search/public/applications/shared/error_state/index.ts rename to x-pack/plugins/security_solution/scripts/siem_migration/draw_graphs.js index b8e1783dbe901..010b6c15f323c 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/error_state/index.ts +++ b/x-pack/plugins/security_solution/scripts/siem_migration/draw_graphs.js @@ -5,4 +5,5 @@ * 2.0. */ -export { ErrorStatePrompt, ErrorStateCallout } from './error_state_prompt'; +require('../../../../../src/setup_node_env'); +require('./draw_graphs_script').draw(); diff --git a/x-pack/plugins/security_solution/scripts/siem_migration/draw_graphs_script.ts b/x-pack/plugins/security_solution/scripts/siem_migration/draw_graphs_script.ts new file mode 100644 index 0000000000000..4cb2b5c740474 --- /dev/null +++ b/x-pack/plugins/security_solution/scripts/siem_migration/draw_graphs_script.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 type { InferenceClient } from '@kbn/inference-plugin/server'; +import type { + ActionsClientChatOpenAI, + ActionsClientSimpleChatModel, +} from '@kbn/langchain/server/language_models'; +import type { Logger } from '@kbn/logging'; +import { ToolingLog } from '@kbn/tooling-log'; +import { FakeLLM } from '@langchain/core/utils/testing'; +import fs from 'fs/promises'; +import path from 'path'; +import { getRuleMigrationAgent } from '../../server/lib/siem_migrations/rules/task/agent'; +import type { IntegrationRetriever } from '../../server/lib/siem_migrations/rules/task/util/integration_retriever'; +import type { PrebuiltRulesMapByName } from '../../server/lib/siem_migrations/rules/task/util/prebuilt_rules'; +import type { RuleResourceRetriever } from '../../server/lib/siem_migrations/rules/task/util/rule_resource_retriever'; + +interface Drawable { + drawMermaidPng: () => Promise; +} + +const mockLlm = new FakeLLM({ + response: JSON.stringify({}, null, 2), +}) as unknown as ActionsClientChatOpenAI | ActionsClientSimpleChatModel; + +const inferenceClient = {} as InferenceClient; +const connectorId = 'draw_graphs'; +const prebuiltRulesMap = {} as PrebuiltRulesMapByName; +const resourceRetriever = {} as RuleResourceRetriever; +const integrationRetriever = {} as IntegrationRetriever; + +const createLlmInstance = () => { + return mockLlm; +}; + +async function getAgentGraph(logger: Logger): Promise { + const model = createLlmInstance(); + const graph = getRuleMigrationAgent({ + model, + inferenceClient, + prebuiltRulesMap, + resourceRetriever, + integrationRetriever, + connectorId, + logger, + }); + return graph.getGraphAsync({ xray: true }); +} + +export const drawGraph = async ({ + getGraphAsync, + outputFilename, +}: { + getGraphAsync: (logger: Logger) => Promise; + outputFilename: string; +}) => { + const logger = new ToolingLog({ + level: 'info', + writeTo: process.stdout, + }) as unknown as Logger; + logger.info('Compiling graph'); + const outputPath = path.join(__dirname, outputFilename); + const graph = await getGraphAsync(logger); + const output = await graph.drawMermaidPng(); + const buffer = Buffer.from(await output.arrayBuffer()); + logger.info(`Writing graph to ${outputPath}`); + await fs.writeFile(outputPath, buffer); +}; + +export const draw = async () => { + await drawGraph({ + getGraphAsync: getAgentGraph, + outputFilename: '../../docs/siem_migration/img/agent_graph.png', + }); +}; diff --git a/x-pack/plugins/security_solution/server/endpoint/endpoint_app_context_services.ts b/x-pack/plugins/security_solution/server/endpoint/endpoint_app_context_services.ts index 1afa24ebbd529..bdffed6c1269a 100644 --- a/x-pack/plugins/security_solution/server/endpoint/endpoint_app_context_services.ts +++ b/x-pack/plugins/security_solution/server/endpoint/endpoint_app_context_services.ts @@ -21,7 +21,7 @@ import type { FleetStartContract, MessageSigningServiceInterface, } from '@kbn/fleet-plugin/server'; -import type { PluginStartContract as AlertsPluginStartContract } from '@kbn/alerting-plugin/server'; +import type { AlertingServerStart } from '@kbn/alerting-plugin/server'; import type { CloudSetup } from '@kbn/cloud-plugin/server'; import type { FleetActionsClientInterface } from '@kbn/fleet-plugin/server/services/actions/types'; import type { PluginStartContract as ActionsPluginStartContract } from '@kbn/actions-plugin/server'; @@ -73,7 +73,7 @@ export interface EndpointAppContextServiceStartContract { fleetStartServices: FleetStartContract; manifestManager: ManifestManager; security: SecurityServiceStart; - alerting: AlertsPluginStartContract; + alerting: AlertingServerStart; config: ConfigType; registerListsServerExtension?: ListsServerExtensionRegistrar; licenseService: LicenseService; diff --git a/x-pack/plugins/security_solution/server/endpoint/services/workflow_insights/constants.ts b/x-pack/plugins/security_solution/server/endpoint/services/workflow_insights/constants.ts index f0884f2214cb8..f8b97932289f5 100644 --- a/x-pack/plugins/security_solution/server/endpoint/services/workflow_insights/constants.ts +++ b/x-pack/plugins/security_solution/server/endpoint/services/workflow_insights/constants.ts @@ -5,7 +5,7 @@ * 2.0. */ -export const DATA_STREAM_PREFIX = '.security-workflow-insights'; +export const DATA_STREAM_PREFIX = '.edr-workflow-insights'; export const COMPONENT_TEMPLATE_NAME = `${DATA_STREAM_PREFIX}-component-template`; export const INDEX_TEMPLATE_NAME = `${DATA_STREAM_PREFIX}-index-template`; export const INGEST_PIPELINE_NAME = `${DATA_STREAM_PREFIX}-ingest-pipeline`; diff --git a/x-pack/plugins/security_solution/server/endpoint/services/workflow_insights/helpers.test.ts b/x-pack/plugins/security_solution/server/endpoint/services/workflow_insights/helpers.test.ts index 33f1851091167..119c1848f6a1a 100644 --- a/x-pack/plugins/security_solution/server/endpoint/services/workflow_insights/helpers.test.ts +++ b/x-pack/plugins/security_solution/server/endpoint/services/workflow_insights/helpers.test.ts @@ -6,11 +6,15 @@ */ import type { ElasticsearchClient } from '@kbn/core/server'; -import { elasticsearchServiceMock } from '@kbn/core-elasticsearch-server-mocks'; + import { DataStreamSpacesAdapter } from '@kbn/data-stream-adapter'; +import { DefendInsightType } from '@kbn/elastic-assistant-common'; +import { elasticsearchServiceMock } from '@kbn/core-elasticsearch-server-mocks'; import { kibanaPackageJson } from '@kbn/repo-info'; -import { createDatastream, createPipeline } from './helpers'; +import type { SearchParams } from '../../../../common/endpoint/types/workflow_insights'; + +import { buildEsQueryParams, createDatastream, createPipeline } from './helpers'; import { DATA_STREAM_PREFIX, COMPONENT_TEMPLATE_NAME, @@ -19,6 +23,12 @@ import { TOTAL_FIELDS_LIMIT, } from './constants'; import { securityWorkflowInsightsFieldMap } from './field_map_configurations'; +import { + ActionType, + Category, + SourceType, + TargetType, +} from '../../../../common/endpoint/types/workflow_insights'; jest.mock('@kbn/data-stream-adapter', () => ({ DataStreamSpacesAdapter: jest.fn().mockImplementation(() => ({ @@ -77,4 +87,64 @@ describe('helpers', () => { }); }); }); + + describe('buildEsQueryParams', () => { + it('should build es query correct', () => { + const searchParams: SearchParams = { + size: 50, + from: 50, + ids: ['id1', 'id2'], + categories: [Category.Endpoint], + types: [DefendInsightType.Enum.incompatible_antivirus], + sourceTypes: [SourceType.LlmConnector], + sourceIds: ['source-id1', 'source-id2'], + targetTypes: [TargetType.Endpoint], + targetIds: ['target-id1', 'target-id2'], + actionTypes: [ActionType.Refreshed, ActionType.Remediated], + }; + const result = buildEsQueryParams(searchParams); + expect(result).toEqual([ + { + terms: { + _id: ['id1', 'id2'], + }, + }, + { + terms: { + categories: ['endpoint'], + }, + }, + { + terms: { + types: ['incompatible_antivirus'], + }, + }, + { + terms: { + 'source.type': ['llm-connector'], + }, + }, + { + terms: { + 'source.id': ['source-id1', 'source-id2'], + }, + }, + { + terms: { + 'target.type': ['endpoint'], + }, + }, + { + terms: { + 'target.id': ['target-id1', 'target-id2'], + }, + }, + { + terms: { + 'action.type': ['refreshed', 'remediated'], + }, + }, + ]); + }); + }); }); diff --git a/x-pack/plugins/security_solution/server/endpoint/services/workflow_insights/helpers.ts b/x-pack/plugins/security_solution/server/endpoint/services/workflow_insights/helpers.ts index 54b449edf86ff..f0057faed6aa6 100644 --- a/x-pack/plugins/security_solution/server/endpoint/services/workflow_insights/helpers.ts +++ b/x-pack/plugins/security_solution/server/endpoint/services/workflow_insights/helpers.ts @@ -5,10 +5,15 @@ * 2.0. */ +import { get as _get } from 'lodash'; + +import type { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/types'; import type { ElasticsearchClient } from '@kbn/core/server'; import { DataStreamSpacesAdapter } from '@kbn/data-stream-adapter'; +import type { SearchParams } from '../../../../common/endpoint/types/workflow_insights'; + import { COMPONENT_TEMPLATE_NAME, DATA_STREAM_PREFIX, @@ -60,3 +65,34 @@ export async function createPipeline(esClient: ElasticsearchClient): Promise { + if (!validKeys.has(k)) { + return acc; + } + + const paramKey = _get(paramFieldMap, k, k); + const next = { terms: { [paramKey]: v } }; + + return [...acc, next]; + }, []); +} diff --git a/x-pack/plugins/security_solution/server/endpoint/services/workflow_insights/index.test.ts b/x-pack/plugins/security_solution/server/endpoint/services/workflow_insights/index.test.ts index 6271bd780dedd..792a7a9ecd949 100644 --- a/x-pack/plugins/security_solution/server/endpoint/services/workflow_insights/index.test.ts +++ b/x-pack/plugins/security_solution/server/endpoint/services/workflow_insights/index.test.ts @@ -5,22 +5,92 @@ * 2.0. */ +import { merge } from 'lodash'; +import moment from 'moment'; import { ReplaySubject } from 'rxjs'; import type { ElasticsearchClient, Logger } from '@kbn/core/server'; -import { elasticsearchServiceMock } from '@kbn/core-elasticsearch-server-mocks'; + import { DataStreamSpacesAdapter } from '@kbn/data-stream-adapter'; -import { loggerMock } from '@kbn/logging-mocks'; +import { DefendInsightType } from '@kbn/elastic-assistant-common'; +import { elasticsearchServiceMock } from '@kbn/core-elasticsearch-server-mocks'; import { kibanaPackageJson } from '@kbn/repo-info'; +import { loggerMock } from '@kbn/logging-mocks'; + +import type { + SearchParams, + SecurityWorkflowInsight, +} from '../../../../common/endpoint/types/workflow_insights'; +import { + Category, + SourceType, + TargetType, + ActionType, +} from '../../../../common/endpoint/types/workflow_insights'; import { createDatastream, createPipeline } from './helpers'; import { securityWorkflowInsightsService } from '.'; import { DATA_STREAM_NAME } from './constants'; -jest.mock('./helpers', () => ({ - createDatastream: jest.fn(), - createPipeline: jest.fn(), -})); +jest.mock('./helpers', () => { + const original = jest.requireActual('./helpers'); + return { + ...original, + createDatastream: jest.fn(), + createPipeline: jest.fn(), + }; +}); + +function getDefaultInsight(overrides?: Partial): SecurityWorkflowInsight { + const defaultInsight = { + '@timestamp': moment(), + message: 'This is a test message', + category: Category.Endpoint, + type: DefendInsightType.Enum.incompatible_antivirus, + source: { + type: SourceType.LlmConnector, + id: 'openai-connector-id', + data_range_start: moment(), + data_range_end: moment(), + }, + target: { + type: TargetType.Endpoint, + ids: ['endpoint-1', 'endpoint-2'], + }, + action: { + type: ActionType.Refreshed, + timestamp: moment(), + }, + value: 'unique-key', + remediation: { + exception_list_items: [ + { + list_id: 'example-list-id', + name: 'Example List Name', + description: 'Example description', + entries: [ + { + field: 'example-field', + operator: 'included', + type: 'match', + value: 'example-value', + }, + ], + tags: ['example-tag'], + os_types: ['windows', 'linux'], + }, + ], + }, + metadata: { + notes: { + key1: 'value1', + key2: 'value2', + }, + message_variables: ['variable1', 'variable2'], + }, + }; + return merge(defaultInsight, overrides); +} describe('SecurityWorkflowInsightsService', () => { let logger: Logger; @@ -126,38 +196,127 @@ describe('SecurityWorkflowInsightsService', () => { }); describe('create', () => { - it('should wait for initialization', async () => { + it('should index the doc correctly', async () => { const isInitializedSpy = jest .spyOn(securityWorkflowInsightsService, 'isInitialized', 'get') .mockResolvedValueOnce([undefined, undefined]); - await securityWorkflowInsightsService.create(); + await securityWorkflowInsightsService.start({ esClient }); + const insight = getDefaultInsight(); + await securityWorkflowInsightsService.create(insight); + // ensure it waits for initialization first expect(isInitializedSpy).toHaveBeenCalledTimes(1); + // indexes the doc + expect(esClient.index).toHaveBeenCalledTimes(1); + expect(esClient.index).toHaveBeenCalledWith({ + index: DATA_STREAM_NAME, + body: insight, + }); }); }); describe('update', () => { - it('should wait for initialization', async () => { + it('should update the doc correctly', async () => { const isInitializedSpy = jest .spyOn(securityWorkflowInsightsService, 'isInitialized', 'get') .mockResolvedValueOnce([undefined, undefined]); - await securityWorkflowInsightsService.update(); + await securityWorkflowInsightsService.start({ esClient }); + const insightId = 'some-insight-id'; + const insight = getDefaultInsight(); + await securityWorkflowInsightsService.update(insightId, insight); + // ensure it waits for initialization first expect(isInitializedSpy).toHaveBeenCalledTimes(1); + // updates the doc + expect(esClient.update).toHaveBeenCalledTimes(1); + expect(esClient.update).toHaveBeenCalledWith({ + index: DATA_STREAM_NAME, + id: insightId, + body: { doc: insight }, + }); }); }); describe('fetch', () => { - it('should wait for initialization', async () => { + it('should fetch the docs with the correct params', async () => { const isInitializedSpy = jest .spyOn(securityWorkflowInsightsService, 'isInitialized', 'get') .mockResolvedValueOnce([undefined, undefined]); - await securityWorkflowInsightsService.fetch(); + await securityWorkflowInsightsService.start({ esClient }); + const searchParams: SearchParams = { + size: 50, + from: 50, + ids: ['id1', 'id2'], + categories: [Category.Endpoint], + types: [DefendInsightType.Enum.incompatible_antivirus], + sourceTypes: [SourceType.LlmConnector], + sourceIds: ['source-id1', 'source-id2'], + targetTypes: [TargetType.Endpoint], + targetIds: ['target-id1', 'target-id2'], + actionTypes: [ActionType.Refreshed, ActionType.Remediated], + }; + await securityWorkflowInsightsService.fetch(searchParams); + // ensure it waits for initialization first expect(isInitializedSpy).toHaveBeenCalledTimes(1); + // fetches the doc + expect(esClient.search).toHaveBeenCalledTimes(1); + expect(esClient.search).toHaveBeenCalledWith({ + index: DATA_STREAM_NAME, + body: { + query: { + bool: { + must: [ + { + terms: { + _id: ['id1', 'id2'], + }, + }, + { + terms: { + categories: ['endpoint'], + }, + }, + { + terms: { + types: ['incompatible_antivirus'], + }, + }, + { + terms: { + 'source.type': ['llm-connector'], + }, + }, + { + terms: { + 'source.id': ['source-id1', 'source-id2'], + }, + }, + { + terms: { + 'target.type': ['endpoint'], + }, + }, + { + terms: { + 'target.id': ['target-id1', 'target-id2'], + }, + }, + { + terms: { + 'action.type': ['refreshed', 'remediated'], + }, + }, + ], + }, + }, + size: searchParams.size, + from: searchParams.from, + }, + }); }); }); }); diff --git a/x-pack/plugins/security_solution/server/endpoint/services/workflow_insights/index.ts b/x-pack/plugins/security_solution/server/endpoint/services/workflow_insights/index.ts index 005be1b0398e1..0aa495dac0931 100644 --- a/x-pack/plugins/security_solution/server/endpoint/services/workflow_insights/index.ts +++ b/x-pack/plugins/security_solution/server/endpoint/services/workflow_insights/index.ts @@ -7,14 +7,25 @@ import { ReplaySubject, firstValueFrom, combineLatest } from 'rxjs'; +import type { + SearchHit, + UpdateResponse, + WriteResponseBase, +} from '@elastic/elasticsearch/lib/api/types'; import type { ElasticsearchClient, Logger } from '@kbn/core/server'; - import type { DataStreamSpacesAdapter } from '@kbn/data-stream-adapter'; +import type { + SearchParams, + SecurityWorkflowInsight, +} from '../../../../common/endpoint/types/workflow_insights'; + import { SecurityWorkflowInsightsFailedInitialized } from './errors'; -import { createDatastream, createPipeline } from './helpers'; +import { buildEsQueryParams, createDatastream, createPipeline } from './helpers'; import { DATA_STREAM_NAME } from './constants'; +const DEFAULT_PAGE_SIZE = 10; + interface SetupInterface { kibanaVersion: string; logger: Logger; @@ -30,7 +41,7 @@ class SecurityWorkflowInsightsService { private start$ = new ReplaySubject(1); private stop$ = new ReplaySubject(1); private ds: DataStreamSpacesAdapter | undefined; - // private _esClient: ElasticsearchClient | undefined; + private _esClient: ElasticsearchClient | undefined; private _logger: Logger | undefined; private _isInitialized: Promise<[void, void]> = firstValueFrom( combineLatest<[void, void]>([this.setup$, this.start$]) @@ -64,7 +75,7 @@ class SecurityWorkflowInsightsService { return; } - // this._esClient = esClient; + this._esClient = esClient; await firstValueFrom(this.setup$); try { @@ -97,26 +108,62 @@ class SecurityWorkflowInsightsService { this.stop$.complete(); } - public async create() { + public async create(insight: SecurityWorkflowInsight): Promise { await this.isInitialized; + + const response = await this.esClient.index({ + index: DATA_STREAM_NAME, + body: insight, + }); + + return response; } - public async update() { + public async update( + id: string, + insight: Partial + ): Promise { await this.isInitialized; + + const response = await this.esClient.update({ + index: DATA_STREAM_NAME, + id, + body: { doc: insight }, + }); + + return response; } - public async fetch() { + public async fetch(params?: SearchParams): Promise>> { await this.isInitialized; + + const size = params?.size ?? DEFAULT_PAGE_SIZE; + const from = params?.from ?? 0; + + const termFilters = params ? buildEsQueryParams(params) : []; + const response = await this.esClient.search({ + index: DATA_STREAM_NAME, + body: { + query: { + bool: { + must: termFilters, + }, + }, + size, + from, + }, + }); + + return response?.hits?.hits ?? []; } - // to be used in create/update/fetch above - // private get esClient(): ElasticsearchClient { - // if (!this._esClient) { - // throw new SecurityWorkflowInsightsFailedInitialized('no elasticsearch client found'); - // } + private get esClient(): ElasticsearchClient { + if (!this._esClient) { + throw new SecurityWorkflowInsightsFailedInitialized('no elasticsearch client found'); + } - // return this._esClient; - // } + return this._esClient; + } private get logger(): Logger { if (!this._logger) { diff --git a/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.ts b/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.ts index 54f1ce8cc7e01..4987250644cb4 100644 --- a/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.ts +++ b/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.ts @@ -7,7 +7,7 @@ import type { Logger, ElasticsearchClient, SavedObjectsClientContract } from '@kbn/core/server'; import type { ExceptionListClient } from '@kbn/lists-plugin/server'; -import type { PluginStartContract as AlertsStartContract } from '@kbn/alerting-plugin/server'; +import type { AlertingServerStart } from '@kbn/alerting-plugin/server'; import type { PostPackagePolicyCreateCallback, PostPackagePolicyPostDeleteCallback, @@ -119,7 +119,7 @@ export const getPackagePolicyCreateCallback = ( logger: Logger, manifestManager: ManifestManager, securitySolutionRequestContextFactory: IRequestContextFactory, - alerts: AlertsStartContract, + alerts: AlertingServerStart, licenseService: LicenseService, exceptionsClient: ExceptionListClient | undefined, cloud: CloudSetup, diff --git a/x-pack/plugins/security_solution/server/fleet_integration/handlers/install_prepackaged_rules.ts b/x-pack/plugins/security_solution/server/fleet_integration/handlers/install_prepackaged_rules.ts index d4a60be85d3ea..891face9f2879 100644 --- a/x-pack/plugins/security_solution/server/fleet_integration/handlers/install_prepackaged_rules.ts +++ b/x-pack/plugins/security_solution/server/fleet_integration/handlers/install_prepackaged_rules.ts @@ -7,7 +7,7 @@ import type { KibanaRequest, Logger } from '@kbn/core/server'; import type { ExceptionListClient } from '@kbn/lists-plugin/server'; -import type { PluginStartContract as AlertsStartContract } from '@kbn/alerting-plugin/server'; +import type { AlertingServerStart } from '@kbn/alerting-plugin/server'; import { createDetectionIndex } from '../../lib/detection_engine/routes/index/create_index_route'; import { createPrepackagedRules } from '../../lib/detection_engine/prebuilt_rules'; import type { SecuritySolutionApiRequestHandlerContext } from '../../types'; @@ -16,7 +16,7 @@ export interface InstallPrepackagedRulesProps { logger: Logger; context: SecuritySolutionApiRequestHandlerContext; request: KibanaRequest; - alerts: AlertsStartContract; + alerts: AlertingServerStart; exceptionsClient: ExceptionListClient; } @@ -45,11 +45,8 @@ export const installPrepackagedRules = async ({ try { // this checks to make sure index exists first, safe to try in case of failure above // may be able to recover from minor errors - await createPrepackagedRules( - context, - alerts.getRulesClientWithRequest(request), - exceptionsClient - ); + const rulesClient = await alerts.getRulesClientWithRequest(request); + await createPrepackagedRules(context, rulesClient, exceptionsClient); } catch (err) { logger.error( `Unable to create detection rules automatically (${err.statusCode}): ${err.message}` diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/get_prebuilt_rules_and_timelines_status/get_prebuilt_rules_and_timelines_status_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/get_prebuilt_rules_and_timelines_status/get_prebuilt_rules_and_timelines_status_route.ts index dc9c15ac5b5f7..718c16387281a 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/get_prebuilt_rules_and_timelines_status/get_prebuilt_rules_and_timelines_status_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/get_prebuilt_rules_and_timelines_status/get_prebuilt_rules_and_timelines_status_route.ts @@ -45,7 +45,7 @@ export const getPrebuiltRulesAndTimelinesStatusRoute = (router: SecuritySolution const siemResponse = buildSiemResponse(response); const ctx = await context.resolve(['core', 'alerting']); const savedObjectsClient = ctx.core.savedObjects.client; - const rulesClient = ctx.alerting.getRulesClient(); + const rulesClient = await ctx.alerting.getRulesClient(); const ruleAssetsClient = createPrebuiltRuleAssetsClient(savedObjectsClient); try { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/get_prebuilt_rules_status/get_prebuilt_rules_status_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/get_prebuilt_rules_status/get_prebuilt_rules_status_route.ts index 0561c826e0c78..52e2c552c74fa 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/get_prebuilt_rules_status/get_prebuilt_rules_status_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/get_prebuilt_rules_status/get_prebuilt_rules_status_route.ts @@ -37,7 +37,7 @@ export const getPrebuiltRulesStatusRoute = (router: SecuritySolutionPluginRouter try { const ctx = await context.resolve(['core', 'alerting']); const soClient = ctx.core.savedObjects.client; - const rulesClient = ctx.alerting.getRulesClient(); + const rulesClient = await ctx.alerting.getRulesClient(); const ruleAssetsClient = createPrebuiltRuleAssetsClient(soClient); const ruleObjectsClient = createPrebuiltRuleObjectsClient(rulesClient); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/install_prebuilt_rules_and_timelines/install_prebuilt_rules_and_timelines_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/install_prebuilt_rules_and_timelines/install_prebuilt_rules_and_timelines_route.ts index 8740d27fce817..f24454726c615 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/install_prebuilt_rules_and_timelines/install_prebuilt_rules_and_timelines_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/install_prebuilt_rules_and_timelines/install_prebuilt_rules_and_timelines_route.ts @@ -53,7 +53,7 @@ export const installPrebuiltRulesAndTimelinesRoute = (router: SecuritySolutionPl const siemResponse = buildSiemResponse(response); try { - const rulesClient = (await context.alerting).getRulesClient(); + const rulesClient = await (await context.alerting).getRulesClient(); const validated = await createPrepackagedRules( await context.securitySolution, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/perform_rule_installation/perform_rule_installation_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/perform_rule_installation/perform_rule_installation_route.ts index 8b4d38bd2f4a4..a2abc00b43a39 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/perform_rule_installation/perform_rule_installation_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/perform_rule_installation/perform_rule_installation_route.ts @@ -61,7 +61,7 @@ export const performRuleInstallationRoute = (router: SecuritySolutionPluginRoute const ctx = await context.resolve(['core', 'alerting', 'securitySolution']); const config = ctx.securitySolution.getConfig(); const soClient = ctx.core.savedObjects.client; - const rulesClient = ctx.alerting.getRulesClient(); + const rulesClient = await ctx.alerting.getRulesClient(); const detectionRulesClient = ctx.securitySolution.getDetectionRulesClient(); const ruleAssetsClient = createPrebuiltRuleAssetsClient(soClient); const ruleObjectsClient = createPrebuiltRuleObjectsClient(rulesClient); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/perform_rule_upgrade/perform_rule_upgrade_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/perform_rule_upgrade/perform_rule_upgrade_route.ts index db5f7a186d303..cb0baca5c522e 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/perform_rule_upgrade/perform_rule_upgrade_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/perform_rule_upgrade/perform_rule_upgrade_route.ts @@ -61,7 +61,7 @@ export const performRuleUpgradeRoute = ( try { const ctx = await context.resolve(['core', 'alerting', 'securitySolution']); const soClient = ctx.core.savedObjects.client; - const rulesClient = ctx.alerting.getRulesClient(); + const rulesClient = await ctx.alerting.getRulesClient(); const detectionRulesClient = ctx.securitySolution.getDetectionRulesClient(); const ruleAssetsClient = createPrebuiltRuleAssetsClient(soClient); const ruleObjectsClient = createPrebuiltRuleObjectsClient(rulesClient); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/review_rule_installation/review_rule_installation_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/review_rule_installation/review_rule_installation_route.ts index c1c45532f61bb..78d75603dd23b 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/review_rule_installation/review_rule_installation_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/review_rule_installation/review_rule_installation_route.ts @@ -48,7 +48,7 @@ export const reviewRuleInstallationRoute = (router: SecuritySolutionPluginRouter try { const ctx = await context.resolve(['core', 'alerting']); const soClient = ctx.core.savedObjects.client; - const rulesClient = ctx.alerting.getRulesClient(); + const rulesClient = await ctx.alerting.getRulesClient(); const ruleAssetsClient = createPrebuiltRuleAssetsClient(soClient); const ruleObjectsClient = createPrebuiltRuleObjectsClient(rulesClient); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/review_rule_upgrade/review_rule_upgrade_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/review_rule_upgrade/review_rule_upgrade_route.ts index 3da62bd9bb21d..0f8dee1a4e2ff 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/review_rule_upgrade/review_rule_upgrade_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/review_rule_upgrade/review_rule_upgrade_route.ts @@ -57,7 +57,7 @@ export const reviewRuleUpgradeRoute = (router: SecuritySolutionPluginRouter) => try { const ctx = await context.resolve(['core', 'alerting']); const soClient = ctx.core.savedObjects.client; - const rulesClient = ctx.alerting.getRulesClient(); + const rulesClient = await ctx.alerting.getRulesClient(); const ruleAssetsClient = createPrebuiltRuleAssetsClient(soClient); const ruleObjectsClient = createPrebuiltRuleObjectsClient(rulesClient); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/__mocks__/request_context.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/__mocks__/request_context.ts index cba989890438e..3c99cebbbe8fb 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/__mocks__/request_context.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/__mocks__/request_context.ts @@ -103,7 +103,7 @@ const createRequestContextMock = ( getActionsClient: jest.fn(() => clients.actionsClient), } as unknown as jest.Mocked, alerting: { - getRulesClient: jest.fn(() => clients.rulesClient), + getRulesClient: jest.fn().mockResolvedValue(clients.rulesClient), } as unknown as jest.Mocked, licensing: clients.licensing, lists: { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/api/create_legacy_notification/route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/api/create_legacy_notification/route.ts index d5623df8db91c..2a06549f3f359 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/api/create_legacy_notification/route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/api/create_legacy_notification/route.ts @@ -64,7 +64,7 @@ export const legacyCreateLegacyNotificationRoute = ( }, }, async (context, request, response) => { - const rulesClient = (await context.alerting).getRulesClient(); + const rulesClient = await (await context.alerting).getRulesClient(); const savedObjectsClient = (await context.core).savedObjects.client; const { alert_id: ruleAlertId } = request.query; const { actions, interval, name } = request.body; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_exceptions/api/create_rule_exceptions/route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_exceptions/api/create_rule_exceptions/route.ts index 1d8038b1052c3..b178d912ccf27 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_exceptions/api/create_rule_exceptions/route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_exceptions/api/create_rule_exceptions/route.ts @@ -63,7 +63,7 @@ export const createRuleExceptionsRoute = (router: SecuritySolutionPluginRouter) 'licensing', 'lists', ]); - const rulesClient = ctx.alerting.getRulesClient(); + const rulesClient = await ctx.alerting.getRulesClient(); const listsClient = ctx.securitySolution.getExceptionListClient(); const detectionRulesClient = ctx.securitySolution.getDetectionRulesClient(); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_exceptions/api/find_exception_references/route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_exceptions/api/find_exception_references/route.ts index 3680a70525fd4..db890c7104e58 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_exceptions/api/find_exception_references/route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_exceptions/api/find_exception_references/route.ts @@ -54,7 +54,7 @@ export const findRuleExceptionReferencesRoute = (router: SecuritySolutionPluginR const { ids, namespace_types: namespaceTypes, list_ids: listIds } = request.query; const ctx = await context.resolve(['core', 'securitySolution', 'alerting']); - const rulesClient = ctx.alerting.getRulesClient(); + const rulesClient = await ctx.alerting.getRulesClient(); const listsClient = ctx.securitySolution.getExceptionListClient(); if ( diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_actions/route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_actions/route.ts index e599ff4a936ef..e0b33b35e2e1f 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_actions/route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_actions/route.ts @@ -131,7 +131,7 @@ export const performBulkActionRoute = ( 'actions', ]); - const rulesClient = ctx.alerting.getRulesClient(); + const rulesClient = await ctx.alerting.getRulesClient(); const exceptionsClient = ctx.lists?.getExceptionListClient(); const savedObjectsClient = ctx.core.savedObjects.client; const actionsClient = ctx.actions.getActionsClient(); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_create_rules/route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_create_rules/route.ts index 225782ef01942..8d35de9547159 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_create_rules/route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_create_rules/route.ts @@ -66,7 +66,7 @@ export const bulkCreateRulesRoute = (router: SecuritySolutionPluginRouter, logge try { const ctx = await context.resolve(['core', 'securitySolution', 'licensing', 'alerting']); - const rulesClient = ctx.alerting.getRulesClient(); + const rulesClient = await ctx.alerting.getRulesClient(); const detectionRulesClient = ctx.securitySolution.getDetectionRulesClient(); const ruleDefinitions = request.body; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_delete_rules/route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_delete_rules/route.ts index f24f563e1a99d..c38bd58bde5a4 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_delete_rules/route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_delete_rules/route.ts @@ -61,7 +61,7 @@ export const bulkDeleteRulesRoute = (router: SecuritySolutionPluginRouter, logge try { const ctx = await context.resolve(['core', 'securitySolution', 'alerting']); - const rulesClient = ctx.alerting.getRulesClient(); + const rulesClient = await ctx.alerting.getRulesClient(); const detectionRulesClient = ctx.securitySolution.getDetectionRulesClient(); const rules = await Promise.all( diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_patch_rules/route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_patch_rules/route.ts index 5bd8adaf86a38..fbbfc2656124d 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_patch_rules/route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_patch_rules/route.ts @@ -60,7 +60,7 @@ export const bulkPatchRulesRoute = (router: SecuritySolutionPluginRouter, logger try { const ctx = await context.resolve(['core', 'securitySolution', 'alerting', 'licensing']); - const rulesClient = ctx.alerting.getRulesClient(); + const rulesClient = await ctx.alerting.getRulesClient(); const detectionRulesClient = ctx.securitySolution.getDetectionRulesClient(); const rules = await Promise.all( diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_update_rules/route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_update_rules/route.ts index d2c985fbc70e6..ad82d5a0edce2 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_update_rules/route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_update_rules/route.ts @@ -64,7 +64,7 @@ export const bulkUpdateRulesRoute = (router: SecuritySolutionPluginRouter, logge try { const ctx = await context.resolve(['core', 'securitySolution', 'alerting', 'licensing']); - const rulesClient = ctx.alerting.getRulesClient(); + const rulesClient = await ctx.alerting.getRulesClient(); const detectionRulesClient = ctx.securitySolution.getDetectionRulesClient(); const rules = await Promise.all( diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/coverage_overview/route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/coverage_overview/route.ts index a959c522c1718..a3c6a07e0b8be 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/coverage_overview/route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/coverage_overview/route.ts @@ -45,7 +45,7 @@ export const getCoverageOverviewRoute = (router: SecuritySolutionPluginRouter) = const responseData = await handleCoverageOverviewRequest({ params: request.body, - deps: { rulesClient: ctx.alerting.getRulesClient() }, + deps: { rulesClient: await ctx.alerting.getRulesClient() }, }); return response.ok({ diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/create_rule/route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/create_rule/route.ts index a5fee66d00148..dbeaed85db055 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/create_rule/route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/create_rule/route.ts @@ -58,7 +58,7 @@ export const createRuleRoute = (router: SecuritySolutionPluginRouter): void => { 'lists', ]); - const rulesClient = ctx.alerting.getRulesClient(); + const rulesClient = await ctx.alerting.getRulesClient(); const detectionRulesClient = ctx.securitySolution.getDetectionRulesClient(); const exceptionsClient = ctx.lists?.getExceptionListClient(); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/delete_rule/route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/delete_rule/route.ts index a5854e9a2caf5..3e5ef8aa8ab7a 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/delete_rule/route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/delete_rule/route.ts @@ -50,7 +50,7 @@ export const deleteRuleRoute = (router: SecuritySolutionPluginRouter) => { const { id, rule_id: ruleId } = request.query; const ctx = await context.resolve(['core', 'securitySolution', 'alerting']); - const rulesClient = ctx.alerting.getRulesClient(); + const rulesClient = await ctx.alerting.getRulesClient(); const detectionRulesClient = ctx.securitySolution.getDetectionRulesClient(); const rule = await readRules({ rulesClient, id, ruleId }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/export_rules/route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/export_rules/route.ts index a37bb29963332..be19da6df831e 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/export_rules/route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/export_rules/route.ts @@ -56,7 +56,7 @@ export const exportRulesRoute = ( }, async (context, request, response) => { const siemResponse = buildSiemResponse(response); - const rulesClient = (await context.alerting).getRulesClient(); + const rulesClient = await (await context.alerting).getRulesClient(); const exceptionsClient = (await context.lists)?.getExceptionListClient(); const actionsClient = (await context.actions)?.getActionsClient(); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/filters/route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/filters/route.ts index 05633892cdddb..6496c6edc2a87 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/filters/route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/filters/route.ts @@ -70,7 +70,7 @@ export const getRuleManagementFilters = (router: SecuritySolutionPluginRouter) = async (context, _, response): Promise> => { const siemResponse = buildSiemResponse(response); const ctx = await context.resolve(['alerting']); - const rulesClient = ctx.alerting.getRulesClient(); + const rulesClient = await ctx.alerting.getRulesClient(); try { const [{ prebuilt: prebuiltRulesCount, custom: customRulesCount }, tags] = diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/find_rules/route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/find_rules/route.ts index 899e568e79630..dbe58e7815ea5 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/find_rules/route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/find_rules/route.ts @@ -51,7 +51,7 @@ export const findRulesRoute = (router: SecuritySolutionPluginRouter, logger: Log try { const { query } = request; const ctx = await context.resolve(['core', 'securitySolution', 'alerting']); - const rulesClient = ctx.alerting.getRulesClient(); + const rulesClient = await ctx.alerting.getRulesClient(); const rules = await findRules({ rulesClient, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/patch_rule/route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/patch_rule/route.ts index fcd388e81d1e7..6971628a780d9 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/patch_rule/route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/patch_rule/route.ts @@ -52,7 +52,7 @@ export const patchRuleRoute = (router: SecuritySolutionPluginRouter) => { } try { const params = request.body; - const rulesClient = (await context.alerting).getRulesClient(); + const rulesClient = await (await context.alerting).getRulesClient(); const detectionRulesClient = (await context.securitySolution).getDetectionRulesClient(); const existingRule = await readRules({ diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/read_rule/route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/read_rule/route.ts index f8826e8aad45b..53b8ca4085209 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/read_rule/route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/read_rule/route.ts @@ -49,7 +49,7 @@ export const readRuleRoute = (router: SecuritySolutionPluginRouter, logger: Logg const { id, rule_id: ruleId } = request.query; try { - const rulesClient = (await context.alerting).getRulesClient(); + const rulesClient = await (await context.alerting).getRulesClient(); // TODO: https://github.com/elastic/kibana/issues/125642 Reuse fetchRuleById const rule = await readRules({ diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/update_rule/route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/update_rule/route.ts index 0bedcb25de528..8a83aae938d6f 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/update_rule/route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/update_rule/route.ts @@ -50,7 +50,7 @@ export const updateRuleRoute = (router: SecuritySolutionPluginRouter) => { } try { const ctx = await context.resolve(['core', 'securitySolution', 'alerting', 'licensing']); - const rulesClient = ctx.alerting.getRulesClient(); + const rulesClient = await ctx.alerting.getRulesClient(); const detectionRulesClient = ctx.securitySolution.getDetectionRulesClient(); checkDefaultRuleExceptionListReferences({ exceptionLists: request.body.exceptions_list }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/tags/read_tags/route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/tags/read_tags/route.ts index d94f695f39179..0332dfe024964 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/tags/read_tags/route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/tags/read_tags/route.ts @@ -32,7 +32,7 @@ export const readTagsRoute = (router: SecuritySolutionPluginRouter) => { async (context, request, response): Promise> => { const siemResponse = buildSiemResponse(response); const ctx = await context.resolve(['alerting']); - const rulesClient = ctx.alerting.getRulesClient(); + const rulesClient = await ctx.alerting.getRulesClient(); try { const tags = await readTags({ diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/bulk_actions/bulk_edit_rules.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/bulk_actions/bulk_edit_rules.ts index bee44a3600f97..b9c97c2412b1a 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/bulk_actions/bulk_edit_rules.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/bulk_actions/bulk_edit_rules.ts @@ -92,14 +92,20 @@ export const bulkEditRules = async ({ params: modifiedParams, }; const ruleResponse = convertAlertingRuleToRuleResponse(updatedRule); + let isCustomized = false; + if (ruleResponse.immutable === true) { + isCustomized = calculateIsCustomized({ + baseRule: baseVersionsMap.get(ruleResponse.rule_id), + nextRule: ruleResponse, + isRuleCustomizationEnabled: experimentalFeatures.prebuiltRulesCustomizationEnabled, + }); + } + const ruleSource = ruleResponse.immutable === true ? { type: 'external' as const, - isCustomized: calculateIsCustomized( - baseVersionsMap.get(ruleResponse.rule_id), - ruleResponse - ), + isCustomized, } : { type: 'internal' as const, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client.create_custom_rule.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client.create_custom_rule.test.ts index af3f85f3e1345..b07f95f74d2f9 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client.create_custom_rule.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client.create_custom_rule.test.ts @@ -51,6 +51,7 @@ describe('DetectionRulesClient.createCustomRule', () => { rulesClient, mlAuthz, savedObjectsClient, + isRuleCustomizationEnabled: true, }); }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client.create_prebuilt_rule.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client.create_prebuilt_rule.test.ts index 4caeb4bd9b940..6e1e75855b6a0 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client.create_prebuilt_rule.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client.create_prebuilt_rule.test.ts @@ -44,6 +44,7 @@ describe('DetectionRulesClient.createPrebuiltRule', () => { rulesClient, mlAuthz, savedObjectsClient, + isRuleCustomizationEnabled: true, }); }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client.delete_rule.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client.delete_rule.test.ts index ea5d1453753c3..a4afe5abadb6b 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client.delete_rule.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client.delete_rule.test.ts @@ -30,6 +30,7 @@ describe('DetectionRulesClient.deleteRule', () => { rulesClient, mlAuthz, savedObjectsClient, + isRuleCustomizationEnabled: true, }); }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client.import_rule.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client.import_rule.test.ts index 4300b17b3be80..5f8bfb5577740 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client.import_rule.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client.import_rule.test.ts @@ -51,6 +51,7 @@ describe('DetectionRulesClient.importRule', () => { rulesClient, mlAuthz, savedObjectsClient, + isRuleCustomizationEnabled: true, }); }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client.import_rules.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client.import_rules.test.ts index 58b1385dda09c..3dfd859fb0b7b 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client.import_rules.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client.import_rules.test.ts @@ -32,6 +32,7 @@ describe('detectionRulesClient.importRules', () => { rulesClient: rulesClientMock.create(), mlAuthz: buildMlAuthz(), savedObjectsClient: savedObjectsClientMock.create(), + isRuleCustomizationEnabled: true, }); (checkRuleExceptionReferences as jest.Mock).mockReturnValue([[], []]); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client.patch_rule.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client.patch_rule.test.ts index 448df6b581a3b..18fe3c54da7e0 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client.patch_rule.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client.patch_rule.test.ts @@ -50,6 +50,7 @@ describe('DetectionRulesClient.patchRule', () => { rulesClient, mlAuthz, savedObjectsClient, + isRuleCustomizationEnabled: true, }); }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client.ts index fb6f5c4a03c1f..57c8f12c09aa9 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client.ts @@ -38,6 +38,7 @@ interface DetectionRulesClientParams { rulesClient: RulesClient; savedObjectsClient: SavedObjectsClientContract; mlAuthz: MlAuthz; + isRuleCustomizationEnabled: boolean; } export const createDetectionRulesClient = ({ @@ -45,6 +46,7 @@ export const createDetectionRulesClient = ({ rulesClient, mlAuthz, savedObjectsClient, + isRuleCustomizationEnabled, }: DetectionRulesClientParams): IDetectionRulesClient => { const prebuiltRuleAssetClient = createPrebuiltRuleAssetsClient(savedObjectsClient); @@ -89,6 +91,7 @@ export const createDetectionRulesClient = ({ prebuiltRuleAssetClient, mlAuthz, ruleUpdate, + isRuleCustomizationEnabled, }); }); }, @@ -101,6 +104,7 @@ export const createDetectionRulesClient = ({ prebuiltRuleAssetClient, mlAuthz, rulePatch, + isRuleCustomizationEnabled, }); }); }, @@ -119,6 +123,7 @@ export const createDetectionRulesClient = ({ ruleAsset, mlAuthz, prebuiltRuleAssetClient, + isRuleCustomizationEnabled, }); }); }, @@ -131,6 +136,7 @@ export const createDetectionRulesClient = ({ importRulePayload: args, mlAuthz, prebuiltRuleAssetClient, + isRuleCustomizationEnabled, }); }); }, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client.update_rule.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client.update_rule.test.ts index cbd0fb1fe3680..64c01ab395529 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client.update_rule.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client.update_rule.test.ts @@ -50,6 +50,7 @@ describe('DetectionRulesClient.updateRule', () => { rulesClient, mlAuthz, savedObjectsClient, + isRuleCustomizationEnabled: true, }); }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client.upgrade_prebuilt_rule.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client.upgrade_prebuilt_rule.test.ts index acdb7b9653930..ed186abe5a7c3 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client.upgrade_prebuilt_rule.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client.upgrade_prebuilt_rule.test.ts @@ -48,6 +48,7 @@ describe('DetectionRulesClient.upgradePrebuiltRule', () => { rulesClient, mlAuthz, savedObjectsClient, + isRuleCustomizationEnabled: true, }); }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/mergers/apply_rule_patch.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/mergers/apply_rule_patch.test.ts index abf90c3f4dfc4..0d780c07aac19 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/mergers/apply_rule_patch.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/mergers/apply_rule_patch.test.ts @@ -37,6 +37,7 @@ describe('applyRulePatch', () => { rulePatch, existingRule, prebuiltRuleAssetClient, + isRuleCustomizationEnabled: true, }); expect(patchedRule).toEqual( expect.objectContaining({ @@ -65,6 +66,7 @@ describe('applyRulePatch', () => { rulePatch, existingRule, prebuiltRuleAssetClient, + isRuleCustomizationEnabled: true, }); expect(patchedRule).toEqual( expect.objectContaining({ @@ -94,6 +96,7 @@ describe('applyRulePatch', () => { rulePatch, existingRule, prebuiltRuleAssetClient, + isRuleCustomizationEnabled: true, }) ).rejects.toThrowError( 'event_category_override: Expected string, received number, tiebreaker_field: Expected string, received number, timestamp_field: Expected string, received number' @@ -119,6 +122,7 @@ describe('applyRulePatch', () => { rulePatch, existingRule, prebuiltRuleAssetClient, + isRuleCustomizationEnabled: true, }) ).rejects.toThrowError('alert_suppression.group_by: Expected array, received string'); }); @@ -134,6 +138,7 @@ describe('applyRulePatch', () => { rulePatch, existingRule, prebuiltRuleAssetClient, + isRuleCustomizationEnabled: true, }); expect(patchedRule).toEqual( expect.objectContaining({ @@ -154,6 +159,7 @@ describe('applyRulePatch', () => { rulePatch, existingRule, prebuiltRuleAssetClient, + isRuleCustomizationEnabled: true, }) ).rejects.toThrowError( 'threat_query: Expected string, received number, threat_indicator_path: Expected string, received number' @@ -170,6 +176,7 @@ describe('applyRulePatch', () => { rulePatch, existingRule, prebuiltRuleAssetClient, + isRuleCustomizationEnabled: true, }); expect(patchedRule).toEqual( expect.objectContaining({ @@ -190,6 +197,7 @@ describe('applyRulePatch', () => { rulePatch, existingRule, prebuiltRuleAssetClient, + isRuleCustomizationEnabled: true, }) ).rejects.toThrowError( "index.0: Expected string, received number, language: Invalid enum value. Expected 'kuery' | 'lucene', received 'non-language'" @@ -206,6 +214,7 @@ describe('applyRulePatch', () => { rulePatch, existingRule, prebuiltRuleAssetClient, + isRuleCustomizationEnabled: true, }); expect(patchedRule).toEqual( expect.objectContaining({ @@ -226,6 +235,7 @@ describe('applyRulePatch', () => { rulePatch, existingRule, prebuiltRuleAssetClient, + isRuleCustomizationEnabled: true, }) ).rejects.toThrowError( "index.0: Expected string, received number, language: Invalid enum value. Expected 'kuery' | 'lucene', received 'non-language'" @@ -244,6 +254,7 @@ describe('applyRulePatch', () => { rulePatch, existingRule, prebuiltRuleAssetClient, + isRuleCustomizationEnabled: true, }); expect(patchedRule).toEqual( expect.objectContaining({ @@ -268,6 +279,7 @@ describe('applyRulePatch', () => { rulePatch, existingRule, prebuiltRuleAssetClient, + isRuleCustomizationEnabled: true, }) ).rejects.toThrowError('threshold.value: Expected number, received string'); }); @@ -285,6 +297,7 @@ describe('applyRulePatch', () => { rulePatch, existingRule, prebuiltRuleAssetClient, + isRuleCustomizationEnabled: true, }); expect(patchedRule).toEqual( expect.objectContaining({ @@ -308,6 +321,7 @@ describe('applyRulePatch', () => { rulePatch, existingRule, prebuiltRuleAssetClient, + isRuleCustomizationEnabled: true, }); expect(patchedRule).toEqual( expect.objectContaining({ @@ -330,6 +344,7 @@ describe('applyRulePatch', () => { rulePatch, existingRule, prebuiltRuleAssetClient, + isRuleCustomizationEnabled: true, }); expect(patchedRule).toEqual( expect.objectContaining({ @@ -354,6 +369,7 @@ describe('applyRulePatch', () => { rulePatch, existingRule, prebuiltRuleAssetClient, + isRuleCustomizationEnabled: true, }); expect(patchedRule).toEqual( expect.objectContaining({ @@ -376,6 +392,7 @@ describe('applyRulePatch', () => { rulePatch, existingRule, prebuiltRuleAssetClient, + isRuleCustomizationEnabled: true, }); expect(patchedRule).toEqual( expect.objectContaining({ @@ -394,6 +411,7 @@ describe('applyRulePatch', () => { rulePatch, existingRule, prebuiltRuleAssetClient, + isRuleCustomizationEnabled: true, }) ).rejects.toThrowError('anomaly_threshold: Expected number, received string'); }); @@ -410,6 +428,7 @@ describe('applyRulePatch', () => { rulePatch, existingRule, prebuiltRuleAssetClient, + isRuleCustomizationEnabled: true, }); expect(patchedRule).toEqual( @@ -432,6 +451,7 @@ describe('applyRulePatch', () => { rulePatch, existingRule, prebuiltRuleAssetClient, + isRuleCustomizationEnabled: true, }); expect(patchedRule).toEqual( expect.objectContaining({ @@ -450,6 +470,7 @@ describe('applyRulePatch', () => { rulePatch, existingRule, prebuiltRuleAssetClient, + isRuleCustomizationEnabled: true, }) ).rejects.toThrowError('new_terms_fields: Expected array, received string'); }); @@ -472,6 +493,7 @@ describe('applyRulePatch', () => { rulePatch, existingRule, prebuiltRuleAssetClient, + isRuleCustomizationEnabled: true, }); expect(patchedRule).toEqual( expect.objectContaining({ diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/mergers/apply_rule_patch.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/mergers/apply_rule_patch.ts index 9f5b167322491..aaaab474c2fbe 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/mergers/apply_rule_patch.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/mergers/apply_rule_patch.ts @@ -51,6 +51,7 @@ interface ApplyRulePatchProps { prebuiltRuleAssetClient: IPrebuiltRuleAssetsClient; existingRule: RuleResponse; rulePatch: PatchRuleRequestBody; + isRuleCustomizationEnabled: boolean; } // eslint-disable-next-line complexity @@ -58,6 +59,7 @@ export const applyRulePatch = async ({ rulePatch, existingRule, prebuiltRuleAssetClient, + isRuleCustomizationEnabled, }: ApplyRulePatchProps): Promise => { const typeSpecificParams = patchTypeSpecificParams(rulePatch, existingRule); @@ -122,6 +124,7 @@ export const applyRulePatch = async ({ nextRule.rule_source = await calculateRuleSource({ rule: nextRule, prebuiltRuleAssetClient, + isRuleCustomizationEnabled, }); return nextRule; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/mergers/apply_rule_update.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/mergers/apply_rule_update.ts index b911e66a1fc45..850924d3cd04d 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/mergers/apply_rule_update.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/mergers/apply_rule_update.ts @@ -17,12 +17,14 @@ interface ApplyRuleUpdateProps { prebuiltRuleAssetClient: IPrebuiltRuleAssetsClient; existingRule: RuleResponse; ruleUpdate: RuleUpdateProps; + isRuleCustomizationEnabled: boolean; } export const applyRuleUpdate = async ({ prebuiltRuleAssetClient, existingRule, ruleUpdate, + isRuleCustomizationEnabled, }: ApplyRuleUpdateProps): Promise => { const nextRule: RuleResponse = { ...applyRuleDefaults(ruleUpdate), @@ -46,6 +48,7 @@ export const applyRuleUpdate = async ({ nextRule.rule_source = await calculateRuleSource({ rule: nextRule, prebuiltRuleAssetClient, + isRuleCustomizationEnabled, }); return nextRule; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/mergers/rule_source/calculate_is_customized.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/mergers/rule_source/calculate_is_customized.ts index 92c7d941dd7f1..a94506486cc53 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/mergers/rule_source/calculate_is_customized.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/mergers/rule_source/calculate_is_customized.ts @@ -12,10 +12,22 @@ import { calculateRuleFieldsDiff } from '../../../../../prebuilt_rules/logic/dif import { convertRuleToDiffable } from '../../../../../../../../common/detection_engine/prebuilt_rules/diff/convert_rule_to_diffable'; import { convertPrebuiltRuleAssetToRuleResponse } from '../../converters/convert_prebuilt_rule_asset_to_rule_response'; -export function calculateIsCustomized( - baseRule: PrebuiltRuleAsset | undefined, - nextRule: RuleResponse -) { +interface CalculateIsCustomizedArgs { + baseRule: PrebuiltRuleAsset | undefined; + nextRule: RuleResponse; + isRuleCustomizationEnabled: boolean; +} + +export function calculateIsCustomized({ + baseRule, + nextRule, + isRuleCustomizationEnabled, +}: CalculateIsCustomizedArgs) { + if (!isRuleCustomizationEnabled) { + // We don't want to accidentally mark rules as customized when customization is disabled. + return false; + } + if (baseRule == null) { // If the base version is missing, we consider the rule to be customized return true; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/mergers/rule_source/calculate_rule_source.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/mergers/rule_source/calculate_rule_source.test.ts index e44c69d2705d5..d0b9f722458a1 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/mergers/rule_source/calculate_rule_source.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/mergers/rule_source/calculate_rule_source.test.ts @@ -43,6 +43,7 @@ describe('calculateRuleSource', () => { const result = await calculateRuleSource({ prebuiltRuleAssetClient, rule, + isRuleCustomizationEnabled: true, }); expect(result).toEqual({ type: 'internal', @@ -59,6 +60,7 @@ describe('calculateRuleSource', () => { const result = await calculateRuleSource({ prebuiltRuleAssetClient, rule, + isRuleCustomizationEnabled: true, }); expect(result).toEqual( expect.objectContaining({ @@ -79,6 +81,7 @@ describe('calculateRuleSource', () => { const result = await calculateRuleSource({ prebuiltRuleAssetClient, rule, + isRuleCustomizationEnabled: true, }); expect(result).toEqual( expect.objectContaining({ @@ -101,6 +104,28 @@ describe('calculateRuleSource', () => { const result = await calculateRuleSource({ prebuiltRuleAssetClient, rule, + isRuleCustomizationEnabled: true, + }); + expect(result).toEqual( + expect.objectContaining({ + type: 'external', + is_customized: false, + }) + ); + }); + + it('returns is_customized false when the rule is customized but customization is disabled', async () => { + const rule = getSampleRule(); + rule.immutable = true; + rule.name = 'Updated name'; + + const baseRule = getSampleRuleAsset(); + prebuiltRuleAssetClient.fetchAssetsByVersion.mockResolvedValueOnce([baseRule]); + + const result = await calculateRuleSource({ + prebuiltRuleAssetClient, + rule, + isRuleCustomizationEnabled: false, }); expect(result).toEqual( expect.objectContaining({ diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/mergers/rule_source/calculate_rule_source.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/mergers/rule_source/calculate_rule_source.ts index 742cd20544a60..6c3d2419159a6 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/mergers/rule_source/calculate_rule_source.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/mergers/rule_source/calculate_rule_source.ts @@ -16,11 +16,13 @@ import { calculateIsCustomized } from './calculate_is_customized'; interface CalculateRuleSourceProps { prebuiltRuleAssetClient: IPrebuiltRuleAssetsClient; rule: RuleResponse; + isRuleCustomizationEnabled: boolean; } export async function calculateRuleSource({ prebuiltRuleAssetClient, rule, + isRuleCustomizationEnabled, }: CalculateRuleSourceProps): Promise { if (rule.immutable) { // This is a prebuilt rule and, despite the name, they are not immutable. So @@ -33,7 +35,11 @@ export async function calculateRuleSource({ ]); const baseRule: PrebuiltRuleAsset | undefined = prebuiltRulesResponse.at(0); - const isCustomized = calculateIsCustomized(baseRule, rule); + const isCustomized = calculateIsCustomized({ + baseRule, + nextRule: rule, + isRuleCustomizationEnabled, + }); return { type: 'external', diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/methods/import_rule.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/methods/import_rule.ts index dd57e66c41a64..16fda89391ab9 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/methods/import_rule.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/methods/import_rule.ts @@ -26,6 +26,7 @@ interface ImportRuleOptions { prebuiltRuleAssetClient: IPrebuiltRuleAssetsClient; importRulePayload: ImportRuleArgs; mlAuthz: MlAuthz; + isRuleCustomizationEnabled: boolean; } export const importRule = async ({ @@ -34,6 +35,7 @@ export const importRule = async ({ importRulePayload, prebuiltRuleAssetClient, mlAuthz, + isRuleCustomizationEnabled, }: ImportRuleOptions): Promise => { const { ruleToImport, overwriteRules, overrideFields, allowMissingConnectorSecrets } = importRulePayload; @@ -60,6 +62,7 @@ export const importRule = async ({ prebuiltRuleAssetClient, existingRule, ruleUpdate: rule, + isRuleCustomizationEnabled, }); // applyRuleUpdate prefers the existing rule's values for `rule_source` and `immutable`, but we want to use the importing rule's calculated values ruleWithUpdates = { ...ruleWithUpdates, ...overrideFields }; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/methods/patch_rule.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/methods/patch_rule.ts index 113576e8d02e2..0b22ea39eaef4 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/methods/patch_rule.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/methods/patch_rule.ts @@ -28,6 +28,7 @@ interface PatchRuleOptions { prebuiltRuleAssetClient: IPrebuiltRuleAssetsClient; rulePatch: RulePatchProps; mlAuthz: MlAuthz; + isRuleCustomizationEnabled: boolean; } export const patchRule = async ({ @@ -36,6 +37,7 @@ export const patchRule = async ({ prebuiltRuleAssetClient, rulePatch, mlAuthz, + isRuleCustomizationEnabled, }: PatchRuleOptions): Promise => { const { rule_id: ruleId, id } = rulePatch; @@ -58,6 +60,7 @@ export const patchRule = async ({ prebuiltRuleAssetClient, existingRule, rulePatch, + isRuleCustomizationEnabled, }); const patchedInternalRule = await rulesClient.update({ diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/methods/update_rule.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/methods/update_rule.ts index 8fd7f7a89dcb7..3d465d44fdc1d 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/methods/update_rule.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/methods/update_rule.ts @@ -27,6 +27,7 @@ interface UpdateRuleArguments { prebuiltRuleAssetClient: IPrebuiltRuleAssetsClient; ruleUpdate: RuleUpdateProps; mlAuthz: MlAuthz; + isRuleCustomizationEnabled: boolean; } export const updateRule = async ({ @@ -35,6 +36,7 @@ export const updateRule = async ({ prebuiltRuleAssetClient, ruleUpdate, mlAuthz, + isRuleCustomizationEnabled, }: UpdateRuleArguments): Promise => { const { rule_id: ruleId, id } = ruleUpdate; @@ -57,6 +59,7 @@ export const updateRule = async ({ prebuiltRuleAssetClient, existingRule, ruleUpdate, + isRuleCustomizationEnabled, }); const updatedRule = await rulesClient.update({ diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/methods/upgrade_prebuilt_rule.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/methods/upgrade_prebuilt_rule.ts index 64486bed14304..dff7c8a333ca7 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/methods/upgrade_prebuilt_rule.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/methods/upgrade_prebuilt_rule.ts @@ -25,12 +25,14 @@ export const upgradePrebuiltRule = async ({ ruleAsset, mlAuthz, prebuiltRuleAssetClient, + isRuleCustomizationEnabled, }: { actionsClient: ActionsClient; rulesClient: RulesClient; ruleAsset: PrebuiltRuleAsset; mlAuthz: MlAuthz; prebuiltRuleAssetClient: IPrebuiltRuleAssetsClient; + isRuleCustomizationEnabled: boolean; }): Promise => { await validateMlAuth(mlAuthz, ruleAsset.type); @@ -73,6 +75,7 @@ export const upgradePrebuiltRule = async ({ prebuiltRuleAssetClient, existingRule, ruleUpdate: ruleAsset, + isRuleCustomizationEnabled, }); const updatedInternalRule = await rulesClient.update({ diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/import/calculate_rule_source_for_import.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/import/calculate_rule_source_for_import.test.ts index e3bfb75c6a88d..b1952ff6948c7 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/import/calculate_rule_source_for_import.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/import/calculate_rule_source_for_import.test.ts @@ -15,6 +15,7 @@ describe('calculateRuleSourceForImport', () => { rule: getRulesSchemaMock(), prebuiltRuleAssetsByRuleId: {}, isKnownPrebuiltRule: false, + isRuleCustomizationEnabled: true, }); expect(result).toEqual({ @@ -33,6 +34,7 @@ describe('calculateRuleSourceForImport', () => { rule, prebuiltRuleAssetsByRuleId: {}, isKnownPrebuiltRule: true, + isRuleCustomizationEnabled: true, }); expect(result).toEqual({ @@ -53,6 +55,7 @@ describe('calculateRuleSourceForImport', () => { rule, prebuiltRuleAssetsByRuleId, isKnownPrebuiltRule: true, + isRuleCustomizationEnabled: true, }); expect(result).toEqual({ @@ -73,6 +76,7 @@ describe('calculateRuleSourceForImport', () => { rule, prebuiltRuleAssetsByRuleId, isKnownPrebuiltRule: true, + isRuleCustomizationEnabled: true, }); expect(result).toEqual({ diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/import/calculate_rule_source_for_import.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/import/calculate_rule_source_for_import.ts index 133566a7b776b..32a1f622b08d8 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/import/calculate_rule_source_for_import.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/import/calculate_rule_source_for_import.ts @@ -28,10 +28,12 @@ export const calculateRuleSourceForImport = ({ rule, prebuiltRuleAssetsByRuleId, isKnownPrebuiltRule, + isRuleCustomizationEnabled, }: { rule: ValidatedRuleToImport; prebuiltRuleAssetsByRuleId: Record; isKnownPrebuiltRule: boolean; + isRuleCustomizationEnabled: boolean; }): { ruleSource: RuleSource; immutable: boolean } => { const assetWithMatchingVersion = prebuiltRuleAssetsByRuleId[rule.rule_id]; // We convert here so that RuleSource calculation can @@ -43,6 +45,7 @@ export const calculateRuleSourceForImport = ({ rule: ruleResponseForImport, assetWithMatchingVersion, isKnownPrebuiltRule, + isRuleCustomizationEnabled, }); return { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/import/calculate_rule_source_from_asset.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/import/calculate_rule_source_from_asset.test.ts index 9a2f68479fdea..099c0f41f1720 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/import/calculate_rule_source_from_asset.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/import/calculate_rule_source_from_asset.test.ts @@ -15,6 +15,7 @@ describe('calculateRuleSourceFromAsset', () => { rule: getRulesSchemaMock(), assetWithMatchingVersion: undefined, isKnownPrebuiltRule: false, + isRuleCustomizationEnabled: true, }); expect(result).toEqual({ @@ -28,6 +29,7 @@ describe('calculateRuleSourceFromAsset', () => { rule: ruleToImport, assetWithMatchingVersion: undefined, isKnownPrebuiltRule: true, + isRuleCustomizationEnabled: true, }); expect(result).toEqual({ @@ -47,6 +49,7 @@ describe('calculateRuleSourceFromAsset', () => { // no other overwrites -> no differences }), isKnownPrebuiltRule: true, + isRuleCustomizationEnabled: true, }); expect(result).toEqual({ @@ -65,6 +68,7 @@ describe('calculateRuleSourceFromAsset', () => { name: 'Customized name', // mock a customization }), isKnownPrebuiltRule: true, + isRuleCustomizationEnabled: true, }); expect(result).toEqual({ diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/import/calculate_rule_source_from_asset.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/import/calculate_rule_source_from_asset.ts index 4f0caf9b10056..33063bedb11b2 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/import/calculate_rule_source_from_asset.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/import/calculate_rule_source_from_asset.ts @@ -24,10 +24,12 @@ export const calculateRuleSourceFromAsset = ({ rule, assetWithMatchingVersion, isKnownPrebuiltRule, + isRuleCustomizationEnabled, }: { rule: RuleResponse; assetWithMatchingVersion: PrebuiltRuleAsset | undefined; isKnownPrebuiltRule: boolean; + isRuleCustomizationEnabled: boolean; }): RuleSource => { if (!isKnownPrebuiltRule) { return { @@ -38,11 +40,15 @@ export const calculateRuleSourceFromAsset = ({ if (assetWithMatchingVersion == null) { return { type: 'external', - is_customized: true, + is_customized: isRuleCustomizationEnabled ? true : false, }; } - const isCustomized = calculateIsCustomized(assetWithMatchingVersion, rule); + const isCustomized = calculateIsCustomized({ + baseRule: assetWithMatchingVersion, + nextRule: rule, + isRuleCustomizationEnabled, + }); return { type: 'external', diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/import/rule_source_importer/rule_source_importer.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/import/rule_source_importer/rule_source_importer.test.ts index 39c937f4645a7..426109bbeb3bb 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/import/rule_source_importer/rule_source_importer.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/import/rule_source_importer/rule_source_importer.test.ts @@ -138,6 +138,7 @@ describe('ruleSourceImporter', () => { rule, prebuiltRuleAssetsByRuleId: { 'rule-1': expect.objectContaining({ rule_id: 'rule-1' }) }, isKnownPrebuiltRule: true, + isRuleCustomizationEnabled: true, }); }); @@ -166,6 +167,7 @@ describe('ruleSourceImporter', () => { rule, prebuiltRuleAssetsByRuleId: { 'rule-1': expect.objectContaining({ rule_id: 'rule-1' }) }, isKnownPrebuiltRule: true, + isRuleCustomizationEnabled: true, }); }); }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/import/rule_source_importer/rule_source_importer.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/import/rule_source_importer/rule_source_importer.ts index 1f5c2c5aa543b..0c553e6bb7c56 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/import/rule_source_importer/rule_source_importer.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/import/rule_source_importer/rule_source_importer.ts @@ -143,6 +143,8 @@ export class RuleSourceImporter implements IRuleSourceImporter { rule, prebuiltRuleAssetsByRuleId: this.matchingAssetsByRuleId, isKnownPrebuiltRule: this.availableRuleAssetIds.has(rule.rule_id), + isRuleCustomizationEnabled: + this.config.experimentalFeatures.prebuiltRulesCustomizationEnabled, }); } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/__mocks__/rule_type.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/__mocks__/rule_type.ts index c3b748f5d1828..b36ca687bc515 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/__mocks__/rule_type.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/__mocks__/rule_type.ts @@ -16,7 +16,7 @@ import type { IRuleDataClient } from '@kbn/rule-registry-plugin/server'; import { ruleRegistryMocks } from '@kbn/rule-registry-plugin/server/mocks'; import { eventLogServiceMock } from '@kbn/event-log-plugin/server/mocks'; import type { PluginSetupContract as ActionsPluginSetupContract } from '@kbn/actions-plugin/server'; -import type { PluginSetupContract as AlertingPluginSetupContract } from '@kbn/alerting-plugin/server'; +import type { AlertingServerSetup } from '@kbn/alerting-plugin/server'; import type { ConfigType } from '../../../../config'; import type { AlertAttributes } from '../types'; import { createRuleMock } from './rule'; @@ -48,7 +48,7 @@ export const createRuleTypeMocks = ( alertExecutor = executor; }, getConfig: () => ({ run: { alerts: { max: DEFAULT_MAX_ALERTS } } }), - } as AlertingPluginSetupContract; + } as AlertingServerSetup; const actions = { registerType: jest.fn(), diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/search_after_bulk_create.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/search_after_bulk_create.test.ts index d2e51e03908f7..d3b0c2dd6b420 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/search_after_bulk_create.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/search_after_bulk_create.test.ts @@ -48,7 +48,7 @@ import { ruleExecutionLogMock } from '../../rule_monitoring/mocks'; import type { BuildReasonMessage } from './reason_formatters'; import type { QueryRuleParams } from '../../rule_schema'; import { SERVER_APP_ID } from '../../../../../common/constants'; -import type { PluginSetupContract } from '@kbn/alerting-plugin/server'; +import type { AlertingServerSetup } from '@kbn/alerting-plugin/server'; describe('searchAfterAndBulkCreate', () => { let mockService: RuleExecutorServicesMock; @@ -58,7 +58,7 @@ describe('searchAfterAndBulkCreate', () => { let wrapHits: WrapHits; let inputIndexPattern: string[] = []; let listClient = listMock.getListClient(); - let alerting: PluginSetupContract; + let alerting: AlertingServerSetup; const ruleExecutionLogger = ruleExecutionLogMock.forExecutors.create(); const someGuids = Array.from({ length: 13 }).map(() => uuidv4()); const sampleParams = getQueryRuleParams(); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/utils.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/utils.test.ts index 5397d473af3c8..0a625ed5f245b 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/utils.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/utils.test.ts @@ -68,7 +68,7 @@ import type { ShardError } from '../../../types'; import { ruleExecutionLogMock } from '../../rule_monitoring/mocks'; import type { GenericBulkCreateResponse } from '../factories'; import type { BaseFieldsLatest } from '../../../../../common/api/detection_engine/model/alerts'; -import type { PluginSetupContract } from '@kbn/alerting-plugin/server'; +import type { AlertingServerSetup } from '@kbn/alerting-plugin/server'; describe('utils', () => { const anchor = '2020-01-01T06:06:06.666Z'; @@ -446,7 +446,7 @@ describe('utils', () => { }); describe('getRuleRangeTuples', () => { - let alerting: PluginSetupContract; + let alerting: AlertingServerSetup; beforeEach(() => { alerting = alertsMock.createSetup(); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/utils.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/utils.ts index 45193c14fa396..bf0899978f2b2 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/utils.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/utils.ts @@ -27,7 +27,7 @@ import type { import type { AlertInstanceContext, AlertInstanceState, - PluginSetupContract, + AlertingServerSetup, RuleExecutorServices, } from '@kbn/alerting-plugin/server'; import { parseDuration } from '@kbn/alerting-plugin/server'; @@ -429,7 +429,7 @@ export const getRuleRangeTuples = async ({ interval: string; maxSignals: number; ruleExecutionLogger: IRuleExecutionLogForExecutors; - alerting: PluginSetupContract; + alerting: AlertingServerSetup; }) => { const originalFrom = dateMath.parse(from, { forceNow: startedAt }); const originalTo = dateMath.parse(to, { forceNow: startedAt }); diff --git a/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/auditing/resources.ts b/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/auditing/resources.ts deleted file mode 100644 index 67d33fb42dc93..0000000000000 --- a/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/auditing/resources.ts +++ /dev/null @@ -1,18 +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. - */ - -export const EntityStoreResource = { - ENTITY_ENGINE: 'entity_engine', - ENTITY_DEFINITION: 'entity_definition', - ENTITY_INDEX: 'entity_index', - INDEX_COMPONENT_TEMPLATE: 'index_component_template', - PLATFORM_PIPELINE: 'platform_pipeline', - FIELD_RETENTION_ENRICH_POLICY: 'field_retention_enrich_policy', - FIELD_RETENTION_ENRICH_POLICY_TASK: 'field_retention_enrich_policy_task', -} as const; - -export type EntityStoreResource = (typeof EntityStoreResource)[keyof typeof EntityStoreResource]; diff --git a/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/elasticsearch_assets/component_template.ts b/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/elasticsearch_assets/component_template.ts index d0fe14dcd3b8d..a1352594ff47d 100644 --- a/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/elasticsearch_assets/component_template.ts +++ b/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/elasticsearch_assets/component_template.ts @@ -6,6 +6,10 @@ */ import type { ElasticsearchClient } from '@kbn/core/server'; +import { + EngineComponentResourceEnum, + type EngineComponentStatus, +} from '../../../../../common/api/entity_analytics'; import type { UnitedEntityDefinition } from '../united_entity_definitions'; const getComponentTemplateName = (definitionId: string) => `${definitionId}-latest@platform`; @@ -41,3 +45,24 @@ export const deleteEntityIndexComponentTemplate = ({ unitedDefinition, esClient } ); }; + +export const getEntityIndexComponentTemplateStatus = async ({ + definitionId, + esClient, +}: Pick & { definitionId: string }): Promise => { + const name = getComponentTemplateName(definitionId); + const componentTemplate = await esClient.cluster.getComponentTemplate( + { + name, + }, + { + ignore: [404], + } + ); + + return { + id: name, + installed: componentTemplate?.component_templates?.length > 0, + resource: EngineComponentResourceEnum.component_template, + }; +}; diff --git a/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/elasticsearch_assets/enrich_policy.ts b/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/elasticsearch_assets/enrich_policy.ts index 4b8ce594a6cb7..7064a4dd98851 100644 --- a/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/elasticsearch_assets/enrich_policy.ts +++ b/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/elasticsearch_assets/enrich_policy.ts @@ -7,6 +7,7 @@ import type { ElasticsearchClient, Logger } from '@kbn/core/server'; import type { EnrichPutPolicyRequest } from '@elastic/elasticsearch/lib/api/types'; +import { EngineComponentResourceEnum } from '../../../../../common/api/entity_analytics'; import { getEntitiesIndexName } from '../utils'; import type { UnitedEntityDefinition } from '../united_entity_definitions'; @@ -105,3 +106,21 @@ export const deleteFieldRetentionEnrichPolicy = async ({ } } }; + +export const getFieldRetentionEnrichPolicyStatus = async ({ + definitionMetadata, + esClient, +}: { + definitionMetadata: DefinitionMetadata; + esClient: ElasticsearchClient; +}) => { + const name = getFieldRetentionEnrichPolicyName(definitionMetadata); + const policy = await esClient.enrich.getPolicy({ name }, { ignore: [404] }); + const policies = policy.policies; + + return { + installed: policies.length > 0, + id: name, + resource: EngineComponentResourceEnum.enrich_policy, + }; +}; diff --git a/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/elasticsearch_assets/entity_index.ts b/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/elasticsearch_assets/entity_index.ts index 6fb5935618dfc..0de8fe20050ce 100644 --- a/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/elasticsearch_assets/entity_index.ts +++ b/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/elasticsearch_assets/entity_index.ts @@ -6,7 +6,11 @@ */ import type { ElasticsearchClient, Logger } from '@kbn/core/server'; -import type { EntityType } from '../../../../../common/api/entity_analytics'; +import { + EngineComponentResourceEnum, + type EngineComponentStatus, + type EntityType, +} from '../../../../../common/api/entity_analytics'; import { getEntitiesIndexName } from '../utils'; import { createOrUpdateIndex } from '../../utils/create_or_update_index'; @@ -36,3 +40,21 @@ export const deleteEntityIndex = ({ entityType, esClient, namespace }: Options) ignore: [404], } ); + +export const getEntityIndexStatus = async ({ + entityType, + esClient, + namespace, +}: Pick): Promise => { + const index = getEntitiesIndexName(entityType, namespace); + const exists = await esClient.indices.exists( + { + index, + }, + { + ignore: [404], + } + ); + + return { id: index, installed: exists, resource: EngineComponentResourceEnum.index }; +}; diff --git a/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/elasticsearch_assets/ingest_pipeline.ts b/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/elasticsearch_assets/ingest_pipeline.ts index f4d2b848b726f..f57102fd13f14 100644 --- a/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/elasticsearch_assets/ingest_pipeline.ts +++ b/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/elasticsearch_assets/ingest_pipeline.ts @@ -8,6 +8,7 @@ import type { ElasticsearchClient, Logger } from '@kbn/core/server'; import type { IngestProcessorContainer } from '@elastic/elasticsearch/lib/api/types'; import type { EntityDefinition } from '@kbn/entities-schema'; +import { EngineComponentResourceEnum } from '../../../../../common/api/entity_analytics'; import { type FieldRetentionDefinition } from '../field_retention_definition'; import { debugDeepCopyContextStep, @@ -161,3 +162,27 @@ export const deletePlatformPipeline = ({ } ); }; + +export const getPlatformPipelineStatus = async ({ + definition, + esClient, +}: { + definition: EntityDefinition; + esClient: ElasticsearchClient; +}) => { + const pipelineId = getPlatformPipelineId(definition); + const pipeline = await esClient.ingest.getPipeline( + { + id: pipelineId, + }, + { + ignore: [404], + } + ); + + return { + id: pipelineId, + installed: !!pipeline[pipelineId], + resource: EngineComponentResourceEnum.ingest_pipeline, + }; +}; diff --git a/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/entity_store_data_client.ts b/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/entity_store_data_client.ts index a89469acf569b..72d650846fc55 100644 --- a/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/entity_store_data_client.ts +++ b/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/entity_store_data_client.ts @@ -20,19 +20,28 @@ import type { TaskManagerStartContract } from '@kbn/task-manager-plugin/server'; import type { DataViewsService } from '@kbn/data-views-plugin/common'; import { isEqual } from 'lodash/fp'; import moment from 'moment'; +import type { EntityDefinitionWithState } from '@kbn/entityManager-plugin/server/lib/entities/types'; +import type { EntityDefinition } from '@kbn/entities-schema'; +import type { estypes } from '@elastic/elasticsearch'; import type { + GetEntityStoreStatusRequestQuery, GetEntityStoreStatusResponse, +} from '../../../../common/api/entity_analytics/entity_store/status.gen'; +import type { InitEntityStoreRequestBody, InitEntityStoreResponse, -} from '../../../../common/api/entity_analytics/entity_store/enablement.gen'; +} from '../../../../common/api/entity_analytics/entity_store/enable.gen'; import type { AppClient } from '../../..'; -import { EntityType } from '../../../../common/api/entity_analytics'; +import { EngineComponentResourceEnum, EntityType } from '../../../../common/api/entity_analytics'; import type { Entity, EngineDataviewUpdateResult, InitEntityEngineRequestBody, InitEntityEngineResponse, InspectQuery, + ListEntityEnginesResponse, + EngineComponentStatus, + EngineComponentResource, } from '../../../../common/api/entity_analytics'; import { EngineDescriptorClient } from './saved_object/engine_descriptor'; import { ENGINE_STATUS, ENTITY_STORE_STATUS, MAX_SEARCH_RESPONSE_SIZE } from './constants'; @@ -41,6 +50,7 @@ import { getUnitedEntityDefinition } from './united_entity_definitions'; import { startEntityStoreFieldRetentionEnrichTask, removeEntityStoreFieldRetentionEnrichTask, + getEntityStoreFieldRetentionEnrichTaskState as getEntityStoreFieldRetentionEnrichTaskStatus, } from './task'; import { createEntityIndex, @@ -52,6 +62,10 @@ import { createFieldRetentionEnrichPolicy, executeFieldRetentionEnrichPolicy, deleteFieldRetentionEnrichPolicy, + getPlatformPipelineStatus, + getFieldRetentionEnrichPolicyStatus, + getEntityIndexStatus, + getEntityIndexComponentTemplateStatus, } from './elasticsearch_assets'; import { RiskScoreDataClient } from '../risk_score/risk_score_data_client'; import { @@ -62,7 +76,6 @@ import { isPromiseRejected, } from './utils'; import { EntityEngineActions } from './auditing/actions'; -import { EntityStoreResource } from './auditing/resources'; import { AUDIT_CATEGORY, AUDIT_OUTCOME, AUDIT_TYPE } from '../audit'; import type { EntityRecord, EntityStoreConfig } from './types'; import { @@ -71,6 +84,19 @@ import { } from '../../telemetry/event_based/events'; import { CRITICALITY_VALUES } from '../asset_criticality/constants'; +// Workaround. TransformState type is wrong. The health type should be: TransformHealth from '@kbn/transform-plugin/common/types/transform_stats' +export interface TransformHealth extends estypes.TransformGetTransformStatsTransformStatsHealth { + issues?: TransformHealthIssue[]; +} + +export interface TransformHealthIssue { + type: string; + issue: string; + details?: string; + count: number; + first_occurrence?: number; +} + interface EntityStoreClientOpts { logger: Logger; clusterClient: IScopedClusterClient; @@ -131,6 +157,42 @@ export class EntityStoreDataClient { }); } + private async getEngineComponentsState( + type: EntityType, + definition?: EntityDefinition + ): Promise { + const { namespace, taskManager } = this.options; + + return definition + ? Promise.all([ + ...(taskManager + ? [getEntityStoreFieldRetentionEnrichTaskStatus({ namespace, taskManager })] + : []), + getPlatformPipelineStatus({ + definition, + esClient: this.esClient, + }), + getFieldRetentionEnrichPolicyStatus({ + definitionMetadata: { + namespace, + entityType: type, + version: definition.version, + }, + esClient: this.esClient, + }), + getEntityIndexStatus({ + entityType: type, + esClient: this.esClient, + namespace, + }), + getEntityIndexComponentTemplateStatus({ + definitionId: definition.id, + esClient: this.esClient, + }), + ]) + : Promise.resolve([] as EngineComponentStatus[]); + } + public async enable( { indexPattern = '', filter = '', fieldHistoryLength = 10 }: InitEntityStoreRequestBody, { pipelineDebugMode = false }: { pipelineDebugMode?: boolean } = {} @@ -152,7 +214,10 @@ export class EntityStoreDataClient { return { engines, succeeded: true }; } - public async status(): Promise { + public async status({ + include_components: withComponents = false, + }: GetEntityStoreStatusRequestQuery): Promise { + const { namespace } = this.options; const { engines, count } = await this.engineClient.list(); let status = ENTITY_STORE_STATUS.RUNNING; @@ -166,7 +231,38 @@ export class EntityStoreDataClient { status = ENTITY_STORE_STATUS.INSTALLING; } - return { engines, status }; + if (withComponents) { + const enginesWithComponents = await Promise.all( + engines.map(async (engine) => { + const entityDefinitionId = buildEntityDefinitionId(engine.type, namespace); + const { + definitions: [definition], + } = await this.entityClient.getEntityDefinitions({ + id: entityDefinitionId, + includeState: withComponents, + }); + + const definitionComponents = this.getComponentFromEntityDefinition( + entityDefinitionId, + definition + ); + + const entityStoreComponents = await this.getEngineComponentsState( + engine.type, + definition + ); + + return { + ...engine, + components: [...definitionComponents, ...entityStoreComponents], + }; + }) + ); + + return { engines: enginesWithComponents, status }; + } else { + return { engines, status }; + } } public async init( @@ -203,7 +299,7 @@ export class EntityStoreDataClient { this.log('info', entityType, `Initializing entity store`); this.audit( EntityEngineActions.INIT, - EntityStoreResource.ENTITY_ENGINE, + EngineComponentResourceEnum.entity_engine, entityType, 'Initializing entity engine' ); @@ -332,7 +428,7 @@ export class EntityStoreDataClient { this.audit( EntityEngineActions.INIT, - EntityStoreResource.ENTITY_ENGINE, + EngineComponentResourceEnum.entity_engine, entityType, 'Failed to initialize entity engine resources', err @@ -355,6 +451,50 @@ export class EntityStoreDataClient { } } + public getComponentFromEntityDefinition( + id: string, + definition: EntityDefinitionWithState | EntityDefinition + ): EngineComponentStatus[] { + if (!definition) { + return [ + { + id, + installed: false, + resource: EngineComponentResourceEnum.entity_definition, + }, + ]; + } + + if ('state' in definition) { + return [ + { + id: definition.id, + installed: definition.state.installed, + resource: EngineComponentResourceEnum.entity_definition, + }, + ...definition.state.components.transforms.map(({ installed, running, stats }) => ({ + id, + resource: EngineComponentResourceEnum.transform, + installed, + errors: (stats?.health as TransformHealth)?.issues?.map(({ issue, details }) => ({ + title: issue, + message: details, + })), + })), + ...definition.state.components.ingestPipelines.map((pipeline) => ({ + resource: EngineComponentResourceEnum.ingest_pipeline, + ...pipeline, + })), + ...definition.state.components.indexTemplates.map(({ installed }) => ({ + id, + installed, + resource: EngineComponentResourceEnum.index_template, + })), + ]; + } + return []; + } + public async getExistingEntityDefinition(entityType: EntityType) { const entityDefinitionId = buildEntityDefinitionId(entityType, this.options.namespace); @@ -387,7 +527,7 @@ export class EntityStoreDataClient { const fullEntityDefinition = await this.getExistingEntityDefinition(entityType); this.audit( EntityEngineActions.START, - EntityStoreResource.ENTITY_DEFINITION, + EngineComponentResourceEnum.entity_definition, entityType, 'Starting entity definition' ); @@ -414,7 +554,7 @@ export class EntityStoreDataClient { const fullEntityDefinition = await this.getExistingEntityDefinition(entityType); this.audit( EntityEngineActions.STOP, - EntityStoreResource.ENTITY_DEFINITION, + EngineComponentResourceEnum.entity_definition, entityType, 'Stopping entity definition' ); @@ -428,7 +568,7 @@ export class EntityStoreDataClient { return this.engineClient.get(entityType); } - public async list() { + public async list(): Promise { return this.engineClient.list(); } @@ -457,7 +597,7 @@ export class EntityStoreDataClient { this.log('info', entityType, `Deleting entity store`); this.audit( EntityEngineActions.DELETE, - EntityStoreResource.ENTITY_ENGINE, + EngineComponentResourceEnum.entity_engine, entityType, 'Deleting entity engine' ); @@ -525,7 +665,7 @@ export class EntityStoreDataClient { this.audit( EntityEngineActions.DELETE, - EntityStoreResource.ENTITY_ENGINE, + EngineComponentResourceEnum.entity_engine, entityType, 'Failed to delete entity engine', err @@ -672,7 +812,7 @@ export class EntityStoreDataClient { private audit( action: EntityEngineActions, - resource: EntityStoreResource, + resource: EngineComponentResource, entityType: EntityType, msg: string, error?: Error diff --git a/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/routes/enablement.ts b/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/routes/enablement.ts index 16813fccdf235..d19e9699f4756 100644 --- a/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/routes/enablement.ts +++ b/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/routes/enablement.ts @@ -10,8 +10,8 @@ import { buildSiemResponse } from '@kbn/lists-plugin/server/routes/utils'; import { transformError } from '@kbn/securitysolution-es-utils'; import { buildRouteValidationWithZod } from '@kbn/zod-helpers'; -import type { InitEntityStoreResponse } from '../../../../../common/api/entity_analytics/entity_store/enablement.gen'; -import { InitEntityStoreRequestBody } from '../../../../../common/api/entity_analytics/entity_store/enablement.gen'; +import type { InitEntityStoreResponse } from '../../../../../common/api/entity_analytics/entity_store/enable.gen'; +import { InitEntityStoreRequestBody } from '../../../../../common/api/entity_analytics/entity_store/enable.gen'; import { API_VERSIONS, APP_ID } from '../../../../../common/constants'; import type { EntityAnalyticsRoutesDeps } from '../../types'; import { checkAndInitAssetCriticalityResources } from '../../asset_criticality/check_and_init_asset_criticality_resources'; diff --git a/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/routes/stats.ts b/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/routes/stats.ts deleted file mode 100644 index 24785fbd5c015..0000000000000 --- a/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/routes/stats.ts +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import type { IKibanaResponse, Logger } from '@kbn/core/server'; -import { buildSiemResponse } from '@kbn/lists-plugin/server/routes/utils'; -import { transformError } from '@kbn/securitysolution-es-utils'; -import { buildRouteValidationWithZod } from '@kbn/zod-helpers'; - -import type { GetEntityEngineStatsResponse } from '../../../../../common/api/entity_analytics/entity_store/engine/stats.gen'; -import { GetEntityEngineStatsRequestParams } from '../../../../../common/api/entity_analytics/entity_store/engine/stats.gen'; -import { API_VERSIONS, APP_ID } from '../../../../../common/constants'; -import type { EntityAnalyticsRoutesDeps } from '../../types'; - -export const getEntityEngineStatsRoute = ( - router: EntityAnalyticsRoutesDeps['router'], - logger: Logger -) => { - router.versioned - .post({ - access: 'public', - path: '/api/entity_store/engines/{entityType}/stats', - security: { - authz: { - requiredPrivileges: ['securitySolution', `${APP_ID}-entity-analytics`], - }, - }, - }) - .addVersion( - { - version: API_VERSIONS.public.v1, - validate: { - request: { - params: buildRouteValidationWithZod(GetEntityEngineStatsRequestParams), - }, - }, - }, - - async ( - context, - request, - response - ): Promise> => { - const siemResponse = buildSiemResponse(response); - - try { - // TODO - throw new Error('Not implemented'); - - // return response.ok({ body }); - } catch (e) { - logger.error('Error in GetEntityEngineStats:', e); - const error = transformError(e); - return siemResponse.error({ - statusCode: error.statusCode, - body: error.message, - }); - } - } - ); -}; diff --git a/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/routes/status.ts b/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/routes/status.ts index 7a59b59b9914a..c2c24b114f66b 100644 --- a/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/routes/status.ts +++ b/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/routes/status.ts @@ -15,7 +15,9 @@ import type { IKibanaResponse, Logger } from '@kbn/core/server'; import { buildSiemResponse } from '@kbn/lists-plugin/server/routes/utils'; import { transformError } from '@kbn/securitysolution-es-utils'; -import type { GetEntityStoreStatusResponse } from '../../../../../common/api/entity_analytics/entity_store/enablement.gen'; +import { buildRouteValidationWithZod } from '@kbn/zod-helpers'; +import type { GetEntityStoreStatusResponse } from '../../../../../common/api/entity_analytics/entity_store/status.gen'; +import { GetEntityStoreStatusRequestQuery } from '../../../../../common/api/entity_analytics/entity_store/status.gen'; import { API_VERSIONS, APP_ID } from '../../../../../common/constants'; import type { EntityAnalyticsRoutesDeps } from '../../types'; import { checkAndInitAssetCriticalityResources } from '../../asset_criticality/check_and_init_asset_criticality_resources'; @@ -38,7 +40,11 @@ export const getEntityStoreStatusRoute = ( .addVersion( { version: API_VERSIONS.public.v1, - validate: {}, + validate: { + request: { + query: buildRouteValidationWithZod(GetEntityStoreStatusRequestQuery), + }, + }, }, async ( @@ -54,7 +60,7 @@ export const getEntityStoreStatusRoute = ( try { const body: GetEntityStoreStatusResponse = await secSol .getEntityStoreDataClient() - .status(); + .status(request.query); return response.ok({ body }); } catch (e) { diff --git a/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/task/field_retention_enrichment_task.ts b/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/task/field_retention_enrichment_task.ts index 708b74277faae..3d103ea2af467 100644 --- a/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/task/field_retention_enrichment_task.ts +++ b/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/task/field_retention_enrichment_task.ts @@ -13,7 +13,10 @@ import type { TaskManagerSetupContract, TaskManagerStartContract, } from '@kbn/task-manager-plugin/server'; -import type { EntityType } from '../../../../../common/api/entity_analytics/entity_store'; +import { + EngineComponentResourceEnum, + type EntityType, +} from '../../../../../common/api/entity_analytics/entity_store'; import { defaultState, stateSchemaByVersion, @@ -275,3 +278,37 @@ const createTaskRunnerFactory = }, }; }; + +export const getEntityStoreFieldRetentionEnrichTaskState = async ({ + namespace, + taskManager, +}: { + namespace: string; + taskManager: TaskManagerStartContract; +}) => { + const taskId = getTaskId(namespace); + try { + const taskState = await taskManager.get(taskId); + + return { + id: taskState.id, + resource: EngineComponentResourceEnum.task, + installed: true, + enabled: taskState.enabled, + status: taskState.status, + retryAttempts: taskState.attempts, + nextRun: taskState.runAt, + lastRun: taskState.state.lastExecutionTimestamp, + runs: taskState.state.runs, + }; + } catch (e) { + if (SavedObjectsErrorHelpers.isNotFoundError(e)) { + return { + id: taskId, + installed: false, + resource: EngineComponentResourceEnum.task, + }; + } + throw e; + } +}; diff --git a/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/api/get.ts b/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/api/get.ts index e6edb05b3a68a..0d880484877f6 100644 --- a/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/api/get.ts +++ b/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/api/get.ts @@ -38,7 +38,7 @@ export const registerSiemRuleMigrationsGetRoute = ( const ctx = await context.resolve(['securitySolution']); const ruleMigrationsClient = ctx.securitySolution.getSiemRuleMigrationsClient(); - const migrationRules = await ruleMigrationsClient.data.rules.get(migrationId); + const migrationRules = await ruleMigrationsClient.data.rules.get({ migrationId }); return res.ok({ body: migrationRules }); } catch (err) { diff --git a/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/api/index.ts b/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/api/index.ts index c6ea6b8bf897b..601b156aee040 100644 --- a/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/api/index.ts +++ b/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/api/index.ts @@ -17,6 +17,8 @@ import { registerSiemRuleMigrationsStatsAllRoute } from './stats_all'; import { registerSiemRuleMigrationsResourceUpsertRoute } from './resources/upsert'; import { registerSiemRuleMigrationsResourceGetRoute } from './resources/get'; import { registerSiemRuleMigrationsRetryRoute } from './retry'; +import { registerSiemRuleMigrationsInstallRoute } from './rules/install'; +import { registerSiemRuleMigrationsInstallTranslatedRoute } from './rules/install_translated'; export const registerSiemRuleMigrationsRoutes = ( router: SecuritySolutionPluginRouter, @@ -30,6 +32,8 @@ export const registerSiemRuleMigrationsRoutes = ( registerSiemRuleMigrationsRetryRoute(router, logger); registerSiemRuleMigrationsStatsRoute(router, logger); registerSiemRuleMigrationsStopRoute(router, logger); + registerSiemRuleMigrationsInstallRoute(router, logger); + registerSiemRuleMigrationsInstallTranslatedRoute(router, logger); registerSiemRuleMigrationsResourceUpsertRoute(router, logger); registerSiemRuleMigrationsResourceGetRoute(router, logger); diff --git a/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/api/resources/upsert.ts b/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/api/resources/upsert.ts index be1f3e84c46ea..645fa09b49dc1 100644 --- a/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/api/resources/upsert.ts +++ b/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/api/resources/upsert.ts @@ -7,7 +7,6 @@ import type { IKibanaResponse, Logger } from '@kbn/core/server'; import { buildRouteValidationWithZod } from '@kbn/zod-helpers'; -import type { RuleMigrationResource } from '../../../../../../common/siem_migrations/model/rule_migration.gen'; import { UpsertRuleMigrationResourcesRequestBody, UpsertRuleMigrationResourcesRequestParams, @@ -15,6 +14,7 @@ import { } from '../../../../../../common/siem_migrations/model/api/rules/rule_migration.gen'; import { SIEM_RULE_MIGRATION_RESOURCES_PATH } from '../../../../../../common/siem_migrations/constants'; import type { SecuritySolutionPluginRouter } from '../../../../../types'; +import type { CreateRuleMigrationResourceInput } from '../../data/rule_migrations_data_resources_client'; import { withLicense } from '../util/with_license'; export const registerSiemRuleMigrationsResourceUpsertRoute = ( @@ -49,7 +49,7 @@ export const registerSiemRuleMigrationsResourceUpsertRoute = ( const ctx = await context.resolve(['securitySolution']); const ruleMigrationsClient = ctx.securitySolution.getSiemRuleMigrationsClient(); - const ruleMigrations = resources.map((resource) => ({ + const ruleMigrations = resources.map((resource) => ({ migration_id: migrationId, ...resource, })); diff --git a/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/api/retry.ts b/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/api/retry.ts index 4406afc4333e5..0fb96d9aaf72c 100644 --- a/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/api/retry.ts +++ b/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/api/retry.ts @@ -50,7 +50,7 @@ export const registerSiemRuleMigrationsRetryRoute = ( const inferenceClient = ctx.securitySolution.getInferenceClient(); const actionsClient = ctx.actions.getActionsClient(); const soClient = ctx.core.savedObjects.client; - const rulesClient = ctx.alerting.getRulesClient(); + const rulesClient = await ctx.alerting.getRulesClient(); const invocationConfig = { callbacks: [ diff --git a/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/api/rules/install.ts b/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/api/rules/install.ts new file mode 100644 index 0000000000000..7e8b1a25a4837 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/api/rules/install.ts @@ -0,0 +1,69 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { IKibanaResponse, Logger } from '@kbn/core/server'; +import { buildRouteValidationWithZod } from '@kbn/zod-helpers'; +import { SIEM_RULE_MIGRATION_INSTALL_PATH } from '../../../../../../common/siem_migrations/constants'; +import type { InstallMigrationRulesResponse } from '../../../../../../common/siem_migrations/model/api/rules/rule_migration.gen'; +import { + InstallMigrationRulesRequestBody, + InstallMigrationRulesRequestParams, +} from '../../../../../../common/siem_migrations/model/api/rules/rule_migration.gen'; +import type { SecuritySolutionPluginRouter } from '../../../../../types'; +import { withLicense } from '../util/with_license'; +import { installTranslated } from '../util/installation'; + +export const registerSiemRuleMigrationsInstallRoute = ( + router: SecuritySolutionPluginRouter, + logger: Logger +) => { + router.versioned + .post({ + path: SIEM_RULE_MIGRATION_INSTALL_PATH, + access: 'internal', + security: { authz: { requiredPrivileges: ['securitySolution'] } }, + }) + .addVersion( + { + version: '1', + validate: { + request: { + params: buildRouteValidationWithZod(InstallMigrationRulesRequestParams), + body: buildRouteValidationWithZod(InstallMigrationRulesRequestBody), + }, + }, + }, + withLicense( + async (context, req, res): Promise> => { + const { migration_id: migrationId } = req.params; + const ids = req.body; + + try { + const ctx = await context.resolve(['core', 'alerting', 'securitySolution']); + + const securitySolutionContext = ctx.securitySolution; + const savedObjectsClient = ctx.core.savedObjects.client; + const rulesClient = await ctx.alerting.getRulesClient(); + + await installTranslated({ + migrationId, + ids, + securitySolutionContext, + savedObjectsClient, + rulesClient, + logger, + }); + + return res.ok({ body: { installed: true } }); + } catch (err) { + logger.error(err); + return res.badRequest({ body: err.message }); + } + } + ) + ); +}; diff --git a/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/api/rules/install_translated.ts b/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/api/rules/install_translated.ts new file mode 100644 index 0000000000000..6fd4b5f0980b6 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/api/rules/install_translated.ts @@ -0,0 +1,67 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { IKibanaResponse, Logger } from '@kbn/core/server'; +import { buildRouteValidationWithZod } from '@kbn/zod-helpers'; +import { SIEM_RULE_MIGRATION_INSTALL_TRANSLATED_PATH } from '../../../../../../common/siem_migrations/constants'; +import type { InstallTranslatedMigrationRulesResponse } from '../../../../../../common/siem_migrations/model/api/rules/rule_migration.gen'; +import { InstallTranslatedMigrationRulesRequestParams } from '../../../../../../common/siem_migrations/model/api/rules/rule_migration.gen'; +import type { SecuritySolutionPluginRouter } from '../../../../../types'; +import { withLicense } from '../util/with_license'; +import { installTranslated } from '../util/installation'; + +export const registerSiemRuleMigrationsInstallTranslatedRoute = ( + router: SecuritySolutionPluginRouter, + logger: Logger +) => { + router.versioned + .post({ + path: SIEM_RULE_MIGRATION_INSTALL_TRANSLATED_PATH, + access: 'internal', + security: { authz: { requiredPrivileges: ['securitySolution'] } }, + }) + .addVersion( + { + version: '1', + validate: { + request: { + params: buildRouteValidationWithZod(InstallTranslatedMigrationRulesRequestParams), + }, + }, + }, + withLicense( + async ( + context, + req, + res + ): Promise> => { + const { migration_id: migrationId } = req.params; + + try { + const ctx = await context.resolve(['core', 'alerting', 'securitySolution']); + + const securitySolutionContext = ctx.securitySolution; + const savedObjectsClient = ctx.core.savedObjects.client; + const rulesClient = await ctx.alerting.getRulesClient(); + + await installTranslated({ + migrationId, + securitySolutionContext, + savedObjectsClient, + rulesClient, + logger, + }); + + return res.ok({ body: { installed: true } }); + } catch (err) { + logger.error(err); + return res.badRequest({ body: err.message }); + } + } + ) + ); +}; diff --git a/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/api/start.ts b/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/api/start.ts index 73ba2fd3cce71..e9369c0e8d19d 100644 --- a/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/api/start.ts +++ b/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/api/start.ts @@ -50,7 +50,7 @@ export const registerSiemRuleMigrationsStartRoute = ( const inferenceClient = ctx.securitySolution.getInferenceClient(); const actionsClient = ctx.actions.getActionsClient(); const soClient = ctx.core.savedObjects.client; - const rulesClient = ctx.alerting.getRulesClient(); + const rulesClient = await ctx.alerting.getRulesClient(); const invocationConfig = { callbacks: [ diff --git a/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/api/util/installation.ts b/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/api/util/installation.ts new file mode 100644 index 0000000000000..ee211e8a935de --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/api/util/installation.ts @@ -0,0 +1,223 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { Logger, SavedObjectsClientContract } from '@kbn/core/server'; +import type { RulesClient } from '@kbn/alerting-plugin/server'; +import { + DEFAULT_TRANSLATION_RISK_SCORE, + DEFAULT_TRANSLATION_SEVERITY, +} from '../../../../../../common/siem_migrations/constants'; +import type { SecuritySolutionApiRequestHandlerContext } from '../../../../..'; +import { createPrebuiltRuleObjectsClient } from '../../../../detection_engine/prebuilt_rules/logic/rule_objects/prebuilt_rule_objects_client'; +import { performTimelinesInstallation } from '../../../../detection_engine/prebuilt_rules/logic/perform_timelines_installation'; +import { createPrebuiltRules } from '../../../../detection_engine/prebuilt_rules/logic/rule_objects/create_prebuilt_rules'; +import type { PrebuiltRuleAsset } from '../../../../detection_engine/prebuilt_rules'; +import { getRuleGroups } from '../../../../detection_engine/prebuilt_rules/model/rule_groups/get_rule_groups'; +import { fetchRuleVersionsTriad } from '../../../../detection_engine/prebuilt_rules/logic/rule_versions/fetch_rule_versions_triad'; +import { createPrebuiltRuleAssetsClient } from '../../../../detection_engine/prebuilt_rules/logic/rule_assets/prebuilt_rule_assets_client'; +import type { IDetectionRulesClient } from '../../../../detection_engine/rule_management/logic/detection_rules_client/detection_rules_client_interface'; +import type { RuleCreateProps } from '../../../../../../common/api/detection_engine'; +import type { UpdateRuleMigrationInput } from '../../data/rule_migrations_data_rules_client'; +import type { StoredRuleMigration } from '../../types'; + +const installPrebuiltRules = async ( + rulesToInstall: StoredRuleMigration[], + securitySolutionContext: SecuritySolutionApiRequestHandlerContext, + rulesClient: RulesClient, + savedObjectsClient: SavedObjectsClientContract, + detectionRulesClient: IDetectionRulesClient +): Promise => { + const ruleAssetsClient = createPrebuiltRuleAssetsClient(savedObjectsClient); + const ruleObjectsClient = createPrebuiltRuleObjectsClient(rulesClient); + const ruleVersionsMap = await fetchRuleVersionsTriad({ + ruleAssetsClient, + ruleObjectsClient, + }); + const { currentRules, installableRules } = getRuleGroups(ruleVersionsMap); + + const rulesToUpdate: UpdateRuleMigrationInput[] = []; + const assetsToInstall: PrebuiltRuleAsset[] = []; + rulesToInstall.forEach((ruleToInstall) => { + // If prebuilt rule has already been install, then just update migration rule with the installed rule id + const installedRule = currentRules.find( + (rule) => rule.rule_id === ruleToInstall.elastic_rule?.prebuilt_rule_id + ); + if (installedRule) { + rulesToUpdate.push({ + id: ruleToInstall.id, + elastic_rule: { + id: installedRule.id, + }, + }); + return; + } + + // If prebuilt rule is not installed, then keep reference to install it + const installableRule = installableRules.find( + (rule) => rule.rule_id === ruleToInstall.elastic_rule?.prebuilt_rule_id + ); + if (installableRule) { + assetsToInstall.push(installableRule); + } + }); + + // Filter out any duplicates which can occur when multiple translated rules matched the same prebuilt rule + const filteredAssetsToInstall = assetsToInstall.filter( + (value, index, self) => index === self.findIndex((rule) => rule.rule_id === value.rule_id) + ); + + // TODO: we need to do an error handling which can happen during the rule installation + const { results: installedRules } = await createPrebuiltRules( + detectionRulesClient, + filteredAssetsToInstall + ); + await performTimelinesInstallation(securitySolutionContext); + + installedRules.forEach((installedRule) => { + const rules = rulesToInstall.filter( + (rule) => rule.elastic_rule?.prebuilt_rule_id === installedRule.result.rule_id + ); + rules.forEach((prebuiltRule) => { + rulesToUpdate.push({ + id: prebuiltRule.id, + elastic_rule: { + id: installedRule.result.id, + }, + }); + }); + }); + + return rulesToUpdate; +}; + +const installCustomRules = async ( + rulesToInstall: StoredRuleMigration[], + detectionRulesClient: IDetectionRulesClient, + logger: Logger +): Promise => { + const rulesToUpdate: UpdateRuleMigrationInput[] = []; + await Promise.all( + rulesToInstall.map(async (rule) => { + if (!rule.elastic_rule?.query || !rule.elastic_rule?.description) { + return; + } + try { + const payloadRule: RuleCreateProps = { + type: 'esql', + language: 'esql', + query: rule.elastic_rule.query, + name: rule.elastic_rule.title, + description: rule.elastic_rule.description, + severity: DEFAULT_TRANSLATION_SEVERITY, + risk_score: DEFAULT_TRANSLATION_RISK_SCORE, + }; + const createdRule = await detectionRulesClient.createCustomRule({ + params: payloadRule, + }); + rulesToUpdate.push({ + id: rule.id, + elastic_rule: { + id: createdRule.id, + }, + }); + } catch (err) { + // TODO: we need to do an error handling which can happen during the rule creation + logger.debug(`Could not create a rule because of error: ${JSON.stringify(err)}`); + } + }) + ); + return rulesToUpdate; +}; + +interface InstallTranslatedProps { + /** + * The migration id + */ + migrationId: string; + + /** + * If specified, then installable translated rules in theThe list will be installed, + * otherwise all installable translated rules will be installed. + */ + ids?: string[]; + + /** + * The security solution context + */ + securitySolutionContext: SecuritySolutionApiRequestHandlerContext; + + /** + * The rules client to create rules + */ + rulesClient: RulesClient; + + /** + * The saved objects client + */ + savedObjectsClient: SavedObjectsClientContract; + + /** + * The logger + */ + logger: Logger; +} + +export const installTranslated = async ({ + migrationId, + ids, + securitySolutionContext, + rulesClient, + savedObjectsClient, + logger, +}: InstallTranslatedProps) => { + const detectionRulesClient = securitySolutionContext.getDetectionRulesClient(); + const ruleMigrationsClient = securitySolutionContext.getSiemRuleMigrationsClient(); + + const rulesToInstall = await ruleMigrationsClient.data.rules.get({ + migrationId, + ids, + installable: true, + }); + + const { customRulesToInstall, prebuiltRulesToInstall } = rulesToInstall.reduce( + (acc, item) => { + if (item.elastic_rule?.prebuilt_rule_id) { + acc.prebuiltRulesToInstall.push(item); + } else { + acc.customRulesToInstall.push(item); + } + return acc; + }, + { customRulesToInstall: [], prebuiltRulesToInstall: [] } as { + customRulesToInstall: StoredRuleMigration[]; + prebuiltRulesToInstall: StoredRuleMigration[]; + } + ); + + const updatedPrebuiltRules = await installPrebuiltRules( + prebuiltRulesToInstall, + securitySolutionContext, + rulesClient, + savedObjectsClient, + detectionRulesClient + ); + + const updatedCustomRules = await installCustomRules( + customRulesToInstall, + detectionRulesClient, + logger + ); + + const rulesToUpdate: UpdateRuleMigrationInput[] = [ + ...updatedPrebuiltRules, + ...updatedCustomRules, + ]; + + if (rulesToUpdate.length) { + await ruleMigrationsClient.data.rules.update(rulesToUpdate); + } +}; diff --git a/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/data/rule_migrations_data_resources_client.ts b/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/data/rule_migrations_data_resources_client.ts index 66b463da79cc3..888a41aca944c 100644 --- a/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/data/rule_migrations_data_resources_client.ts +++ b/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/data/rule_migrations_data_resources_client.ts @@ -14,23 +14,35 @@ import type { import type { StoredRuleMigrationResource } from '../types'; import { RuleMigrationsDataBaseClient } from './rule_migrations_data_base_client'; +export type CreateRuleMigrationResourceInput = Omit; + /* BULK_MAX_SIZE defines the number to break down the bulk operations by. * The 500 number was chosen as a reasonable number to avoid large payloads. It can be adjusted if needed. */ const BULK_MAX_SIZE = 500 as const; export class RuleMigrationsDataResourcesClient extends RuleMigrationsDataBaseClient { - public async upsert(resources: RuleMigrationResource[]): Promise { + public async upsert(resources: CreateRuleMigrationResourceInput[]): Promise { const index = await this.getIndexName(); - let resourcesSlice: RuleMigrationResource[]; + let resourcesSlice: CreateRuleMigrationResourceInput[]; + + const createdAt = new Date().toISOString(); while ((resourcesSlice = resources.splice(0, BULK_MAX_SIZE)).length > 0) { await this.esClient .bulk({ refresh: 'wait_for', operations: resourcesSlice.flatMap((resource) => [ { update: { _id: this.createId(resource), _index: index } }, - { doc: resource, doc_as_upsert: true }, + { + doc: { + ...resource, + '@timestamp': createdAt, + updated_by: this.username, + updated_at: createdAt, + }, + doc_as_upsert: true, + }, ]), }) .catch((error) => { @@ -65,7 +77,7 @@ export class RuleMigrationsDataResourcesClient extends RuleMigrationsDataBaseCli }); } - private createId(resource: RuleMigrationResource): string { + private createId(resource: CreateRuleMigrationResourceInput): string { const key = `${resource.migration_id}-${resource.type}-${resource.name}`; return sha256.create().update(key).hex(); } diff --git a/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/data/rule_migrations_data_rules_client.ts b/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/data/rule_migrations_data_rules_client.ts index 06e257b9862c5..0a82e2c311906 100644 --- a/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/data/rule_migrations_data_rules_client.ts +++ b/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/data/rule_migrations_data_rules_client.ts @@ -34,6 +34,13 @@ export type UpdateRuleMigrationInput = { elastic_rule?: Partial } & export type RuleMigrationDataStats = Omit; export type RuleMigrationAllDataStats = RuleMigrationDataStats[]; +export interface RuleMigrationFilterOptions { + migrationId: string; + status?: SiemMigrationStatus | SiemMigrationStatus[]; + ids?: string[]; + installable?: boolean; +} + /* BULK_MAX_SIZE defines the number to break down the bulk operations by. * The 500 number was chosen as a reasonable number to avoid large payloads. It can be adjusted if needed. */ @@ -101,9 +108,9 @@ export class RuleMigrationsDataRulesClient extends RuleMigrationsDataBaseClient } /** Retrieves an array of rule documents of a specific migrations */ - async get(migrationId: string): Promise { + async get(filters: RuleMigrationFilterOptions): Promise { const index = await this.getIndexName(); - const query = this.getFilterQuery(migrationId); + const query = this.getFilterQuery(filters); const storedRuleMigrations = await this.esClient .search({ index, query, sort: '_doc' }) @@ -123,7 +130,7 @@ export class RuleMigrationsDataRulesClient extends RuleMigrationsDataBaseClient */ async takePending(migrationId: string, size: number): Promise { const index = await this.getIndexName(); - const query = this.getFilterQuery(migrationId, SiemMigrationStatus.PENDING); + const query = this.getFilterQuery({ migrationId, status: SiemMigrationStatus.PENDING }); const storedRuleMigrations = await this.esClient .search({ index, query, sort: '_doc', size }) @@ -202,7 +209,7 @@ export class RuleMigrationsDataRulesClient extends RuleMigrationsDataBaseClient { refresh = false }: { refresh?: boolean } = {} ): Promise { const index = await this.getIndexName(); - const query = this.getFilterQuery(migrationId, statusToQuery); + const query = this.getFilterQuery({ migrationId, status: statusToQuery }); const script = { source: `ctx._source['status'] = '${statusToUpdate}'` }; await this.esClient.updateByQuery({ index, query, script, refresh }).catch((error) => { this.logger.error(`Error updating rule migrations status: ${error.message}`); @@ -213,7 +220,7 @@ export class RuleMigrationsDataRulesClient extends RuleMigrationsDataBaseClient /** Retrieves the stats for the rule migrations with the provided id */ async getStats(migrationId: string): Promise { const index = await this.getIndexName(); - const query = this.getFilterQuery(migrationId); + const query = this.getFilterQuery({ migrationId }); const aggregations = { pending: { filter: { term: { status: SiemMigrationStatus.PENDING } } }, processing: { filter: { term: { status: SiemMigrationStatus.PROCESSING } } }, @@ -283,10 +290,12 @@ export class RuleMigrationsDataRulesClient extends RuleMigrationsDataBaseClient })); } - private getFilterQuery( - migrationId: string, - status?: SiemMigrationStatus | SiemMigrationStatus[] - ): QueryDslQueryContainer { + private getFilterQuery({ + migrationId, + status, + ids, + installable, + }: RuleMigrationFilterOptions): QueryDslQueryContainer { const filter: QueryDslQueryContainer[] = [{ term: { migration_id: migrationId } }]; if (status) { if (Array.isArray(status)) { @@ -295,6 +304,20 @@ export class RuleMigrationsDataRulesClient extends RuleMigrationsDataBaseClient filter.push({ term: { status } }); } } + if (ids) { + filter.push({ terms: { _id: ids } }); + } + if (installable) { + filter.push( + { term: { translation_result: 'full' } }, + { + nested: { + path: 'elastic_rule', + query: { bool: { must_not: { exists: { field: 'elastic_rule.id' } } } }, + }, + } + ); + } return { bool: { filter } }; } } diff --git a/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/task/agent/graph.test.ts b/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/task/agent/graph.test.ts new file mode 100644 index 0000000000000..eece827726a33 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/task/agent/graph.test.ts @@ -0,0 +1,47 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { InferenceClient } from '@kbn/inference-plugin/server'; +import type { + ActionsClientChatOpenAI, + ActionsClientSimpleChatModel, +} from '@kbn/langchain/server/language_models'; +import { loggerMock } from '@kbn/logging-mocks'; +import { FakeLLM } from '@langchain/core/utils/testing'; +import type { IntegrationRetriever } from '../util/integration_retriever'; +import type { PrebuiltRulesMapByName } from '../util/prebuilt_rules'; +import type { RuleResourceRetriever } from '../util/rule_resource_retriever'; +import { getRuleMigrationAgent } from './graph'; + +describe('getRuleMigrationAgent', () => { + const model = new FakeLLM({ + response: JSON.stringify({}, null, 2), + }) as unknown as ActionsClientChatOpenAI | ActionsClientSimpleChatModel; + + const inferenceClient = {} as InferenceClient; + const connectorId = 'draw_graphs'; + const prebuiltRulesMap = {} as PrebuiltRulesMapByName; + const resourceRetriever = {} as RuleResourceRetriever; + const integrationRetriever = {} as IntegrationRetriever; + const logger = loggerMock.create(); + + it('Ensures that the graph compiles', async () => { + try { + await getRuleMigrationAgent({ + model, + inferenceClient, + prebuiltRulesMap, + resourceRetriever, + integrationRetriever, + connectorId, + logger, + }); + } catch (error) { + throw Error(`getRuleMigrationAgent threw an error: ${error}`); + } + }); +}); diff --git a/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/task/agent/graph.ts b/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/task/agent/graph.ts index 078b3ffdcdcb4..4ce5e2d87a3fe 100644 --- a/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/task/agent/graph.ts +++ b/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/task/agent/graph.ts @@ -30,16 +30,16 @@ export function getRuleMigrationAgent({ logger, }); - const translateRuleGraph = new StateGraph(migrateRuleState) + const siemMigrationAgentGraph = new StateGraph(migrateRuleState) // Nodes .addNode('matchPrebuiltRule', matchPrebuiltRuleNode) - .addNode('translation', translationSubGraph) + .addNode('translationSubGraph', translationSubGraph) // Edges .addEdge(START, 'matchPrebuiltRule') .addConditionalEdges('matchPrebuiltRule', matchedPrebuiltRuleConditional) - .addEdge('translation', END); + .addEdge('translationSubGraph', END); - const graph = translateRuleGraph.compile(); + const graph = siemMigrationAgentGraph.compile(); graph.name = 'Rule Migration Graph'; // Customizes the name displayed in LangSmith return graph; } @@ -48,5 +48,5 @@ const matchedPrebuiltRuleConditional = (state: MigrateRuleState) => { if (state.elastic_rule?.prebuilt_rule_id) { return END; } - return 'translation'; + return 'translationSubGraph'; }; diff --git a/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/task/agent/nodes/match_prebuilt_rule/match_prebuilt_rule.ts b/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/task/agent/nodes/match_prebuilt_rule/match_prebuilt_rule.ts index 056b41bf088a0..8f0460165f290 100644 --- a/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/task/agent/nodes/match_prebuilt_rule/match_prebuilt_rule.ts +++ b/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/task/agent/nodes/match_prebuilt_rule/match_prebuilt_rule.ts @@ -6,6 +6,7 @@ */ import { JsonOutputParser } from '@langchain/core/output_parsers'; +import { SiemMigrationRuleTranslationResult } from '../../../../../../../../common/siem_migrations/constants'; import type { ChatModel } from '../../../util/actions_client_chat'; import { filterPrebuiltRules, type PrebuiltRulesMapByName } from '../../../util/prebuilt_rules'; import type { GraphNode } from '../../types'; @@ -51,6 +52,7 @@ export const getMatchPrebuiltRuleNode = prebuilt_rule_id: result.rule.rule_id, id: result.installedRuleId, }, + translation_result: SiemMigrationRuleTranslationResult.FULL, }; } } diff --git a/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/task/agent/sub_graphs/translate_rule/graph.ts b/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/task/agent/sub_graphs/translate_rule/graph.ts index f986098e9deb0..32f41e54619be 100644 --- a/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/task/agent/sub_graphs/translate_rule/graph.ts +++ b/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/task/agent/sub_graphs/translate_rule/graph.ts @@ -6,11 +6,18 @@ */ import { END, START, StateGraph } from '@langchain/langgraph'; +import { isEmpty } from 'lodash/fp'; +import { SiemMigrationRuleTranslationResult } from '../../../../../../../../common/siem_migrations/constants'; +import { getFixQueryErrorsNode } from './nodes/fix_query_errors'; import { getProcessQueryNode } from './nodes/process_query'; import { getRetrieveIntegrationsNode } from './nodes/retrieve_integrations'; import { getTranslateRuleNode } from './nodes/translate_rule'; +import { getValidationNode } from './nodes/validation'; import { translateRuleState } from './state'; -import type { TranslateRuleGraphParams } from './types'; +import type { TranslateRuleGraphParams, TranslateRuleState } from './types'; + +// How many times we will try to self-heal when validation fails, to prevent infinite graph recursions +const MAX_VALIDATION_ITERATIONS = 3; export function getTranslateRuleGraph({ model, @@ -35,19 +42,37 @@ export function getTranslateRuleGraph({ model, integrationRetriever, }); + const validationNode = getValidationNode({ logger }); + const fixQueryErrorsNode = getFixQueryErrorsNode({ inferenceClient, connectorId, logger }); const translateRuleGraph = new StateGraph(translateRuleState) // Nodes .addNode('processQuery', processQueryNode) .addNode('retrieveIntegrations', retrieveIntegrationsNode) .addNode('translateRule', translateRuleNode) + .addNode('validation', validationNode) + .addNode('fixQueryErrors', fixQueryErrorsNode) // Edges .addEdge(START, 'processQuery') .addEdge('processQuery', 'retrieveIntegrations') .addEdge('retrieveIntegrations', 'translateRule') - .addEdge('translateRule', END); + .addEdge('translateRule', 'validation') + .addEdge('fixQueryErrors', 'validation') + .addConditionalEdges('validation', validationRouter); const graph = translateRuleGraph.compile(); graph.name = 'Translate Rule Graph'; return graph; } + +const validationRouter = (state: TranslateRuleState) => { + if ( + state.validation_errors.iterations <= MAX_VALIDATION_ITERATIONS && + state.translation_result === SiemMigrationRuleTranslationResult.FULL + ) { + if (!isEmpty(state.validation_errors?.esql_errors)) { + return 'fixQueryErrors'; + } + } + return END; +}; diff --git a/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/task/agent/sub_graphs/translate_rule/nodes/fix_query_errors/fix_query_errors.ts b/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/task/agent/sub_graphs/translate_rule/nodes/fix_query_errors/fix_query_errors.ts new file mode 100644 index 0000000000000..a21aceee70f95 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/task/agent/sub_graphs/translate_rule/nodes/fix_query_errors/fix_query_errors.ts @@ -0,0 +1,38 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { Logger } from '@kbn/core/server'; +import type { InferenceClient } from '@kbn/inference-plugin/server'; +import { getEsqlKnowledgeBase } from '../../../../../util/esql_knowledge_base_caller'; +import type { GraphNode } from '../../types'; +import { RESOLVE_ESQL_ERRORS_TEMPLATE } from './prompts'; + +interface GetFixQueryErrorsNodeParams { + inferenceClient: InferenceClient; + connectorId: string; + logger: Logger; +} + +export const getFixQueryErrorsNode = ({ + inferenceClient, + connectorId, + logger, +}: GetFixQueryErrorsNodeParams): GraphNode => { + const esqlKnowledgeBaseCaller = getEsqlKnowledgeBase({ inferenceClient, connectorId, logger }); + return async (state) => { + const rule = state.elastic_rule; + const prompt = await RESOLVE_ESQL_ERRORS_TEMPLATE.format({ + esql_errors: state.validation_errors.esql_errors, + esql_query: rule.query, + }); + const response = await esqlKnowledgeBaseCaller(prompt); + + const esqlQuery = response.match(/```esql\n([\s\S]*?)\n```/)?.[1] ?? ''; + rule.query = esqlQuery; + return { elastic_rule: rule }; + }; +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/error_connecting/index.ts b/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/task/agent/sub_graphs/translate_rule/nodes/fix_query_errors/index.ts similarity index 80% rename from x-pack/plugins/enterprise_search/public/applications/app_search/components/error_connecting/index.ts rename to x-pack/plugins/security_solution/server/lib/siem_migrations/rules/task/agent/sub_graphs/translate_rule/nodes/fix_query_errors/index.ts index 59ac4e0e37efe..a805331675389 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/error_connecting/index.ts +++ b/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/task/agent/sub_graphs/translate_rule/nodes/fix_query_errors/index.ts @@ -4,5 +4,4 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ - -export { ErrorConnecting } from './error_connecting'; +export { getFixQueryErrorsNode } from './fix_query_errors'; diff --git a/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/task/agent/sub_graphs/translate_rule/nodes/fix_query_errors/prompts.ts b/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/task/agent/sub_graphs/translate_rule/nodes/fix_query_errors/prompts.ts new file mode 100644 index 0000000000000..ca5fe67097d12 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/task/agent/sub_graphs/translate_rule/nodes/fix_query_errors/prompts.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 { ChatPromptTemplate } from '@langchain/core/prompts'; + +export const RESOLVE_ESQL_ERRORS_TEMPLATE = + ChatPromptTemplate.fromTemplate(`You are a helpful cybersecurity (SIEM) expert agent. Your task is to resolve the errors in the Elasticsearch Query Language (ES|QL) query provided by the user. + +Below is the relevant errors related to the ES|SQL query: + + + +{esql_errors} + + +{esql_query} + + + + +- You will be provided with the currentl ES|QL query and its related errors. +- Try to resolve the errors in the ES|QL query as best as you can to make it work. +- You must respond only with the modified query inside a \`\`\`esql code block, nothing else similar to the example response below. + + + +A: Please find the modified ES|QL query below: +\`\`\`esql +FROM logs-endpoint.events.process-* +| WHERE process.executable LIKE \"%chown root%\" +| STATS count = COUNT(*), firstTime = MIN(@timestamp), lastTime = MAX(@timestamp) BY process.executable, + process.command_line, + host.name +| EVAL firstTime = TO_DATETIME(firstTime), lastTime = TO_DATETIME(lastTime) +\`\`\` + + +`); diff --git a/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/task/agent/sub_graphs/translate_rule/nodes/process_query/process_query.ts b/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/task/agent/sub_graphs/translate_rule/nodes/process_query/process_query.ts index 97d4168f1283e..ae0e93ee0c4bb 100644 --- a/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/task/agent/sub_graphs/translate_rule/nodes/process_query/process_query.ts +++ b/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/task/agent/sub_graphs/translate_rule/nodes/process_query/process_query.ts @@ -29,11 +29,15 @@ export const getProcessQueryNode = ({ const replaceQueryResourcePrompt = REPLACE_QUERY_RESOURCE_PROMPT.pipe(model).pipe(replaceQueryParser); const resourceContext = getResourcesContext(resources); - query = await replaceQueryResourcePrompt.invoke({ + const response = await replaceQueryResourcePrompt.invoke({ query: state.original_rule.query, macros: resourceContext.macros, lookup_tables: resourceContext.lists, }); + const splQuery = response.match(/```spl\n([\s\S]*?)\n```/)?.[1] ?? ''; + if (splQuery) { + query = splQuery; + } } return { inline_query: query }; }; diff --git a/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/task/agent/sub_graphs/translate_rule/nodes/process_query/prompts.ts b/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/task/agent/sub_graphs/translate_rule/nodes/process_query/prompts.ts index f074da6b27d1a..b4c6b0e74aaa9 100644 --- a/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/task/agent/sub_graphs/translate_rule/nodes/process_query/prompts.ts +++ b/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/task/agent/sub_graphs/translate_rule/nodes/process_query/prompts.ts @@ -140,8 +140,14 @@ Divide the query up into separate section and go through each section one at a t A: Please find the modified SPL query below: -\`\`\`json -{{"match": "Linux User Account Creation"}} +\`\`\`spl +sourcetype="linux:audit" \`linux_auditd_normalized_proctitle_process\` +| rename host as dest +| where LIKE (process_exec, "%chown root%") +| stats count min(_time) as firstTime max(_time) as lastTime by process_exec proctitle normalized_proctitle_delimiter dest +| convert timeformat="%Y-%m-%dT%H:%M:%S" ctime(firstTime) +| convert timeformat="%Y-%m-%dT%H:%M:%S" ctime(lastTime) +| search * \`\`\` diff --git a/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/task/agent/sub_graphs/translate_rule/nodes/translate_rule/cim_ecs_map.ts b/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/task/agent/sub_graphs/translate_rule/nodes/translate_rule/cim_ecs_map.ts new file mode 100644 index 0000000000000..3bafaf2fc6518 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/task/agent/sub_graphs/translate_rule/nodes/translate_rule/cim_ecs_map.ts @@ -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. + */ + +export const SIEM_RULE_MIGRATION_CIM_ECS_MAP = ` +datamodel,object,source_field,ecs_field,data_type +Application_State,All_Application_State,dest,service.node.name,string +Application_State,All_Application_State,process,process.title,string +Application_State,All_Application_State,user,user.name,string +Application_State,Ports,dest_port,destination.port,number +Application_State,Ports,transport,network.transport,string +Application_State,Ports,transport_dest_port,destination.port,string +Application_State,Services,service,service.name,string +Application_State,Services,service_id,service.id,string +Application_State,Services,status,service.state,string +Authentication,Authentication,action,event.action,string +Authentication,Authentication,app,process.name,string +Authentication,Authentication,dest,host.name,string +Authentication,Authentication,duration,event.duration,number +Authentication,Authentication,signature,event.code,string +Authentication,Authentication,signature_id,event.reason,string +Authentication,Authentication,src,source.address,string +Authentication,Authentication,src_nt_domain,source.domain,string +Authentication,Authentication,user,user.name,string +Certificates,All_Certificates,dest_port,destination.port,number +Certificates,All_Certificates,duration,event.duration,number +Certificates,All_Certificates,src,source.address,string +Certificates,All_Certificates,src_port,source.port,number +Certificates,All_Certificates,transport,network.protocol,string +Certificates,SSL,ssl_end_time,tls.server.not_after,time +Certificates,SSL,ssl_hash,tls.server.hash,string +Certificates,SSL,ssl_issuer_common_name,tls.server.issuer,string +Certificates,SSL,ssl_issuer_locality,x509.issuer.locality,string +Certificates,SSL,ssl_issuer_organization,x509.issuer.organization,string +Certificates,SSL,ssl_issuer_state,x509.issuer.state_or_province,string +Certificates,SSL,ssl_issuer_unit,x509.issuer.organizational_unit,string +Certificates,SSL,ssl_publickey_algorithm,x509.public_key_algorithm,string +Certificates,SSL,ssl_serial,x509.serial_number,string +Certificates,SSL,ssl_signature_algorithm,x509.signature_algorithm,string +Certificates,SSL,ssl_start_time,x509.not_before,time +Certificates,SSL,ssl_subject,x509.subject.distinguished_name,string +Certificates,SSL,ssl_subject_common_name,x509.subject.common_name,string +Certificates,SSL,ssl_subject_locality,x509.subject.locality,string +Certificates,SSL,ssl_subject_organization,x509.subject.organization,string +Certificates,SSL,ssl_subject_state,x509.subject.state_or_province,string +Certificates,SSL,ssl_subject_unit,x509.subject.organizational_unit,string +Certificates,SSL,ssl_version,tls.version,string +Change,All_Changes,action,event.action,string +Change,Account_Management,dest_nt_domain,destination.domain,string +Change,Account_Management,src_nt_domain,source.domain,string +Change,Account_Management,src_user,source.user,string +Intrusion_Detection,IDS_Attacks,action,event.action,string +Intrusion_Detection,IDS_Attacks,dest,destination.address,string +Intrusion_Detection,IDS_Attacks,dest_port,destination.port,number +Intrusion_Detection,IDS_Attacks,dvc,observer.hostname,string +Intrusion_Detection,IDS_Attacks,severity,event.severity,string +Intrusion_Detection,IDS_Attacks,src,source.ip,string +Intrusion_Detection,IDS_Attacks,user,source.user,string +JVM,OS,os,host.os.name,string +JVM,OS,os_architecture,host.architecture,string +JVM,OS,os_version,host.os.version,string +Malware,Malware_Attacks,action,event.action,string +Malware,Malware_Attacks,date,event.created,string +Malware,Malware_Attacks,dest,host.hostname,string +Malware,Malware_Attacks,file_hash,file.hash.*,string +Malware,Malware_Attacks,file_name,file.name,string +Malware,Malware_Attacks,file_path,file.path,string +Malware,Malware_Attacks,Sender,source.user.email,string +Malware,Malware_Attacks,src,source.ip,string +Malware,Malware_Attacks,user,related.user,string +Malware,Malware_Attacks,url,rule.reference,string +Network_Resolution,DNS,answer,dns.answers,string +Network_Resolution,DNS,dest,destination.address,string +Network_Resolution,DNS,dest_port,destination.port,number +Network_Resolution,DNS,duration,event.duration,number +Network_Resolution,DNS,message_type,dns.type,string +Network_Resolution,DNS,name,dns.question.name,string +Network_Resolution,DNS,query,dns.question.name,string +Network_Resolution,DNS,query_type,dns.op_code,string +Network_Resolution,DNS,record_type,dns.question.type,string +Network_Resolution,DNS,reply_code,dns.response_code,string +Network_Resolution,DNS,reply_code_id,dns.id,number +Network_Resolution,DNS,response_time,event.duration,number +Network_Resolution,DNS,src,source.address,string +Network_Resolution,DNS,src_port,source.port,number +Network_Resolution,DNS,transaction_id,dns.id,number +Network_Resolution,DNS,transport,network.transport,string +Network_Resolution,DNS,ttl,dns.answers.ttl,number +Network_Sessions,All_Sessions,action,event.action,string +Network_Sessions,All_Sessions,dest_ip,destination.ip,string +Network_Sessions,All_Sessions,dest_mac,destination.mac,string +Network_Sessions,All_Sessions,duration,event.duration,number +Network_Sessions,All_Sessions,src_dns,source.registered_domain,string +Network_Sessions,All_Sessions,src_ip,source.ip,string +Network_Sessions,All_Sessions,src_mac,source.mac,string +Network_Sessions,All_Sessions,user,user.name,string +Network_Traffic,All_Traffic,action,event.action,string +Network_Traffic,All_Traffic,app,network.protocol,string +Network_Traffic,All_Traffic,bytes,network.bytes,number +Network_Traffic,All_Traffic,dest,destination.ip,string +Network_Traffic,All_Traffic,dest_ip,destination.ip,string +Network_Traffic,All_Traffic,dest_mac,destination.mac,string +Network_Traffic,All_Traffic,dest_port,destination.port,number +Network_Traffic,All_Traffic,dest_translated_ip,destination.nat.ip,string +Network_Traffic,All_Traffic,dest_translated_port,destination.nat.port,number +Network_Traffic,All_Traffic,direction,network.direction,string +Network_Traffic,All_Traffic,duration,event.duration,number +Network_Traffic,All_Traffic,dvc,observer.name,string +Network_Traffic,All_Traffic,dvc_ip,observer.ip,string +Network_Traffic,All_Traffic,dvc_mac,observer.mac,string +Network_Traffic,All_Traffic,dvc_zone,observer.egress.zone,string +Network_Traffic,All_Traffic,packets,network.packets,number +Network_Traffic,All_Traffic,packets_in,source.packets,number +Network_Traffic,All_Traffic,packets_out,destination.packets,number +Network_Traffic,All_Traffic,protocol,network.protocol,string +Network_Traffic,All_Traffic,rule,rule.name,string +Network_Traffic,All_Traffic,src,source.address,string +Network_Traffic,All_Traffic,src_ip,source.ip,string +Network_Traffic,All_Traffic,src_mac,source.mac,string +Network_Traffic,All_Traffic,src_port,source.port,number +Network_Traffic,All_Traffic,src_translated_ip,source.nat.ip,string +Network_Traffic,All_Traffic,src_translated_port,source.nat.port,number +Network_Traffic,All_Traffic,transport,network.transport,string +Network_Traffic,All_Traffic,vlan,vlan.name,string +Vulnerabilities,Vulnerabilities,category,vulnerability.category,string +Vulnerabilities,Vulnerabilities,cve,vulnerability.id,string +Vulnerabilities,Vulnerabilities,cvss,vulnerability.score.base,number +Vulnerabilities,Vulnerabilities,dest,host.name,string +Vulnerabilities,Vulnerabilities,dvc,vulnerability.scanner.vendor,string +Vulnerabilities,Vulnerabilities,severity,vulnerability.severity,string +Vulnerabilities,Vulnerabilities,url,vulnerability.reference,string +Vulnerabilities,Vulnerabilities,user,related.user,string +Vulnerabilities,Vulnerabilities,vendor_product,vulnerability.scanner.vendor,string +Endpoint,Ports,creation_time,@timestamp,timestamp +Endpoint,Ports,dest_port,destination.port,number +Endpoint,Ports,process_id,process.pid,string +Endpoint,Ports,transport,network.transport,string +Endpoint,Ports,transport_dest_port,destination.port,string +Endpoint,Processes,action,event.action,string +Endpoint,Processes,os,os.full,string +Endpoint,Processes,parent_process_exec,process.parent.name,string +Endpoint,Processes,parent_process_id,process.ppid,number +Endpoint,Processes,parent_process_guid,process.parent.entity_id,string +Endpoint,Processes,parent_process_path,process.parent.executable,string +Endpoint,Processes,process_current_directory,process.parent.working_directory, +Endpoint,Processes,process_exec,process.name,string +Endpoint,Processes,process_hash,process.hash.*,string +Endpoint,Processes,process_guid,process.entity_id,string +Endpoint,Processes,process_id,process.pid,number +Endpoint,Processes,process_path,process.executable,string +Endpoint,Processes,user_id,related.user,string +Endpoint,Services,description,service.name,string +Endpoint,Services,process_id,service.id,string +Endpoint,Services,service_dll,dll.name,string +Endpoint,Services,service_dll_path,dll.path,string +Endpoint,Services,service_dll_hash,dll.hash.*,string +Endpoint,Services,service_dll_signature_exists,dll.code_signature.exists,boolean +Endpoint,Services,service_dll_signature_verified,dll.code_signature.valid,boolean +Endpoint,Services,service_exec,service.name,string +Endpoint,Services,service_hash,hash.*,string +Endpoint,Filesystem,file_access_time,file.accessed,timestamp +Endpoint,Filesystem,file_create_time,file.created,timestamp +Endpoint,Filesystem,file_modify_time,file.mtime,timestamp +Endpoint,Filesystem,process_id,process.pid,string +Endpoint,Registry,process_id,process.id,string +Web,Web,action,event.action,string +Web,Web,app,observer.product,string +Web,Web,bytes_in,http.request.bytes,number +Web,Web,bytes_out,http.response.bytes,number +Web,Web,dest,destination.ip,string +Web,Web,duration,event.duration,number +Web,Web,http_method,http.request.method,string +Web,Web,http_referrer,http.request.referrer,string +Web,Web,http_user_agent,user_agent.name,string +Web,Web,status,http.response.status_code,string +Web,Web,url,url.full,string +Web,Web,user,url.username,string +Web,Web,vendor_product,observer.product,string`; diff --git a/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/task/agent/sub_graphs/translate_rule/nodes/translate_rule/prompts.ts b/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/task/agent/sub_graphs/translate_rule/nodes/translate_rule/prompts.ts index 3e77353bba8b1..9749dfd96efba 100644 --- a/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/task/agent/sub_graphs/translate_rule/nodes/translate_rule/prompts.ts +++ b/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/task/agent/sub_graphs/translate_rule/nodes/translate_rule/prompts.ts @@ -5,14 +5,18 @@ * 2.0. */ -import type { TranslateRuleState } from '../../types'; +import { ChatPromptTemplate } from '@langchain/core/prompts'; -export const getEsqlTranslationPrompt = ( - state: TranslateRuleState, - indexPatterns: string -): string => { - return `You are a helpful cybersecurity (SIEM) expert agent. Your task is to migrate "detection rules" from Splunk to Elastic Security. +export const ESQL_TRANSLATION_PROMPT = + ChatPromptTemplate.fromTemplate(`You are a helpful cybersecurity (SIEM) expert agent. Your task is to migrate "detection rules" from Splunk to Elastic Security. Your goal is to translate the SPL query into an equivalent Elastic Security Query Language (ES|QL) query. +Below is the relevant context used when deciding which Elastic Common Schema field to use when translating from Splunk CIM fields: + + + +{field_mapping} + + ## Splunk rule Information provided: - Below you will find Splunk rule information: the title (<>), the description (<<DESCRIPTION>>), and the SPL (Search Processing Language) query (<<SPL_QUERY>>). @@ -22,7 +26,7 @@ Your goal is to translate the SPL query into an equivalent Elastic Security Quer ## Guidelines: - Analyze the SPL query and identify the key components. - Translate the SPL query into an equivalent ES|QL query using ECS (Elastic Common Schema) field names. -- Always start the generated ES|QL query by filtering FROM using these index patterns in the translated query: ${indexPatterns}. +- Always start the generated ES|QL query by filtering FROM using these index patterns in the translated query: {indexPatterns}. - If, in the SPL query, you find a lookup list or macro call, mention it in the summary and add a placeholder in the query with the format [macro:<macro_name>(argumentCount)] or [lookup:<lookup_name>] including the [] keys, - Examples: - \`get_duration(firstDate,secondDate)\` -> [macro:get_duration(2)] @@ -35,15 +39,14 @@ Your goal is to translate the SPL query into an equivalent Elastic Security Quer Find the Splunk rule information below: <<TITLE>> -${state.original_rule.title} +{title} <> <> -${state.original_rule.description} +{description} <> <> -${state.inline_query} +{inline_query} <> -`; -}; +`); diff --git a/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/task/agent/sub_graphs/translate_rule/nodes/translate_rule/translate_rule.ts b/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/task/agent/sub_graphs/translate_rule/nodes/translate_rule/translate_rule.ts index a39e7c10146c0..6ba5edee11b22 100644 --- a/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/task/agent/sub_graphs/translate_rule/nodes/translate_rule/translate_rule.ts +++ b/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/task/agent/sub_graphs/translate_rule/nodes/translate_rule/translate_rule.ts @@ -9,10 +9,11 @@ import type { Logger } from '@kbn/core/server'; import type { InferenceClient } from '@kbn/inference-plugin/server'; import { SiemMigrationRuleTranslationResult } from '../../../../../../../../../../common/siem_migrations/constants'; import type { ChatModel } from '../../../../../util/actions_client_chat'; +import { getEsqlKnowledgeBase } from '../../../../../util/esql_knowledge_base_caller'; import type { RuleResourceRetriever } from '../../../../../util/rule_resource_retriever'; import type { GraphNode } from '../../types'; -import { getEsqlKnowledgeBase } from './esql_knowledge_base_caller'; -import { getEsqlTranslationPrompt } from './prompts'; +import { SIEM_RULE_MIGRATION_CIM_ECS_MAP } from './cim_ecs_map'; +import { ESQL_TRANSLATION_PROMPT } from './prompts'; interface GetTranslateRuleNodeParams { model: ChatModel; @@ -29,12 +30,20 @@ export const getTranslateRuleNode = ({ }: GetTranslateRuleNodeParams): GraphNode => { const esqlKnowledgeBaseCaller = getEsqlKnowledgeBase({ inferenceClient, connectorId, logger }); return async (state) => { - const indexPatterns = state.integrations.flatMap((integration) => - integration.data_streams.map((dataStream) => dataStream.index_pattern) - ); + const indexPatterns = state.integrations + .flatMap((integration) => + integration.data_streams.map((dataStream) => dataStream.index_pattern) + ) + .join(','); const integrationIds = state.integrations.map((integration) => integration.id); - const prompt = getEsqlTranslationPrompt(state, indexPatterns.join(',')); + const prompt = await ESQL_TRANSLATION_PROMPT.format({ + title: state.original_rule.title, + description: state.original_rule.description, + field_mapping: SIEM_RULE_MIGRATION_CIM_ECS_MAP, + inline_query: state.inline_query, + indexPatterns, + }); const response = await esqlKnowledgeBaseCaller(prompt); const esqlQuery = response.match(/```esql\n([\s\S]*?)\n```/)?.[1] ?? ''; diff --git a/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/task/agent/sub_graphs/translate_rule/nodes/validation/esql_query.ts b/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/task/agent/sub_graphs/translate_rule/nodes/validation/esql_query.ts new file mode 100644 index 0000000000000..a8c1d6acff408 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/task/agent/sub_graphs/translate_rule/nodes/validation/esql_query.ts @@ -0,0 +1,62 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { ESQLAstQueryExpression, ESQLCommandOption, EditorError } from '@kbn/esql-ast'; +import { parse } from '@kbn/esql-ast'; +import { isColumnItem, isOptionItem } from '@kbn/esql-validation-autocomplete'; +import { isAggregatingQuery } from '@kbn/securitysolution-utils'; + +interface ParseEsqlQueryResult { + errors: EditorError[]; + isEsqlQueryAggregating: boolean; + hasMetadataOperator: boolean; +} + +function computeHasMetadataOperator(astExpression: ESQLAstQueryExpression): boolean { + // Check whether the `from` command has `metadata` operator + const metadataOption = getMetadataOption(astExpression); + if (!metadataOption) { + return false; + } + + // Check whether the `metadata` operator has `_id` argument + const idColumnItem = metadataOption.args.find( + (fromArg) => isColumnItem(fromArg) && fromArg.name === '_id' + ); + if (!idColumnItem) { + return false; + } + + return true; +} + +function getMetadataOption(astExpression: ESQLAstQueryExpression): ESQLCommandOption | undefined { + const fromCommand = astExpression.commands.find((x) => x.name === 'from'); + + if (!fromCommand?.args) { + return undefined; + } + + // Check whether the `from` command has `metadata` operator + for (const fromArg of fromCommand.args) { + if (isOptionItem(fromArg) && fromArg.name === 'metadata') { + return fromArg; + } + } + + return undefined; +} + +export const parseEsqlQuery = (query: string): ParseEsqlQueryResult => { + const { root, errors } = parse(query); + const isEsqlQueryAggregating = isAggregatingQuery(root); + return { + errors, + isEsqlQueryAggregating, + hasMetadataOperator: computeHasMetadataOperator(root), + }; +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/error_state/index.ts b/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/task/agent/sub_graphs/translate_rule/nodes/validation/index.ts similarity index 83% rename from x-pack/plugins/enterprise_search/public/applications/workplace_search/views/error_state/index.ts rename to x-pack/plugins/security_solution/server/lib/siem_migrations/rules/task/agent/sub_graphs/translate_rule/nodes/validation/index.ts index 9e27852336849..a8c0f55191e42 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/error_state/index.ts +++ b/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/task/agent/sub_graphs/translate_rule/nodes/validation/index.ts @@ -4,5 +4,4 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ - -export { ErrorState } from './error_state'; +export { getValidationNode } from './validation'; diff --git a/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/task/agent/sub_graphs/translate_rule/nodes/validation/validation.ts b/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/task/agent/sub_graphs/translate_rule/nodes/validation/validation.ts new file mode 100644 index 0000000000000..272aedfe4793d --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/task/agent/sub_graphs/translate_rule/nodes/validation/validation.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 { Logger } from '@kbn/core/server'; +import { isEmpty } from 'lodash/fp'; +import type { GraphNode } from '../../types'; +import { parseEsqlQuery } from './esql_query'; + +interface GetValidationNodeParams { + logger: Logger; +} + +/** + * This node runs all validation steps, and will redirect to the END of the graph if no errors are found. + * Any new validation steps should be added here. + */ +export const getValidationNode = ({ logger }: GetValidationNodeParams): GraphNode => { + return async (state) => { + const query = state.elastic_rule.query; + + // We want to prevent infinite loops, so we increment the iterations counter for each validation run. + const currentIteration = ++state.validation_errors.iterations; + let esqlErrors: string = ''; + if (!isEmpty(query)) { + const { errors, isEsqlQueryAggregating, hasMetadataOperator } = parseEsqlQuery(query); + if (!isEmpty(errors)) { + esqlErrors = JSON.stringify(errors); + } else if (!isEsqlQueryAggregating && !hasMetadataOperator) { + esqlErrors = + 'Queries that don’t use the STATS...BY function (non-aggregating queries) must include the "metadata _id, _version, _index" operator after the source command. For example: FROM logs* metadata _id, _version, _index.'; + } + } + if (esqlErrors) { + logger.debug(`ESQL query validation failed: ${esqlErrors}`); + } + + return { validation_errors: { iterations: currentIteration, esql_errors: esqlErrors } }; + }; +}; diff --git a/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/task/agent/sub_graphs/translate_rule/state.ts b/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/task/agent/sub_graphs/translate_rule/state.ts index 8c8e9780aedf8..391d7a54f9ea8 100644 --- a/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/task/agent/sub_graphs/translate_rule/state.ts +++ b/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/task/agent/sub_graphs/translate_rule/state.ts @@ -14,6 +14,7 @@ import type { RuleMigration, } from '../../../../../../../../common/siem_migrations/model/rule_migration.gen'; import type { Integration } from '../../../../types'; +import type { TranslateRuleValidationErrors } from './types'; export const translateRuleState = Annotation.Root({ messages: Annotation({ @@ -33,6 +34,10 @@ export const translateRuleState = Annotation.Root({ reducer: (state, action) => ({ ...state, ...action }), default: () => ({} as ElasticRule), }), + validation_errors: Annotation({ + reducer: (current, value) => value ?? current, + default: () => ({ iterations: 0 } as TranslateRuleValidationErrors), + }), translation_result: Annotation({ reducer: (current, value) => value ?? current, default: () => SiemMigrationRuleTranslationResult.UNTRANSLATABLE, diff --git a/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/task/agent/sub_graphs/translate_rule/types.ts b/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/task/agent/sub_graphs/translate_rule/types.ts index 42bf8e14c5924..44a5750812be0 100644 --- a/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/task/agent/sub_graphs/translate_rule/types.ts +++ b/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/task/agent/sub_graphs/translate_rule/types.ts @@ -23,3 +23,8 @@ export interface TranslateRuleGraphParams { integrationRetriever: IntegrationRetriever; logger: Logger; } + +export interface TranslateRuleValidationErrors { + iterations: number; + esql_errors?: string; +} diff --git a/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/task/rule_migrations_task_client.ts b/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/task/rule_migrations_task_client.ts index 56c7e8485d315..a6ea5c9040e16 100644 --- a/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/task/rule_migrations_task_client.ts +++ b/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/task/rule_migrations_task_client.ts @@ -8,7 +8,10 @@ import type { AuthenticatedUser, Logger } from '@kbn/core/server'; import { AbortError, abortSignalToPromise } from '@kbn/kibana-utils-plugin/server'; import type { RunnableConfig } from '@langchain/core/runnables'; -import { SiemMigrationStatus } from '../../../../../common/siem_migrations/constants'; +import { + SiemMigrationTaskStatus, + SiemMigrationStatus, +} from '../../../../../common/siem_migrations/constants'; import type { RuleMigrationTaskStats } from '../../../../../common/siem_migrations/model/rule_migration.gen'; import type { RuleMigrationsDataClient } from '../data/rule_migrations_data_client'; import type { RuleMigrationDataStats } from '../data/rule_migrations_data_rules_client'; @@ -237,17 +240,17 @@ export class RuleMigrationsTaskClient { private getTaskStatus( migrationId: string, dataStats: RuleMigrationDataStats['rules'] - ): RuleMigrationTaskStats['status'] { + ): SiemMigrationTaskStatus { if (this.migrationsRunning.has(migrationId)) { - return 'running'; + return SiemMigrationTaskStatus.RUNNING; } if (dataStats.pending === dataStats.total) { - return 'ready'; + return SiemMigrationTaskStatus.READY; } if (dataStats.completed + dataStats.failed === dataStats.total) { - return 'finished'; + return SiemMigrationTaskStatus.FINISHED; } - return 'stopped'; + return SiemMigrationTaskStatus.STOPPED; } /** Stops one running migration */ diff --git a/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/task/agent/sub_graphs/translate_rule/nodes/translate_rule/esql_knowledge_base_caller.ts b/x-pack/plugins/security_solution/server/lib/siem_migrations/rules/task/util/esql_knowledge_base_caller.ts similarity index 100% rename from x-pack/plugins/security_solution/server/lib/siem_migrations/rules/task/agent/sub_graphs/translate_rule/nodes/translate_rule/esql_knowledge_base_caller.ts rename to x-pack/plugins/security_solution/server/lib/siem_migrations/rules/task/util/esql_knowledge_base_caller.ts diff --git a/x-pack/plugins/security_solution/server/plugin_contract.ts b/x-pack/plugins/security_solution/server/plugin_contract.ts index c178f0654d9bd..b1e7d0b613800 100644 --- a/x-pack/plugins/security_solution/server/plugin_contract.ts +++ b/x-pack/plugins/security_solution/server/plugin_contract.ts @@ -12,10 +12,7 @@ import type { } from '@kbn/data-plugin/server'; import type { PluginStart as DataViewsPluginStart } from '@kbn/data-views-plugin/server'; import type { UsageCollectionSetup as UsageCollectionPluginSetup } from '@kbn/usage-collection-plugin/server'; -import type { - PluginSetupContract as AlertingPluginSetup, - PluginStartContract as AlertingPluginStart, -} from '@kbn/alerting-plugin/server'; +import type { AlertingServerSetup, AlertingServerStart } from '@kbn/alerting-plugin/server'; import type { PluginSetupContract as ActionsPluginSetup, PluginStartContract as ActionsPluginStartContract, @@ -50,7 +47,7 @@ import type { ProductFeaturesService } from './lib/product_features_service/prod import type { ExperimentalFeatures } from '../common'; export interface SecuritySolutionPluginSetupDependencies { - alerting: AlertingPluginSetup; + alerting: AlertingServerSetup; actions: ActionsPluginSetup; cases: CasesServerSetup; cloud: CloudSetup; @@ -73,7 +70,7 @@ export interface SecuritySolutionPluginSetupDependencies { } export interface SecuritySolutionPluginStartDependencies { - alerting: AlertingPluginStart; + alerting: AlertingServerStart; cases?: CasesServerStart; cloud: CloudSetup; data: DataPluginStart; diff --git a/x-pack/plugins/security_solution/server/request_context_factory.ts b/x-pack/plugins/security_solution/server/request_context_factory.ts index eb1fed5826158..c2b3782d405d0 100644 --- a/x-pack/plugins/security_solution/server/request_context_factory.ts +++ b/x-pack/plugins/security_solution/server/request_context_factory.ts @@ -107,6 +107,8 @@ export class RequestContextFactory implements IRequestContextFactory { // time it is requested (see `getEndpointAuthz()` below) let endpointAuthz: Immutable; + const rulesClient = await startPlugins.alerting.getRulesClientWithRequest(request); + return { core: coreContext, @@ -146,16 +148,17 @@ export class RequestContextFactory implements IRequestContextFactory { }); return createDetectionRulesClient({ + rulesClient, actionsClient, - rulesClient: startPlugins.alerting.getRulesClientWithRequest(request), savedObjectsClient: coreContext.savedObjects.client, mlAuthz, + isRuleCustomizationEnabled: config.experimentalFeatures.prebuiltRulesCustomizationEnabled, }); }), getDetectionEngineHealthClient: memoize(() => ruleMonitoringService.createDetectionEngineHealthClient({ - rulesClient: startPlugins.alerting.getRulesClientWithRequest(request), + rulesClient, eventLogClient: startPlugins.eventLog.getClient(request), currentSpaceId: getSpaceId(), }) diff --git a/x-pack/plugins/security_solution/tsconfig.json b/x-pack/plugins/security_solution/tsconfig.json index 4a00ef93abe63..4ed7e1cbdd35f 100644 --- a/x-pack/plugins/security_solution/tsconfig.json +++ b/x-pack/plugins/security_solution/tsconfig.json @@ -15,7 +15,11 @@ "public/**/*.json", "../../../typings/**/*" ], - "exclude": ["target/**/*", "**/cypress/**", "public/management/cypress.config.ts"], + "exclude": [ + "target/**/*", + "**/cypress/**", + "public/management/cypress.config.ts" + ], "kbn_references": [ "@kbn/core", { @@ -228,6 +232,7 @@ "@kbn/core-lifecycle-server", "@kbn/core-user-profile-common", "@kbn/langchain", + "@kbn/discover-shared-plugin", "@kbn/react-hooks", "@kbn/index-adapter", "@kbn/core-http-server-utils" diff --git a/x-pack/plugins/serverless_observability/public/plugin.ts b/x-pack/plugins/serverless_observability/public/plugin.ts index 774a76749f8d6..d4df07673e870 100644 --- a/x-pack/plugins/serverless_observability/public/plugin.ts +++ b/x-pack/plugins/serverless_observability/public/plugin.ts @@ -63,7 +63,7 @@ export class ServerlessObservabilityPlugin observabilityAiAssistantManagement: { category: appCategories.OTHER, title: i18n.translate('xpack.serverlessObservability.aiAssistantManagementTitle', { - defaultMessage: 'AI Assistant for Observability and Search Settings', + defaultMessage: 'AI Assistant Settings', }), description: i18n.translate( 'xpack.serverlessObservability.aiAssistantManagementDescription', diff --git a/x-pack/plugins/serverless_search/public/application/components/connectors/edit_service_type.tsx b/x-pack/plugins/serverless_search/public/application/components/connectors/edit_service_type.tsx index 2c428007034ec..af7e15fa372ec 100644 --- a/x-pack/plugins/serverless_search/public/application/components/connectors/edit_service_type.tsx +++ b/x-pack/plugins/serverless_search/public/application/components/connectors/edit_service_type.tsx @@ -19,6 +19,11 @@ interface EditServiceTypeProps { isDisabled?: boolean; } +interface GeneratedConnectorNameResult { + connectorName: string; + indexName: string; +} + export const EditServiceType: React.FC = ({ connector, isDisabled }) => { const { http } = useKibanaServices(); const connectorTypes = useConnectorTypes(); @@ -52,11 +57,43 @@ export const EditServiceType: React.FC = ({ connector, isD await http.post(`/internal/serverless_search/connectors/${connector.id}/service_type`, { body: JSON.stringify(body), }); - return inputServiceType; + + // if name is empty, auto generate it and a similar index name + const results: Record = await http.post( + `/internal/serverless_search/connectors/${connector.id}/generate_name`, + { + body: JSON.stringify({ + name: connector.name, + is_native: connector.is_native, + service_type: inputServiceType, + }), + } + ); + + const connectorName = results.result.connectorName; + const indexName = results.result.indexName; + + // save the generated connector name + await http.post(`/internal/serverless_search/connectors/${connector.id}/name`, { + body: JSON.stringify({ name: connectorName || '' }), + }); + + // save the generated index name (this does not create an index) + try { + // this can fail if another connector has an identical index_name value despite no index being created yet. + // in this case we just won't update the index_name, the user can do that manually when they reach that step. + await http.post(`/internal/serverless_search/connectors/${connector.id}/index_name`, { + body: JSON.stringify({ index_name: indexName }), + }); + } catch { + // do nothing + } + + return { serviceType: inputServiceType, name: connectorName }; }, onSuccess: (successData) => { queryClient.setQueryData(queryKey, { - connector: { ...connector, service_type: successData }, + connector: { ...connector, service_type: successData.serviceType, name: successData.name }, }); queryClient.invalidateQueries(queryKey); }, diff --git a/x-pack/plugins/serverless_search/public/plugin.ts b/x-pack/plugins/serverless_search/public/plugin.ts index 3c24211d2a520..1b804e4bab307 100644 --- a/x-pack/plugins/serverless_search/public/plugin.ts +++ b/x-pack/plugins/serverless_search/public/plugin.ts @@ -13,7 +13,7 @@ import { Plugin, } from '@kbn/core/public'; import { i18n } from '@kbn/i18n'; -import { appIds } from '@kbn/management-cards-navigation'; +import { appCategories, appIds } from '@kbn/management-cards-navigation'; import { AuthenticatedUser } from '@kbn/security-plugin/common'; import { QueryClient, MutationCache, QueryCache } from '@tanstack/react-query'; import { of } from 'rxjs'; @@ -168,12 +168,31 @@ export class ServerlessSearchPlugin ): ServerlessSearchPluginStart { const { serverless, management, indexManagement, security } = services; serverless.setProjectHome(services.searchIndices.startRoute); + const aiAssistantIsEnabled = core.application.capabilities.observabilityAIAssistant?.show; const navigationTree$ = of(navigationTree(core.application)); serverless.initNavigation('es', navigationTree$, { dataTestSubj: 'svlSearchSideNav' }); const extendCardNavDefinitions = serverless.getNavigationCards( - security.authz.isRoleManagementEnabled() + security.authz.isRoleManagementEnabled(), + aiAssistantIsEnabled + ? { + observabilityAiAssistantManagement: { + category: appCategories.OTHER, + title: i18n.translate('xpack.serverlessSearch.aiAssistantManagementTitle', { + defaultMessage: 'AI Assistant Settings', + }), + description: i18n.translate( + 'xpack.serverlessSearch.aiAssistantManagementDescription', + { + defaultMessage: + 'Manage knowledge base and control assistant behavior, including response language.', + } + ), + icon: 'sparkles', + }, + } + : undefined ); management.setupCardsNavigation({ diff --git a/x-pack/plugins/serverless_search/server/routes/connectors_routes.ts b/x-pack/plugins/serverless_search/server/routes/connectors_routes.ts index 09896a1808e4d..7c507ca4c7b2f 100644 --- a/x-pack/plugins/serverless_search/server/routes/connectors_routes.ts +++ b/x-pack/plugins/serverless_search/server/routes/connectors_routes.ts @@ -12,6 +12,7 @@ import { fetchConnectorById, fetchConnectors, fetchSyncJobs, + generateConnectorName, IngestPipelineParams, startConnectorSync, updateConnectorConfiguration, @@ -353,4 +354,36 @@ export const registerConnectorsRoutes = ({ logger, http, router }: RouteDependen return response.ok(); }) ); + + router.post( + { + path: '/internal/serverless_search/connectors/{connectorId}/generate_name', + validate: { + body: schema.object({ + name: schema.string(), + is_native: schema.boolean(), + service_type: schema.string(), + }), + params: schema.object({ + connectorId: schema.string(), + }), + }, + }, + errorHandler(logger)(async (context, request, response) => { + const { client } = (await context.core).elasticsearch; + const result = await generateConnectorName( + client.asCurrentUser, + request.body.service_type, + request.body.is_native, + request.body.name + ); + + return response.ok({ + body: { + result, + }, + headers: { 'content-type': 'application/json' }, + }); + }) + ); }; diff --git a/x-pack/plugins/session_view/server/routes/alert_status_route.test.ts b/x-pack/plugins/session_view/server/routes/alert_status_route.test.ts index 646c0cbca96b5..d38b83747181a 100644 --- a/x-pack/plugins/session_view/server/routes/alert_status_route.test.ts +++ b/x-pack/plugins/session_view/server/routes/alert_status_route.test.ts @@ -13,7 +13,7 @@ import { import { elasticsearchServiceMock } from '@kbn/core/server/mocks'; import { searchAlertByUuid } from './alert_status_route'; import { mockAlerts } from '../../common/mocks/constants/session_view_process.mock'; -import { getAlertsClientMockInstance, resetAlertingAuthMock } from './alerts_client_mock.test'; +import { getAlertsClientMockInstance } from './alerts_client_mock.test'; const getEmptyResponse = async () => { return { @@ -54,7 +54,6 @@ const getResponse = async () => { describe('alert_status_route.ts', () => { beforeEach(() => { jest.resetAllMocks(); - resetAlertingAuthMock(); }); describe('searchAlertByUuid(client, alertUuid)', () => { diff --git a/x-pack/plugins/session_view/server/routes/alert_status_route.ts b/x-pack/plugins/session_view/server/routes/alert_status_route.ts index 64192198b5e46..0a1976456ef1c 100644 --- a/x-pack/plugins/session_view/server/routes/alert_status_route.ts +++ b/x-pack/plugins/session_view/server/routes/alert_status_route.ts @@ -11,6 +11,7 @@ import type { AlertsClient, RuleRegistryPluginStartContract, } from '@kbn/rule-registry-plugin/server'; +import { SECURITY_SOLUTION_RULE_TYPE_IDS } from '@kbn/securitysolution-rules'; import { ALERT_STATUS_ROUTE, ALERT_UUID_PROPERTY, @@ -65,9 +66,9 @@ export const registerAlertStatusRoute = ( }; export const searchAlertByUuid = async (client: AlertsClient, alertUuid: string) => { - const indices = (await client.getAuthorizedAlertsIndices(['siem']))?.filter( - (index) => index !== PREVIEW_ALERTS_INDEX - ); + const indices = ( + await client.getAuthorizedAlertsIndices(SECURITY_SOLUTION_RULE_TYPE_IDS) + )?.filter((index) => index !== PREVIEW_ALERTS_INDEX); if (!indices) { return { events: [] }; 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 ff76314776025..dcc1f06b0f2eb 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 @@ -13,7 +13,6 @@ import { elasticsearchServiceMock } from '@kbn/core/server/mocks'; import { loggingSystemMock } from '@kbn/core/server/mocks'; import { alertingAuthorizationMock } from '@kbn/alerting-plugin/server/authorization/alerting_authorization.mock'; import { auditLoggerMock } from '@kbn/security-plugin/server/audit/mocks'; -import { AlertingAuthorizationEntity } from '@kbn/alerting-plugin/server'; import { ruleDataServiceMock } from '@kbn/rule-registry-plugin/server/rule_data_plugin_service/rule_data_plugin_service.mock'; import type { ElasticsearchClient } from '@kbn/core/server'; import { @@ -24,11 +23,6 @@ import { } from '@kbn/rule-data-utils'; import { mockAlerts } from '../../common/mocks/constants/session_view_process.mock'; -export const alertingAuthMock = alertingAuthorizationMock.create(); -const auditLogger = auditLoggerMock.create(); - -const DEFAULT_SPACE = 'test_default_space_id'; - const getResponse = async () => { return { hits: { @@ -56,73 +50,62 @@ const getResponse = async () => { }; }; -const esClientMock = elasticsearchServiceMock.createElasticsearchClient(getResponse()); -const getAlertIndicesAliasMock = jest.fn(); -const alertsClientParams: jest.Mocked = { - logger: loggingSystemMock.create().get(), - authorization: alertingAuthMock, - auditLogger, - ruleDataService: ruleDataServiceMock.create(), - esClient: esClientMock, - getRuleType: jest.fn(), - getRuleList: jest.fn(), - getAlertIndicesAlias: getAlertIndicesAliasMock, -}; - -export function getAlertsClientMockInstance(esClient?: ElasticsearchClient) { - esClient = esClient || elasticsearchServiceMock.createElasticsearchClient(getResponse()); - - const alertsClient = new AlertsClient({ ...alertsClientParams, esClient }); - - return alertsClient; -} +const createAlertsClientParams = () => { + const getAlertIndicesAliasMock = jest.fn(); + const alertingAuthMock = alertingAuthorizationMock.create(); -export function resetAlertingAuthMock() { - alertingAuthMock.getSpaceId.mockImplementation(() => DEFAULT_SPACE); - // @ts-expect-error - alertingAuthMock.getAuthorizationFilter.mockImplementation(async () => - Promise.resolve({ filter: [] }) - ); - // @ts-expect-error - alertingAuthMock.getAugmentedRuleTypesWithAuthorization.mockImplementation(async () => { - const authorizedRuleTypes = new Set(); - authorizedRuleTypes.add({ producer: 'apm' }); - return Promise.resolve({ authorizedRuleTypes }); - }); - // @ts-expect-error - alertingAuthMock.getAuthorizedRuleTypes.mockImplementation(async () => { - const authorizedRuleTypes = [ + const authorizedRuleTypes = new Map([ + [ + 'apm.error_rate', { producer: 'apm', id: 'apm.error_rate', alerts: { context: 'observability.apm', }, + authorizedConsumers: {}, }, - ]; - return Promise.resolve(authorizedRuleTypes); + ], + ]); + + alertingAuthMock.getSpaceId.mockImplementation(() => 'test_default_space_id'); + alertingAuthMock.getAllAuthorizedRuleTypes.mockResolvedValue({ + hasAllRequested: true, + authorizedRuleTypes, }); + + alertingAuthMock.getAllAuthorizedRuleTypesFindOperation.mockResolvedValue(authorizedRuleTypes); getAlertIndicesAliasMock.mockReturnValue(['.alerts-observability.apm-default']); - alertingAuthMock.ensureAuthorized.mockImplementation( - // @ts-expect-error - async ({ - ruleTypeId, - consumer, - operation, - entity, - }: { - ruleTypeId: string; - consumer: string; - operation: string; - entity: typeof AlertingAuthorizationEntity.Alert; - }) => { - if (ruleTypeId === 'apm.error_rate' && consumer === 'apm') { - return Promise.resolve(); - } - return Promise.reject(new Error(`Unauthorized for ${ruleTypeId} and ${consumer}`)); + alertingAuthMock.ensureAuthorized.mockImplementation(async ({ ruleTypeId, consumer }) => { + if (ruleTypeId === 'apm.error_rate' && consumer === 'apm') { + return Promise.resolve(); } - ); + return Promise.reject(new Error(`Unauthorized for ${ruleTypeId} and ${consumer}`)); + }); + + const auditLogger = auditLoggerMock.create(); + const esClientMock = elasticsearchServiceMock.createElasticsearchClient(getResponse()); + const alertsClientParams: jest.Mocked = { + logger: loggingSystemMock.create().get(), + authorization: alertingAuthMock, + auditLogger, + ruleDataService: ruleDataServiceMock.create(), + esClient: esClientMock, + getRuleType: jest.fn(), + getRuleList: jest.fn(), + getAlertIndicesAlias: getAlertIndicesAliasMock, + }; + + return alertsClientParams; +}; + +export function getAlertsClientMockInstance(esClient?: ElasticsearchClient) { + esClient = esClient || elasticsearchServiceMock.createElasticsearchClient(getResponse()); + + const alertsClient = new AlertsClient({ ...createAlertsClientParams(), esClient }); + + return alertsClient; } // this is only here because the above imports complain if they aren't declared as part of a test file. diff --git a/x-pack/plugins/session_view/server/routes/alerts_route.test.ts b/x-pack/plugins/session_view/server/routes/alerts_route.test.ts index 12300b8946a78..b8ba3f5d45a02 100644 --- a/x-pack/plugins/session_view/server/routes/alerts_route.test.ts +++ b/x-pack/plugins/session_view/server/routes/alerts_route.test.ts @@ -7,7 +7,7 @@ import { elasticsearchServiceMock } from '@kbn/core/server/mocks'; import { searchAlerts } from './alerts_route'; import { mockAlerts } from '../../common/mocks/constants/session_view_process.mock'; -import { getAlertsClientMockInstance, resetAlertingAuthMock } from './alerts_client_mock.test'; +import { getAlertsClientMockInstance } from './alerts_client_mock.test'; const getEmptyResponse = async () => { return { @@ -20,9 +20,7 @@ const getEmptyResponse = async () => { describe('alerts_route.ts', () => { beforeEach(() => { - jest.resetAllMocks(); - - resetAlertingAuthMock(); + jest.clearAllMocks(); }); describe('searchAlerts(client, sessionEntityId)', () => { diff --git a/x-pack/plugins/session_view/server/routes/alerts_route.ts b/x-pack/plugins/session_view/server/routes/alerts_route.ts index c875236989efe..c4aa913334305 100644 --- a/x-pack/plugins/session_view/server/routes/alerts_route.ts +++ b/x-pack/plugins/session_view/server/routes/alerts_route.ts @@ -11,6 +11,7 @@ import type { AlertsClient, RuleRegistryPluginStartContract, } from '@kbn/rule-registry-plugin/server'; +import { SECURITY_SOLUTION_RULE_TYPE_IDS } from '@kbn/securitysolution-rules'; import { ALERTS_ROUTE, ALERTS_PER_PAGE, @@ -88,9 +89,9 @@ export const searchAlerts = async ( range?: string[], cursor?: string ) => { - const indices = (await client.getAuthorizedAlertsIndices(['siem']))?.filter( - (index) => index !== PREVIEW_ALERTS_INDEX - ); + const indices = ( + await client.getAuthorizedAlertsIndices(SECURITY_SOLUTION_RULE_TYPE_IDS) + )?.filter((index) => index !== PREVIEW_ALERTS_INDEX); if (!indices) { return { events: [] }; diff --git a/x-pack/plugins/session_view/server/routes/process_events_route.test.ts b/x-pack/plugins/session_view/server/routes/process_events_route.test.ts index 034cab178af2f..aaba035c7496b 100644 --- a/x-pack/plugins/session_view/server/routes/process_events_route.test.ts +++ b/x-pack/plugins/session_view/server/routes/process_events_route.test.ts @@ -12,7 +12,7 @@ import { mockEvents, mockAlerts, } from '../../common/mocks/constants/session_view_process.mock'; -import { getAlertsClientMockInstance, resetAlertingAuthMock } from './alerts_client_mock.test'; +import { getAlertsClientMockInstance } from './alerts_client_mock.test'; import type { ProcessEvent } from '../../common'; const getEmptyResponse = async () => { @@ -38,8 +38,6 @@ const getResponse = async () => { describe('process_events_route.ts', () => { beforeEach(() => { jest.resetAllMocks(); - - resetAlertingAuthMock(); }); describe('fetchEventsAndScopedAlerts(client, entityId, cursor, forward)', () => { diff --git a/x-pack/plugins/session_view/tsconfig.json b/x-pack/plugins/session_view/tsconfig.json index 20a1f5234d9ff..412de8355943c 100644 --- a/x-pack/plugins/session_view/tsconfig.json +++ b/x-pack/plugins/session_view/tsconfig.json @@ -38,6 +38,7 @@ "@kbn/shared-ux-router", "@kbn/usage-collection-plugin", "@kbn/analytics", + "@kbn/securitysolution-rules", ], "exclude": [ "target/**/*", diff --git a/x-pack/plugins/stack_alerts/server/feature.test.ts b/x-pack/plugins/stack_alerts/server/feature.test.ts index 769fad5172d65..deb1a317eed51 100644 --- a/x-pack/plugins/stack_alerts/server/feature.test.ts +++ b/x-pack/plugins/stack_alerts/server/feature.test.ts @@ -27,36 +27,145 @@ describe('Stack Alerts Feature Privileges', () => { const featuresSetup = featuresPluginMock.createSetup(); plugin.setup(coreSetup, { alerting: alertingSetup, features: featuresSetup }); - expect(BUILT_IN_ALERTS_FEATURE.alerting).toMatchInlineSnapshot(` + const ruleTypeAlerting = BUILT_IN_ALERTS_FEATURE.alerting ?? []; + const ruleTypeAll = BUILT_IN_ALERTS_FEATURE.privileges?.all?.alerting?.rule?.all ?? []; + const ruleTypeRead = BUILT_IN_ALERTS_FEATURE.privileges?.read?.alerting?.rule?.read ?? []; + + expect(ruleTypeAlerting).toMatchInlineSnapshot(` Array [ - ".index-threshold", - ".geo-containment", - ".es-query", - "transform_health", - "observability.rules.custom_threshold", - "xpack.ml.anomaly_detection_alert", + Object { + "consumers": Array [ + "stackAlerts", + "alerts", + ], + "ruleTypeId": ".index-threshold", + }, + Object { + "consumers": Array [ + "stackAlerts", + "alerts", + ], + "ruleTypeId": ".geo-containment", + }, + Object { + "consumers": Array [ + "stackAlerts", + "alerts", + ], + "ruleTypeId": "transform_health", + }, + Object { + "consumers": Array [ + "stackAlerts", + "alerts", + "discover", + ], + "ruleTypeId": ".es-query", + }, + Object { + "consumers": Array [ + "stackAlerts", + ], + "ruleTypeId": "xpack.ml.anomaly_detection_alert", + }, + Object { + "consumers": Array [ + "stackAlerts", + ], + "ruleTypeId": "observability.rules.custom_threshold", + }, ] `); - expect(BUILT_IN_ALERTS_FEATURE.privileges?.all?.alerting?.rule?.all).toMatchInlineSnapshot(` + expect(ruleTypeAll).toMatchInlineSnapshot(` Array [ - ".index-threshold", - ".geo-containment", - ".es-query", - "transform_health", - "observability.rules.custom_threshold", - "xpack.ml.anomaly_detection_alert", + Object { + "consumers": Array [ + "stackAlerts", + "alerts", + ], + "ruleTypeId": ".index-threshold", + }, + Object { + "consumers": Array [ + "stackAlerts", + "alerts", + ], + "ruleTypeId": ".geo-containment", + }, + Object { + "consumers": Array [ + "stackAlerts", + "alerts", + ], + "ruleTypeId": "transform_health", + }, + Object { + "consumers": Array [ + "stackAlerts", + "alerts", + "discover", + ], + "ruleTypeId": ".es-query", + }, + Object { + "consumers": Array [ + "stackAlerts", + ], + "ruleTypeId": "xpack.ml.anomaly_detection_alert", + }, + Object { + "consumers": Array [ + "stackAlerts", + ], + "ruleTypeId": "observability.rules.custom_threshold", + }, ] `); - expect(BUILT_IN_ALERTS_FEATURE.privileges?.read?.alerting?.rule?.read).toMatchInlineSnapshot(` + expect(ruleTypeRead).toMatchInlineSnapshot(` Array [ - ".index-threshold", - ".geo-containment", - ".es-query", - "transform_health", - "observability.rules.custom_threshold", - "xpack.ml.anomaly_detection_alert", + Object { + "consumers": Array [ + "stackAlerts", + "alerts", + ], + "ruleTypeId": ".index-threshold", + }, + Object { + "consumers": Array [ + "stackAlerts", + "alerts", + ], + "ruleTypeId": ".geo-containment", + }, + Object { + "consumers": Array [ + "stackAlerts", + "alerts", + ], + "ruleTypeId": "transform_health", + }, + Object { + "consumers": Array [ + "stackAlerts", + "alerts", + "discover", + ], + "ruleTypeId": ".es-query", + }, + Object { + "consumers": Array [ + "stackAlerts", + ], + "ruleTypeId": "xpack.ml.anomaly_detection_alert", + }, + Object { + "consumers": Array [ + "stackAlerts", + ], + "ruleTypeId": "observability.rules.custom_threshold", + }, ] `); }); diff --git a/x-pack/plugins/stack_alerts/server/feature.ts b/x-pack/plugins/stack_alerts/server/feature.ts index fcb7aba3947a3..fa98c155b6ba8 100644 --- a/x-pack/plugins/stack_alerts/server/feature.ts +++ b/x-pack/plugins/stack_alerts/server/feature.ts @@ -15,11 +15,59 @@ import { STACK_ALERTS_FEATURE_ID, } from '@kbn/rule-data-utils'; import { ES_QUERY_ID as ElasticsearchQuery } from '@kbn/rule-data-utils'; +import { ALERTING_FEATURE_ID } from '@kbn/alerting-plugin/common'; import { KibanaFeatureScope } from '@kbn/features-plugin/common'; import { ID as IndexThreshold } from './rule_types/index_threshold/rule_type'; import { GEO_CONTAINMENT_ID as GeoContainment } from './rule_types/geo_containment'; const TransformHealth = TRANSFORM_RULE_TYPE.TRANSFORM_HEALTH; +const DISCOVER_CONSUMER = 'discover'; + +const basicAlertingFeatures = [IndexThreshold, GeoContainment, TransformHealth].map( + (ruleTypeId) => ({ + ruleTypeId, + consumers: [STACK_ALERTS_FEATURE_ID, ALERTING_FEATURE_ID], + }) +); + +/** + * We need to add the discover consumer + * to support legacy ES rules that were + * created with the discover consumer. + * + * Issue: https://github.com/elastic/kibana/issues/184595 + */ +const esQueryAlertingFeature = { + ruleTypeId: ElasticsearchQuery, + consumers: [STACK_ALERTS_FEATURE_ID, ALERTING_FEATURE_ID, DISCOVER_CONSUMER], +}; + +/** + * Only the stackAlerts consumer is valid + * for the stackAlerts feature ID for the + * xpack.ml.anomaly_detection_alert rule type. + */ +const mlAnomalyDetectionAlertingFeature = { + ruleTypeId: ML_ANOMALY_DETECTION_RULE_TYPE_ID, + consumers: [STACK_ALERTS_FEATURE_ID], +}; + +/** + * Only the stackAlerts consumer is valid + * for the stackAlerts feature ID for the + * observability.rules.custom_threshold rule type. + */ +const observabilityThresholdAlertingFeature = { + ruleTypeId: OBSERVABILITY_THRESHOLD_RULE_TYPE_ID, + consumers: [STACK_ALERTS_FEATURE_ID], +}; + +const alertingFeatures = [ + ...basicAlertingFeatures, + esQueryAlertingFeature, + mlAnomalyDetectionAlertingFeature, + observabilityThresholdAlertingFeature, +]; export const BUILT_IN_ALERTS_FEATURE: KibanaFeatureConfig = { id: STACK_ALERTS_FEATURE_ID, @@ -32,14 +80,7 @@ export const BUILT_IN_ALERTS_FEATURE: KibanaFeatureConfig = { management: { insightsAndAlerting: ['triggersActions'], }, - alerting: [ - IndexThreshold, - GeoContainment, - ElasticsearchQuery, - TransformHealth, - OBSERVABILITY_THRESHOLD_RULE_TYPE_ID, - ML_ANOMALY_DETECTION_RULE_TYPE_ID, - ], + alerting: alertingFeatures, privileges: { all: { app: [], @@ -49,24 +90,10 @@ export const BUILT_IN_ALERTS_FEATURE: KibanaFeatureConfig = { }, alerting: { rule: { - all: [ - IndexThreshold, - GeoContainment, - ElasticsearchQuery, - TransformHealth, - OBSERVABILITY_THRESHOLD_RULE_TYPE_ID, - ML_ANOMALY_DETECTION_RULE_TYPE_ID, - ], + all: alertingFeatures, }, alert: { - all: [ - IndexThreshold, - GeoContainment, - ElasticsearchQuery, - TransformHealth, - OBSERVABILITY_THRESHOLD_RULE_TYPE_ID, - ML_ANOMALY_DETECTION_RULE_TYPE_ID, - ], + all: alertingFeatures, }, }, savedObject: { @@ -84,24 +111,10 @@ export const BUILT_IN_ALERTS_FEATURE: KibanaFeatureConfig = { }, alerting: { rule: { - read: [ - IndexThreshold, - GeoContainment, - ElasticsearchQuery, - TransformHealth, - OBSERVABILITY_THRESHOLD_RULE_TYPE_ID, - ML_ANOMALY_DETECTION_RULE_TYPE_ID, - ], + read: alertingFeatures, }, alert: { - read: [ - IndexThreshold, - GeoContainment, - ElasticsearchQuery, - TransformHealth, - OBSERVABILITY_THRESHOLD_RULE_TYPE_ID, - ML_ANOMALY_DETECTION_RULE_TYPE_ID, - ], + read: alertingFeatures, }, }, savedObject: { diff --git a/x-pack/plugins/stack_alerts/server/rule_types/types.ts b/x-pack/plugins/stack_alerts/server/rule_types/types.ts index e06553233e774..876a3c472e3ad 100644 --- a/x-pack/plugins/stack_alerts/server/rule_types/types.ts +++ b/x-pack/plugins/stack_alerts/server/rule_types/types.ts @@ -7,12 +7,12 @@ import { StackAlert } from '@kbn/alerts-as-data-utils'; import { CoreSetup, Logger } from '@kbn/core/server'; -import { AlertingSetup, StackAlertsStartDeps } from '../types'; +import { AlertingServerSetup, StackAlertsStartDeps } from '../types'; export interface RegisterRuleTypesParams { logger: Logger; data: Promise; - alerting: AlertingSetup; + alerting: AlertingServerSetup; core: CoreSetup; } diff --git a/x-pack/plugins/stack_alerts/server/types.ts b/x-pack/plugins/stack_alerts/server/types.ts index ce148fb8c0434..1f4d2d2914867 100644 --- a/x-pack/plugins/stack_alerts/server/types.ts +++ b/x-pack/plugins/stack_alerts/server/types.ts @@ -6,20 +6,19 @@ */ import { PluginStartContract as TriggersActionsUiStartContract } from '@kbn/triggers-actions-ui-plugin/server'; -import { PluginSetupContract as AlertingSetup } from '@kbn/alerting-plugin/server'; - export type { - PluginSetupContract as AlertingSetup, RuleType, RuleParamsAndRefs, RuleExecutorOptions, RuleTypeParams, + AlertingServerSetup, } from '@kbn/alerting-plugin/server'; import { FeaturesPluginSetup } from '@kbn/features-plugin/server'; +import { AlertingServerSetup } from '@kbn/alerting-plugin/server'; // this plugin's dependendencies export interface StackAlertsDeps { - alerting: AlertingSetup; + alerting: AlertingServerSetup; features: FeaturesPluginSetup; } diff --git a/x-pack/plugins/stack_connectors/common/crowdstrike/schema.ts b/x-pack/plugins/stack_connectors/common/crowdstrike/schema.ts index 379adfb0fcc95..d5e8cd693af98 100644 --- a/x-pack/plugins/stack_connectors/common/crowdstrike/schema.ts +++ b/x-pack/plugins/stack_connectors/common/crowdstrike/schema.ts @@ -17,7 +17,9 @@ export const CrowdstrikeSecretsSchema = schema.object({ clientSecret: schema.string(), }); -export const RelaxedCrowdstrikeBaseApiResponseSchema = schema.object({}, { unknowns: 'allow' }); +export const RelaxedCrowdstrikeBaseApiResponseSchema = schema.maybe( + schema.object({}, { unknowns: 'allow' }) +); export const CrowdstrikeBaseApiResponseSchema = schema.object( { resources: schema.arrayOf(schema.any()), diff --git a/x-pack/plugins/stack_connectors/common/sentinelone/schema.ts b/x-pack/plugins/stack_connectors/common/sentinelone/schema.ts index d9dde5773d79b..7daf615e01d31 100644 --- a/x-pack/plugins/stack_connectors/common/sentinelone/schema.ts +++ b/x-pack/plugins/stack_connectors/common/sentinelone/schema.ts @@ -16,7 +16,9 @@ export const SentinelOneSecretsSchema = schema.object({ token: schema.string(), }); -export const SentinelOneBaseApiResponseSchema = schema.object({}, { unknowns: 'allow' }); +export const SentinelOneBaseApiResponseSchema = schema.maybe( + schema.object({}, { unknowns: 'allow' }) +); export const SentinelOneGetAgentsResponseSchema = schema.object( { diff --git a/x-pack/plugins/stack_connectors/server/connector_types/crowdstrike/crowdstrike.ts b/x-pack/plugins/stack_connectors/server/connector_types/crowdstrike/crowdstrike.ts index 686612956d175..bd1f6613d5f04 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/crowdstrike/crowdstrike.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/crowdstrike/crowdstrike.ts @@ -236,6 +236,11 @@ export class CrowdstrikeConnector extends SubActionConnector< const response = await this.request( { ...req, + // We don't validate responses from Crowdstrike API's because we do not want failures for cases + // where the external system might add/remove/change values in the response that we have no + // control over. + responseSchema: + RelaxedCrowdstrikeBaseApiResponseSchema as unknown as SubActionRequestParams['responseSchema'], headers: { ...req.headers, Authorization: `Bearer ${CrowdstrikeConnector.token}`, diff --git a/x-pack/plugins/stack_connectors/server/connector_types/index.ts b/x-pack/plugins/stack_connectors/server/connector_types/index.ts index a156547cc2fa6..08b0331f1cf2f 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/index.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/index.ts @@ -63,6 +63,7 @@ export { ConnectorTypeId as WebhookConnectorTypeId } from './webhook'; export type { ActionParamsType as WebhookActionParams } from './webhook/types'; export { ConnectorTypeId as XmattersConnectorTypeId } from './xmatters'; export type { ActionParamsType as XmattersActionParams } from './xmatters'; +export { OpsgenieConnectorTypeId } from './opsgenie'; export type { OpsgenieActionConfig, diff --git a/x-pack/plugins/stack_connectors/server/connector_types/opsgenie/index.ts b/x-pack/plugins/stack_connectors/server/connector_types/opsgenie/index.ts index 7e92a3b7f3332..9570e0033f531 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/opsgenie/index.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/opsgenie/index.ts @@ -39,6 +39,8 @@ export const getOpsgenieConnectorType = (): SubActionConnectorType { params: { APIToken: 'token-abc', }, - responseSchema: SentinelOneGetActivitiesResponseSchema, + responseSchema: expect.any(Object), }); }); diff --git a/x-pack/plugins/stack_connectors/server/connector_types/sentinelone/sentinelone.ts b/x-pack/plugins/stack_connectors/server/connector_types/sentinelone/sentinelone.ts index dd73bafae8d2f..42d946edbc787 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/sentinelone/sentinelone.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/sentinelone/sentinelone.ts @@ -43,6 +43,7 @@ import { SentinelOneGetRemoteScriptResultsParamsSchema, SentinelOneDownloadRemoteScriptResultsParamsSchema, SentinelOneDownloadRemoteScriptResultsResponseSchema, + SentinelOneBaseApiResponseSchema, } from '../../../common/sentinelone/schema'; import { SUB_ACTION } from '../../../common/sentinelone/constants'; import { @@ -400,6 +401,11 @@ export class SentinelOneConnector extends SubActionConnector< const response = await this.request( { ...req, + // We don't validate responses from SentinelOne API's because we do not want failures for cases + // where the external system might add/remove/change values in the response that we have no + // control over. + responseSchema: + SentinelOneBaseApiResponseSchema as unknown as SubActionRequestParams['responseSchema'], params: { ...req.params, APIToken: this.secrets.token, diff --git a/x-pack/plugins/streams/common/types.ts b/x-pack/plugins/streams/common/types.ts index 82a7a372662e8..c2d99d4ba1d89 100644 --- a/x-pack/plugins/streams/common/types.ts +++ b/x-pack/plugins/streams/common/types.ts @@ -94,6 +94,15 @@ export type StreamWithoutIdDefinition = z.infer; export const streamDefinitonSchema = streamWithoutIdDefinitonSchema.extend({ id: z.string(), + managed: z.boolean().default(true), + unmanaged_elasticsearch_assets: z.optional( + z.array( + z.object({ + type: z.enum(['ingest_pipeline', 'component_template', 'index_template', 'data_stream']), + id: z.string(), + }) + ) + ), }); export type StreamDefinition = z.infer; diff --git a/x-pack/plugins/streams/server/lib/streams/internal_stream_mapping.ts b/x-pack/plugins/streams/server/lib/streams/internal_stream_mapping.ts index 8e88eeef8cd84..faff949c0d97b 100644 --- a/x-pack/plugins/streams/server/lib/streams/internal_stream_mapping.ts +++ b/x-pack/plugins/streams/server/lib/streams/internal_stream_mapping.ts @@ -29,6 +29,9 @@ export function createStreamsIndex(scopedClusterClient: IScopedClusterClient) { id: { type: 'keyword', }, + managed: { + type: 'boolean', + }, }, }, }); diff --git a/x-pack/plugins/streams/server/lib/streams/root_stream_definition.ts b/x-pack/plugins/streams/server/lib/streams/root_stream_definition.ts index 2b7deed877309..1bdb4f20a95cc 100644 --- a/x-pack/plugins/streams/server/lib/streams/root_stream_definition.ts +++ b/x-pack/plugins/streams/server/lib/streams/root_stream_definition.ts @@ -9,6 +9,7 @@ import { StreamDefinition } from '../../../common/types'; export const rootStreamDefinition: StreamDefinition = { id: 'logs', + managed: true, processing: [], children: [], fields: [ diff --git a/x-pack/plugins/streams/server/lib/streams/stream_crud.ts b/x-pack/plugins/streams/server/lib/streams/stream_crud.ts index 28775ebe8acba..245e06e8b4573 100644 --- a/x-pack/plugins/streams/server/lib/streams/stream_crud.ts +++ b/x-pack/plugins/streams/server/lib/streams/stream_crud.ts @@ -81,7 +81,7 @@ async function upsertInternalStream({ definition, scopedClusterClient }: BasePar return scopedClusterClient.asInternalUser.index({ id: definition.id, index: STREAMS_INDEX, - document: definition, + document: { ...definition, managed: true }, refresh: 'wait_for', }); } @@ -101,15 +101,32 @@ export async function listStreams({ size: 10000, sort: [{ id: 'asc' }], }); - const definitions = response.hits.hits.map((hit) => hit._source!); + + const dataStreams = await listDataStreamsAsStreams({ scopedClusterClient }); + const definitions = response.hits.hits.map((hit) => ({ ...hit._source!, managed: true })); const total = response.hits.total!; return { - definitions, - total: typeof total === 'number' ? total : total.value, + definitions: [...definitions, ...dataStreams], + total: (typeof total === 'number' ? total : total.value) + dataStreams.length, }; } +export async function listDataStreamsAsStreams({ + scopedClusterClient, +}: ListStreamsParams): Promise { + const response = await scopedClusterClient.asInternalUser.indices.getDataStream(); + return response.data_streams + .filter((dataStream) => dataStream.template.endsWith('@stream') === false) + .map((dataStream) => ({ + id: dataStream.name, + managed: false, + children: [], + fields: [], + processing: [], + })); +} + interface ReadStreamParams extends BaseParams { id: string; skipAccessCheck?: boolean; @@ -137,16 +154,80 @@ export async function readStream({ } } return { - definition, + definition: { + ...definition, + managed: true, + }, }; } catch (e) { if (e.meta?.statusCode === 404) { - throw new DefinitionNotFound(`Stream definition for ${id} not found.`); + return readDataStreamAsStream({ id, scopedClusterClient, skipAccessCheck }); } throw e; } } +export async function readDataStreamAsStream({ + id, + scopedClusterClient, + skipAccessCheck, +}: ReadStreamParams) { + const response = await scopedClusterClient.asInternalUser.indices.getDataStream({ name: id }); + if (response.data_streams.length === 1) { + const definition: StreamDefinition = { + id, + managed: false, + children: [], + fields: [], + processing: [], + }; + if (!skipAccessCheck) { + const hasAccess = await checkReadAccess({ id, scopedClusterClient }); + if (!hasAccess) { + throw new DefinitionNotFound(`Stream definition for ${id} not found.`); + } + } + // retrieve linked index template, component template and ingest pipeline + const templateName = response.data_streams[0].template; + const componentTemplates: string[] = []; + const template = await scopedClusterClient.asInternalUser.indices.getIndexTemplate({ + name: templateName, + }); + if (template.index_templates.length) { + template.index_templates[0].index_template.composed_of.forEach((componentTemplateName) => { + componentTemplates.push(componentTemplateName); + }); + } + const writeIndexName = response.data_streams[0].indices.at(-1)?.index_name!; + const currentIndex = await scopedClusterClient.asInternalUser.indices.get({ + index: writeIndexName, + }); + const ingestPipelineId = currentIndex[writeIndexName].settings?.index?.default_pipeline!; + + definition.unmanaged_elasticsearch_assets = [ + { + type: 'ingest_pipeline', + id: ingestPipelineId, + }, + ...componentTemplates.map((componentTemplateName) => ({ + type: 'component_template' as const, + id: componentTemplateName, + })), + { + type: 'index_template', + id: templateName, + }, + { + type: 'data_stream', + id, + }, + ]; + + return { definition }; + } + throw new DefinitionNotFound(`Stream definition for ${id} not found.`); +} + interface ReadAncestorsParams extends BaseParams { id: string; } @@ -285,6 +366,10 @@ export async function syncStream({ rootDefinition, logger, }: SyncStreamParams) { + if (!definition.managed) { + // TODO For now, we just don't allow reads at all - later on we will relax this to allow certain operations, but they will use a completely different syncing logic + throw new Error('Cannot sync an unmanaged stream'); + } const componentTemplate = generateLayer(definition.id, definition); await upsertComponent({ esClient: scopedClusterClient.asCurrentUser, diff --git a/x-pack/plugins/streams/server/routes/streams/edit.ts b/x-pack/plugins/streams/server/routes/streams/edit.ts index cda73907d2302..6125aa2470b94 100644 --- a/x-pack/plugins/streams/server/routes/streams/edit.ts +++ b/x-pack/plugins/streams/server/routes/streams/edit.ts @@ -76,6 +76,7 @@ export const editStreamRoute = createServerRoute({ children: [], fields: [], processing: [], + managed: true, }; await syncStream({ @@ -87,7 +88,7 @@ export const editStreamRoute = createServerRoute({ await syncStream({ scopedClusterClient, - definition: { ...streamDefinition, id: params.path.id }, + definition: { ...streamDefinition, id: params.path.id, managed: true }, rootDefinition: parentDefinition, logger, }); diff --git a/x-pack/plugins/streams/server/routes/streams/fork.ts b/x-pack/plugins/streams/server/routes/streams/fork.ts index 12dce248dcdd1..a4d846ceccb35 100644 --- a/x-pack/plugins/streams/server/routes/streams/fork.ts +++ b/x-pack/plugins/streams/server/routes/streams/fork.ts @@ -55,7 +55,7 @@ export const forkStreamsRoute = createServerRoute({ id: params.path.id, }); - const childDefinition = { ...params.body.stream, children: [] }; + const childDefinition = { ...params.body.stream, children: [], managed: true }; // check whether root stream has a child of the given name already if (rootDefinition.children.some((child) => child.id === childDefinition.id)) { diff --git a/x-pack/plugins/streams/server/routes/streams/list.ts b/x-pack/plugins/streams/server/routes/streams/list.ts index d3b88ffc36a45..774a256e5ba4a 100644 --- a/x-pack/plugins/streams/server/routes/streams/list.ts +++ b/x-pack/plugins/streams/server/routes/streams/list.ts @@ -52,9 +52,11 @@ export interface StreamTree { children: StreamTree[]; } -function asTrees(definitions: Array<{ id: string }>) { +function asTrees(definitions: Array<{ id: string; managed?: boolean }>) { const trees: StreamTree[] = []; - const ids = definitions.map((definition) => definition.id); + const ids = definitions + .filter((definition) => definition.managed) + .map((definition) => definition.id); ids.sort((a, b) => a.split('.').length - b.split('.').length); diff --git a/x-pack/plugins/streams/server/routes/streams/read.ts b/x-pack/plugins/streams/server/routes/streams/read.ts index b9d21ef25b673..5c503e2b7e625 100644 --- a/x-pack/plugins/streams/server/routes/streams/read.ts +++ b/x-pack/plugins/streams/server/routes/streams/read.ts @@ -45,6 +45,13 @@ export const readStreamRoute = createServerRoute({ id: params.path.id, }); + if (streamEntity.definition.managed === false) { + return { + ...streamEntity.definition, + inheritedFields: [], + }; + } + const { ancestors } = await readAncestors({ id: streamEntity.definition.id, scopedClusterClient, diff --git a/x-pack/plugins/streams_app/public/components/entity_detail_view/index.tsx b/x-pack/plugins/streams_app/public/components/entity_detail_view/index.tsx index 68c5f9d6798ec..8e423908af27d 100644 --- a/x-pack/plugins/streams_app/public/components/entity_detail_view/index.tsx +++ b/x-pack/plugins/streams_app/public/components/entity_detail_view/index.tsx @@ -4,9 +4,10 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { EuiFlexGroup, EuiFlexItem, EuiIcon, EuiLink, EuiPanel } from '@elastic/eui'; +import { EuiFlexGroup, EuiFlexItem, EuiIcon, EuiLink, EuiPanel, EuiBadge } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import React from 'react'; +import { StreamDefinition } from '@kbn/streams-plugin/common'; import { useStreamsAppBreadcrumbs } from '../../hooks/use_streams_app_breadcrumbs'; import { useStreamsAppRouter } from '../../hooks/use_streams_app_router'; import { EntityOverviewTabList } from '../entity_overview_tab_list'; @@ -25,6 +26,7 @@ export function EntityDetailViewWithoutParams({ selectedTab, tabs, entity, + definition, }: { selectedTab: string; tabs: EntityViewTab[]; @@ -32,6 +34,7 @@ export function EntityDetailViewWithoutParams({ displayName?: string; id: string; }; + definition?: StreamDefinition; }) { const router = useStreamsAppRouter(); useStreamsAppBreadcrumbs(() => { @@ -86,7 +89,26 @@ export function EntityDetailViewWithoutParams({ } + title={ + + {entity.displayName} + {definition && !definition.managed ? ( + <> + {' '} + + {i18n.translate( + 'xpack.streams.entityDetailViewWithoutParams.unmanagedBadgeLabel', + { defaultMessage: 'Unmanaged' } + )} + + + ) : null} + + } + /> + } > { diff --git a/x-pack/plugins/streams_app/public/components/stream_detail_management/index.tsx b/x-pack/plugins/streams_app/public/components/stream_detail_management/index.tsx index 534d883905b17..749b0e659d659 100644 --- a/x-pack/plugins/streams_app/public/components/stream_detail_management/index.tsx +++ b/x-pack/plugins/streams_app/public/components/stream_detail_management/index.tsx @@ -7,13 +7,14 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; import { StreamDefinition } from '@kbn/streams-plugin/common'; -import { EuiButtonGroup, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import { EuiButtonGroup, EuiFlexGroup, EuiFlexItem, EuiListGroup, EuiText } from '@elastic/eui'; import { useStreamsAppParams } from '../../hooks/use_streams_app_params'; import { RedirectTo } from '../redirect_to'; import { useStreamsAppRouter } from '../../hooks/use_streams_app_router'; import { StreamDetailRouting } from '../stream_detail_routing'; import { StreamDetailEnriching } from '../stream_detail_enriching'; import { StreamDetailSchemaEditor } from '../stream_detail_schema_editor'; +import { useKibana } from '../../hooks/use_kibana'; type ManagementSubTabs = 'route' | 'enrich' | 'schemaEditor'; @@ -33,6 +34,18 @@ export function StreamDetailManagement({ } = useStreamsAppParams('/{key}/management/{subtab}'); const router = useStreamsAppRouter(); + if (subtab === 'overview') { + if (!definition) { + return null; + } + if (definition.managed) { + return ( + + ); + } + return ; + } + const tabs = { route: { content: ( @@ -66,6 +79,15 @@ export function StreamDetailManagement({ ); } + if (!definition?.managed) { + return ( + + ); + } + const selectedTabObject = tabs[subtab]; return ( @@ -90,3 +112,84 @@ export function StreamDetailManagement({ ); } + +function assetToLink(asset: { type: string; id: string }) { + switch (asset.type) { + case 'index_template': + return `/app/management/data/index_management/templates/${asset.id}`; + case 'component_template': + return `/app/management/data/index_management/component_templates/${asset.id}`; + case 'data_stream': + return `/app/management/data/index_management/data_streams/${asset.id}`; + case 'ingest_pipeline': + return `/app/management/ingest/ingest_pipelines?pipeline=${asset.id}`; + default: + return ''; + } +} + +function assetToTitle(asset: { type: string; id: string }) { + switch (asset.type) { + case 'index_template': + return i18n.translate('xpack.streams.streamDetailView.indexTemplate', { + defaultMessage: 'Index template', + }); + case 'component_template': + return i18n.translate('xpack.streams.streamDetailView.componentTemplate', { + defaultMessage: 'Component template', + }); + case 'data_stream': + return i18n.translate('xpack.streams.streamDetailView.dataStream', { + defaultMessage: 'Data stream', + }); + case 'ingest_pipeline': + return i18n.translate('xpack.streams.streamDetailView.ingestPipeline', { + defaultMessage: 'Ingest pipeline', + }); + default: + return ''; + } +} + +function UnmanagedStreamOverview({ definition }: { definition: StreamDefinition }) { + const { + core: { + http: { basePath }, + }, + } = useKibana(); + const groupedAssets = (definition.unmanaged_elasticsearch_assets ?? []).reduce((acc, asset) => { + const title = assetToTitle(asset); + if (title) { + acc[title] = acc[title] ?? []; + acc[title].push(asset); + } + return acc; + }, {} as Record>); + return ( + + +

        + {i18n.translate('xpack.streams.streamDetailView.unmanagedStreamOverview', { + defaultMessage: + 'This stream is not managed. Follow the links to stack management to change the related Elasticsearch objects.', + })} +

        +
        + {Object.entries(groupedAssets).map(([title, assets]) => ( +
        + +

        {title}

        +
        + ({ + label: asset.id, + href: basePath.prepend(assetToLink(asset)), + iconType: 'index', + target: '_blank', + }))} + /> +
        + ))} +
        + ); +} diff --git a/x-pack/plugins/streams_app/public/components/stream_detail_view/index.tsx b/x-pack/plugins/streams_app/public/components/stream_detail_view/index.tsx index 4f213e855c175..d091fb5758a1e 100644 --- a/x-pack/plugins/streams_app/public/components/stream_detail_view/index.tsx +++ b/x-pack/plugins/streams_app/public/components/stream_detail_view/index.tsx @@ -63,5 +63,12 @@ export function StreamDetailView() { }, ]; - return ; + return ( + + ); } diff --git a/x-pack/plugins/streams_app/public/components/streams_app_page_header/streams_app_page_header_title.tsx b/x-pack/plugins/streams_app/public/components/streams_app_page_header/streams_app_page_header_title.tsx index ff7d6581dea4f..a0fcc554f5133 100644 --- a/x-pack/plugins/streams_app/public/components/streams_app_page_header/streams_app_page_header_title.tsx +++ b/x-pack/plugins/streams_app/public/components/streams_app_page_header/streams_app_page_header_title.tsx @@ -7,7 +7,7 @@ import { EuiTitle } from '@elastic/eui'; import React from 'react'; -export function StreamsAppPageHeaderTitle({ title }: { title: string }) { +export function StreamsAppPageHeaderTitle({ title }: { title: React.ReactNode }) { return (

        {title}

        diff --git a/x-pack/plugins/streams_app/public/components/streams_table/index.tsx b/x-pack/plugins/streams_app/public/components/streams_table/index.tsx index f92c94f115e9b..39814ed904555 100644 --- a/x-pack/plugins/streams_app/public/components/streams_table/index.tsx +++ b/x-pack/plugins/streams_app/public/components/streams_table/index.tsx @@ -46,10 +46,10 @@ export function StreamsTable({ name: i18n.translate('xpack.streams.streamsTable.nameColumnTitle', { defaultMessage: 'Name', }), - render: (_, { id }) => { + render: (_, { id, managed }) => { return ( - + ), }, diff --git a/x-pack/plugins/task_manager/server/index.ts b/x-pack/plugins/task_manager/server/index.ts index 79ec16b52987f..f2ad559f02b9c 100644 --- a/x-pack/plugins/task_manager/server/index.ts +++ b/x-pack/plugins/task_manager/server/index.ts @@ -104,4 +104,13 @@ export const config: PluginConfigDescriptor = { }, ]; }, + exposeToUsage: { + claim_strategy: true, + discovery: { + active_nodes_lookback: true, + }, + unsafe: { + exclude_task_types: true, + }, + }, }; diff --git a/x-pack/plugins/task_manager/server/task_store.test.ts b/x-pack/plugins/task_manager/server/task_store.test.ts index cbb1c44dde3fc..029aa2b1760ce 100644 --- a/x-pack/plugins/task_manager/server/task_store.test.ts +++ b/x-pack/plugins/task_manager/server/task_store.test.ts @@ -555,7 +555,14 @@ describe('TaskStore', () => { body: { size: 0, query: { - bool: { filter: [{ term: { type: 'task' } }, { term: { 'task.enabled': true } }] }, + bool: { + filter: { + bool: { + must: [{ term: { type: 'task' } }, { term: { 'task.enabled': true } }], + must_not: [{ term: { 'task.status': 'unrecognized' } }], + }, + }, + }, }, aggs: { testAgg: { terms: { field: 'task.taskType' } } }, }, @@ -578,7 +585,12 @@ describe('TaskStore', () => { must: [ { bool: { - filter: [{ term: { type: 'task' } }, { term: { 'task.enabled': true } }], + filter: { + bool: { + must: [{ term: { type: 'task' } }, { term: { 'task.enabled': true } }], + must_not: [{ term: { 'task.status': 'unrecognized' } }], + }, + }, }, }, { term: { 'task.taskType': 'bar' } }, @@ -600,7 +612,14 @@ describe('TaskStore', () => { body: { size: 0, query: { - bool: { filter: [{ term: { type: 'task' } }, { term: { 'task.enabled': true } }] }, + bool: { + filter: { + bool: { + must: [{ term: { type: 'task' } }, { term: { 'task.enabled': true } }], + must_not: [{ term: { 'task.status': 'unrecognized' } }], + }, + }, + }, }, aggs: { testAgg: { terms: { field: 'task.taskType' } } }, runtime_mappings: { testMapping: { type: 'long', script: { source: `` } } }, diff --git a/x-pack/plugins/task_manager/server/task_store.ts b/x-pack/plugins/task_manager/server/task_store.ts index 0946c5c18d328..6c48f3bd7552d 100644 --- a/x-pack/plugins/task_manager/server/task_store.ts +++ b/x-pack/plugins/task_manager/server/task_store.ts @@ -34,6 +34,7 @@ import { ConcreteTaskInstance, ConcreteTaskInstanceVersion, TaskInstance, + TaskStatus, TaskLifecycle, TaskLifecycleResult, SerializedConcreteTaskInstance, @@ -842,7 +843,12 @@ function ensureAggregationOnlyReturnsEnabledTaskObjects(opts: AggregationOpts): const originalQuery = opts.query; const filterToOnlyTasks = { bool: { - filter: [{ term: { type: 'task' } }, { term: { 'task.enabled': true } }], + filter: { + bool: { + must: [{ term: { type: 'task' } }, { term: { 'task.enabled': true } }], + must_not: [{ term: { 'task.status': TaskStatus.Unrecognized } }], + }, + }, }, }; const query = originalQuery diff --git a/x-pack/plugins/telemetry_collection_xpack/schema/xpack_plugins.json b/x-pack/plugins/telemetry_collection_xpack/schema/xpack_plugins.json index 257ad9c3af07b..b086844792217 100644 --- a/x-pack/plugins/telemetry_collection_xpack/schema/xpack_plugins.json +++ b/x-pack/plugins/telemetry_collection_xpack/schema/xpack_plugins.json @@ -15224,6 +15224,12 @@ } } }, + "fipsModeEnabled": { + "type": "boolean", + "_meta": { + "description": "Indicates if Kibana is being run in FIPS mode." + } + }, "httpAuthSchemes": { "type": "array", "items": { diff --git a/x-pack/plugins/timelines/server/types.ts b/x-pack/plugins/timelines/server/types.ts index 311281f67ea2a..b412b69be9737 100644 --- a/x-pack/plugins/timelines/server/types.ts +++ b/x-pack/plugins/timelines/server/types.ts @@ -6,7 +6,7 @@ */ import type { PluginSetup, PluginStart } from '@kbn/data-plugin/server'; -import { PluginStartContract as AlertingPluginStartContract } from '@kbn/alerting-plugin/server'; +import { AlertingServerStart } from '@kbn/alerting-plugin/server'; import { SecurityPluginSetup } from '@kbn/security-plugin/server'; // eslint-disable-next-line @typescript-eslint/no-empty-interface @@ -21,5 +21,5 @@ export interface SetupPlugins { export interface StartPlugins { data: PluginStart; - alerting: AlertingPluginStartContract; + alerting: AlertingServerStart; } diff --git a/x-pack/plugins/transform/server/lib/alerting/transform_health_rule_type/register_transform_health_rule_type.ts b/x-pack/plugins/transform/server/lib/alerting/transform_health_rule_type/register_transform_health_rule_type.ts index ac04ff6a7662e..1fe9c3cc59336 100644 --- a/x-pack/plugins/transform/server/lib/alerting/transform_health_rule_type/register_transform_health_rule_type.ts +++ b/x-pack/plugins/transform/server/lib/alerting/transform_health_rule_type/register_transform_health_rule_type.ts @@ -16,11 +16,7 @@ import type { RuleTypeState, } from '@kbn/alerting-plugin/common'; import { AlertsClientError } from '@kbn/alerting-plugin/server'; -import type { - PluginSetupContract as AlertingSetup, - IRuleTypeAlerts, - RuleType, -} from '@kbn/alerting-plugin/server'; +import type { AlertingServerSetup, IRuleTypeAlerts, RuleType } from '@kbn/alerting-plugin/server'; import type { FieldFormatsStart } from '@kbn/field-formats-plugin/server'; import type { TransformHealthAlert } from '@kbn/alerts-as-data-utils'; import { ALERT_REASON } from '@kbn/rule-data-utils'; @@ -74,7 +70,7 @@ export const TRANSFORM_ISSUE_DETECTED: ActionGroup = { interface RegisterParams { logger: Logger; - alerting: AlertingSetup; + alerting: AlertingServerSetup; getFieldFormatsStart: () => FieldFormatsStart; } diff --git a/x-pack/plugins/transform/server/routes/api/transforms_all/route_handler.ts b/x-pack/plugins/transform/server/routes/api/transforms_all/route_handler.ts index 8bbedd9faa023..4bf9a03b64882 100644 --- a/x-pack/plugins/transform/server/routes/api/transforms_all/route_handler.ts +++ b/x-pack/plugins/transform/server/routes/api/transforms_all/route_handler.ts @@ -28,10 +28,13 @@ export const routeHandler: RequestHandler< }); const alerting = await ctx.alerting; + if (alerting) { + const rulesClient = await alerting.getRulesClient(); + const transformHealthService = transformHealthServiceProvider({ esClient: esClient.asCurrentUser, - rulesClient: alerting.getRulesClient(), + rulesClient, }); // @ts-ignore diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index d63f6f793d07d..56176e11de600 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -191,14 +191,8 @@ "alertsUIShared.healthCheck.encryptionErrorTitle": "Configuration supplémentaire requise", "alertsUIShared.healthCheck.healthCheck.apiKeysAndEncryptionErrorTitle": "Configuration supplémentaire requise", "alertsUIShared.hooks.useAlertDataView.fetchErrorMessage": "Impossible de charger la vue des données de l'alerte", - "alertsUIShared.hooks.useFindAlertsQuery.unableToFetchAlertsGroupingAggregations": "Impossible de récupérer les agrégations de groupement d'alertes", "alertsUIShared.hooks.useFindAlertsQuery.unableToFindAlertsQueryMessage": "Impossible de trouver les alertes", "alertsUIShared.hooks.useLoadRuleTypesQuery.unableToLoadRuleTypesMessage": "Impossible de charger les types de règles", - "alertsUIShared.hooks.useRuleAADFields.errorMessage": "Impossible de charger les champs d'alerte par type de règle", - "alertsUIShared.licenseCheck.actionTypeDisabledByConfigMessageTitle": "Cette fonctionnalité est désactivée par la configuration de Kibana.", - "alertsUIShared.licenseCheck.actionTypeDisabledByLicenseLinkTitle": "Afficher les options de licence", - "alertsUIShared.licenseCheck.actionTypeDisabledByLicenseMessageDescription": "Pour réactiver cette action, veuillez mettre à niveau votre licence.", - "alertsUIShared.licenseCheck.actionTypeDisabledByLicenseMessageTitle": "Cette fonctionnalité requiert une licence {minimumLicenseRequired}.", "alertsUIShared.maintenanceWindowCallout.fetchError": "La vérification visant à déterminer si les fenêtres de maintenance sont actives a échoué", "alertsUIShared.maintenanceWindowCallout.fetchErrorDescription": "Les notifications de règle sont arrêtées lorsque les fenêtres de maintenance sont en cours d'exécution.", "alertsUIShared.maintenanceWindowCallout.maintenanceWindowActive": "{activeWindowCount, plural, one {Une fenêtre de maintenance est} other {Des fenêtres de maintenance sont}} en cours d'exécution pour des règles de {categories}", @@ -2734,11 +2728,7 @@ "discover.advancedSettings.context.tieBreakerFieldsTitle": "Champs de départage", "discover.advancedSettings.defaultColumnsText": "Les colonnes affichées par défaut dans l'application Discover. Si elles sont vides, un résumé du document s’affiche.", "discover.advancedSettings.defaultColumnsTitle": "Colonnes par défaut", - "discover.advancedSettings.disableDocumentExplorer": "Explorateur de documents ou vue classique", - "discover.advancedSettings.disableDocumentExplorerDescription": "Désactivez cette option pour utiliser le nouveau {documentExplorerDocs} au lieu de la vue classique. l'explorateur de documents offre un meilleur tri des données, des colonnes redimensionnables et une vue en plein écran.", - "discover.advancedSettings.discover.disableDocumentExplorerDeprecation": "Ce paramètre est déclassé et sera supprimé dans la version 9.0 de Kibana.", "discover.advancedSettings.discover.fieldStatisticsLinkText": "Vue des statistiques de champ", - "discover.advancedSettings.discover.maxCellHeightDeprecation": "Ce paramètre est déclassé et sera supprimé dans la version 9.0 de Kibana.", "discover.advancedSettings.discover.modifyColumnsOnSwitchText": "Supprimez les colonnes qui ne sont pas disponibles dans la nouvelle vue de données.", "discover.advancedSettings.discover.modifyColumnsOnSwitchTitle": "Modifier les colonnes en cas de changement des vues de données", "discover.advancedSettings.discover.multiFieldsLinkText": "champs multiples", @@ -2751,13 +2741,10 @@ "discover.advancedSettings.discover.showMultifieldsDescription": "Détermine si les {multiFields} doivent s'afficher dans la fenêtre de document étendue. Dans la plupart des cas, les champs multiples sont les mêmes que les champs d'origine. Cette option est uniquement disponible lorsque le paramètre `searchFieldsFromSource` est désactivé.", "discover.advancedSettings.docTableHideTimeColumnText": "Permet de masquer la colonne ''Time'' dans Discover et dans toutes les recherches enregistrées des tableaux de bord.", "discover.advancedSettings.docTableHideTimeColumnTitle": "Masquer la colonne ''Time''", - "discover.advancedSettings.documentExplorerLinkText": "Explorateur de documents", "discover.advancedSettings.fieldsPopularLimitText": "Les N champs les plus populaires à afficher", "discover.advancedSettings.fieldsPopularLimitTitle": "Limite de champs populaires", "discover.advancedSettings.maxDocFieldsDisplayedText": "Le nombre maximal de champs renvoyés dans le résumé du document", "discover.advancedSettings.maxDocFieldsDisplayedTitle": "Nombre maximal de champs de document affichés", - "discover.advancedSettings.params.maxCellHeightText": "La hauteur maximale qu'une cellule de tableau peut atteindre. Définissez ce paramètre sur 0 pour désactiver la troncation.", - "discover.advancedSettings.params.maxCellHeightTitle": "Hauteur de cellule maximale dans le tableau classique", "discover.advancedSettings.params.rowHeightText": "Nombre de sous-lignes à autoriser dans une ligne. La valeur -1 ajuste automatiquement la hauteur de ligne selon le contenu. La valeur 0 affiche le contenu en une seule ligne.", "discover.advancedSettings.params.rowHeightTitle": "Hauteur de ligne dans l'explorateur de documents", "discover.advancedSettings.sampleRowsPerPageText": "Limite le nombre de lignes par page dans le tableau de documents.", @@ -2773,7 +2760,6 @@ "discover.alerts.createSearchThreshold": "Créer une règle de seuil de recherche", "discover.alerts.manageRulesAndConnectors": "Gérer les règles et les connecteurs", "discover.alerts.missedTimeFieldToolTip": "La vue de données ne possède pas de champ temporel.", - "discover.backToTopLinkText": "Revenir en haut de la page.", "discover.badge.readOnly.text": "Lecture seule", "discover.badge.readOnly.tooltip": "Impossible d’enregistrer les recherches", "discover.context.breadcrumb": "Documents relatifs", @@ -2782,7 +2768,6 @@ "discover.context.failedToLoadAnchorDocumentErrorDescription": "Le document ancré n’a pas pu être chargé.", "discover.context.invalidTieBreakerFiledSetting": "Paramètre de champ de départage non valide", "discover.context.loadButtonLabel": "Charger", - "discover.context.loadingDescription": "Chargement...", "discover.context.newerDocumentsAriaLabel": "Nombre de documents plus récents", "discover.context.newerDocumentsDescription": "documents plus récents", "discover.context.newerDocumentsWarning": "Seuls {docCount} documents plus récents que le document ancré ont été trouvés.", @@ -2819,39 +2804,8 @@ "discover.doc.pageTitle": "Document unique - #{id}", "discover.doc.somethingWentWrongDescription": "Index {indexName} manquant.", "discover.doc.somethingWentWrongDescriptionAddon": "Veuillez vérifier que cet index existe.", - "discover.docExplorerCallout.closeButtonAriaLabel": "Fermer", - "discover.docExplorerCallout.documentExplorer": "Explorateur de documents", - "discover.docExplorerCallout.headerMessage": "Une meilleure façon d'explorer", - "discover.docExplorerCallout.learnMore": "En savoir plus", - "discover.docExplorerCallout.tryDocumentExplorer": "Testez l'explorateur de documents", - "discover.docTable.documentsNavigation": "Navigation dans les documents", - "discover.docTable.limitedSearchResultLabel": "Limité à {resultCount} résultats. Veuillez affiner votre recherche.", - "discover.docTable.noResultsTitle": "Résultat introuvable", - "discover.docTable.rows": "lignes", - "discover.docTable.rowsPerPage": "Lignes par page : {pageSize}", - "discover.docTable.tableHeader.documentHeader": "Document", - "discover.docTable.tableHeader.moveColumnLeftButtonAriaLabel": "Déplacer la colonne {columnName} vers la gauche", - "discover.docTable.tableHeader.moveColumnLeftButtonTooltip": "Déplacer la colonne vers la gauche", - "discover.docTable.tableHeader.moveColumnRightButtonAriaLabel": "Déplacer la colonne {columnName} vers la droite", - "discover.docTable.tableHeader.moveColumnRightButtonTooltip": "Déplacer la colonne vers la droite", - "discover.docTable.tableHeader.removeColumnButtonAriaLabel": "Supprimer la colonne {columnName}", - "discover.docTable.tableHeader.removeColumnButtonTooltip": "Supprimer la colonne", - "discover.docTable.tableHeader.sortByColumnAscendingAriaLabel": "Trier la colonne {columnName} par ordre croissant", - "discover.docTable.tableHeader.sortByColumnDescendingAriaLabel": "Trier la colonne {columnName} par ordre décroissant", - "discover.docTable.tableHeader.sortByColumnUnsortedAriaLabel": "Arrêter de trier la colonne {columnName}", - "discover.docTable.tableHeader.timeFieldIconTooltip": "Ce champ représente l'heure à laquelle les événements se sont produits.", - "discover.docTable.tableHeader.timeFieldIconTooltipAriaLabel": "{timeFieldName} : ce champ représente l'heure à laquelle les événements se sont produits.", - "discover.docTable.tableRow.detailHeading": "Document développé", - "discover.docTable.tableRow.filterForValueButtonAriaLabel": "Filtrer sur la valeur", - "discover.docTable.tableRow.filterForValueButtonTooltip": "Filtrer sur la valeur", - "discover.docTable.tableRow.filterOutValueButtonAriaLabel": "Exclure la valeur", - "discover.docTable.tableRow.filterOutValueButtonTooltip": "Exclure la valeur", - "discover.docTable.tableRow.toggleRowDetailsButtonAriaLabel": "Afficher/Masquer les détails de la ligne", - "discover.docTable.tableRow.viewSingleDocumentLinkText": "Afficher un seul document", - "discover.docTable.tableRow.viewSurroundingDocumentsLinkText": "Afficher les documents alentour", "discover.documentsAriaLabel": "Documents", "discover.docViews.logsOverview.title": "Aperçu du log", - "discover.docViews.table.scoreSortWarningTooltip": "Filtrez sur _score pour pouvoir récupérer les valeurs correspondantes.", "discover.dropZoneTableLabel": "Abandonner la zone pour ajouter un champ en tant que colonne dans la table", "discover.embeddable.inspectorRequestDataTitle": "Données", "discover.embeddable.inspectorRequestDescription": "Cette requête interroge Elasticsearch afin de récupérer les données pour la recherche.", @@ -2873,7 +2827,6 @@ "discover.globalSearch.esqlSearchTitle": "Créer des recherches ES|QL", "discover.goToDiscoverButtonText": "Aller à Discover", "discover.grid.tableRow.actionsLabel": "Actions", - "discover.grid.tableRow.esqlDetailHeading": "Résultat étendu", "discover.grid.tableRow.mobileFlyoutActionsButton": "Actions", "discover.grid.tableRow.moreFlyoutActionsButton": "Plus d'actions", "discover.grid.tableRow.viewSingleDocumentLinkLabel": "Afficher un seul document", @@ -2884,7 +2837,6 @@ "discover.hitsCounter.hitsPluralTitle": "{formattedHits} {hits, plural, one {résultat} other {résultats}}", "discover.hitsCounter.partialHits": "≥{formattedHits}", "discover.hitsCounter.partialHitsPluralTitle": "≥{formattedHits} {hits, plural, one {résultat} other {résultats}}", - "discover.howToSeeOtherMatchingDocumentsDescription": "Voici les {sampleSize} premiers documents correspondant à votre recherche. Veuillez affiner celle-ci pour en voir plus.", "discover.inspectorEsqlRequestDescription": "Cette requête interroge Elasticsearch afin de récupérer les résultats pour le tableau.", "discover.inspectorEsqlRequestTitle": "Tableau", "discover.inspectorRequestDataTitleDocuments": "Documents", @@ -2893,7 +2845,6 @@ "discover.invalidFiltersWarnToast.description": "Les références d'ID de la vue de données dans certains filtres appliqués diffèrent de la vue de données actuelle.", "discover.invalidFiltersWarnToast.title": "Références d'index différentes", "discover.loadingDocuments": "Chargement des documents", - "discover.loadingResults": "Chargement des résultats", "discover.localMenu.alertsDescription": "Alertes", "discover.localMenu.esqlTooltipLabel": "ES|QL est le nouveau langage de requête canalisé puissant d'Elastic.", "discover.localMenu.fallbackReportTitle": "Recherche Discover sans titre", @@ -8314,24 +8265,16 @@ "unifiedDocViewer.docView.table.searchPlaceHolder": "Rechercher des noms ou valeurs de champs", "unifiedDocViewer.docViews.json.jsonTitle": "JSON", "unifiedDocViewer.docViews.table.esqlMultivalueFilteringDisabled": "Le filtrage multivalué n'est pas pris en charge dans ES|QL", - "unifiedDocViewer.docViews.table.filterForFieldPresentButtonAriaLabel": "Filtrer sur le champ", "unifiedDocViewer.docViews.table.filterForFieldPresentButtonTooltip": "Filtrer sur le champ", - "unifiedDocViewer.docViews.table.filterForValueButtonAriaLabel": "Filtrer sur la valeur", "unifiedDocViewer.docViews.table.filterForValueButtonTooltip": "Filtrer sur la valeur", - "unifiedDocViewer.docViews.table.filterOutValueButtonAriaLabel": "Exclure la valeur", "unifiedDocViewer.docViews.table.filterOutValueButtonTooltip": "Exclure la valeur", "unifiedDocViewer.docViews.table.ignored.multiValueLabel": "Contient des valeurs ignorées", "unifiedDocViewer.docViews.table.ignored.singleValueLabel": "Valeur ignorée", "unifiedDocViewer.docViews.table.ignoredValuesCanNotBeSearchedWarningMessage": "Les valeurs ignorées ne peuvent pas être recherchées", "unifiedDocViewer.docViews.table.pinFieldLabel": "Épingler le champ", "unifiedDocViewer.docViews.table.tableTitle": "Tableau", - "unifiedDocViewer.docViews.table.toggleColumnInTableButtonAriaLabel": "Afficher/Masquer la colonne dans le tableau", - "unifiedDocViewer.docViews.table.toggleColumnInTableButtonTooltip": "Afficher/Masquer la colonne dans le tableau", "unifiedDocViewer.docViews.table.toggleColumnTableButtonTooltip": "Afficher/Masquer la colonne dans le tableau", - "unifiedDocViewer.docViews.table.unableToFilterForPresenceOfMetaFieldsTooltip": "Impossible de filtrer sur les champs méta", - "unifiedDocViewer.docViews.table.unableToFilterForPresenceOfScriptedFieldsTooltip": "Impossible de filtrer sur les champs scriptés", "unifiedDocViewer.docViews.table.unableToFilterForPresenceOfScriptedFieldsWarningMessage": "Impossible de filtrer sur les champs scriptés", - "unifiedDocViewer.docViews.table.unindexedFieldsCanNotBeSearchedTooltip": "Les champs non indexés ou les valeurs ignorées ne peuvent pas être recherchés", "unifiedDocViewer.docViews.table.unindexedFieldsCanNotBeSearchedWarningMessage": "Il est impossible d’effectuer une recherche sur des champs non indexés", "unifiedDocViewer.docViews.table.unpinFieldLabel": "Désépingler le champ", "unifiedDocViewer.docViews.table.viewLessButton": "Afficher moins", @@ -8341,7 +8284,6 @@ "unifiedDocViewer.fieldActions.filterForValue": "Filtrer sur la valeur", "unifiedDocViewer.fieldActions.filterOutValue": "Exclure la valeur", "unifiedDocViewer.fieldActions.toggleColumn": "Afficher/Masquer la colonne dans le tableau", - "unifiedDocViewer.fieldChooser.discoverField.actions": "Actions", "unifiedDocViewer.fieldChooser.discoverField.multiField": "champ multiple", "unifiedDocViewer.fieldChooser.discoverField.multiFieldTooltipContent": "Les champs multiples peuvent avoir plusieurs valeurs.", "unifiedDocViewer.fieldChooser.discoverField.name": "Champ", @@ -15310,7 +15252,6 @@ "xpack.datasetQuality.details.fetchDataStreamDetailsFailed": "Nous n'avons pas pu obtenir les détails de votre flux de données.", "xpack.datasetQuality.details.fetchDataStreamSettingsFailed": "Les paramètres du flux de données n'ont pas pu être chargés.", "xpack.datasetQuality.details.fetchIntegrationDashboardsFailed": "Nous n'avons pas pu obtenir vos tableaux de bord d'intégration.", - "xpack.datasetQuality.details.fetchIntegrationsFailed": "Nous n'avons pas pu obtenir les informations relatives à l'intégration de {integrationName}.", "xpack.datasetQuality.details.indexTemplateActionText": "Modèle d'index", "xpack.datasetQuality.details.integrationActionsText": "Actions d'intégration", "xpack.datasetQuality.details.integrationnameText": "Intégration", @@ -17410,8 +17351,6 @@ "xpack.enterpriseSearch.content.analytics.api.generateAnalyticsApiKeyModal.done": "Terminé", "xpack.enterpriseSearch.content.analytics.api.generateAnalyticsApiKeyModal.generateButton": "Générer une clé", "xpack.enterpriseSearch.content.analytics.api.generateAnalyticsApiKeyModal.title": "Créer une clé d'API d'analyse", - "xpack.enterpriseSearch.content.cannotConnect.body": "En savoir plus.", - "xpack.enterpriseSearch.content.cannotConnect.title": "Impossible de se connecter à Enterprise Search", "xpack.enterpriseSearch.content.conectors.indexHealth": "Intègre", "xpack.enterpriseSearch.content.connector_detail.configurationConnector.badgeType.connectorClient": "Connecteur autogéré", "xpack.enterpriseSearch.content.connector_detail.configurationConnector.badgeType.nativeConnector": "Connecteur géré par Elastic", @@ -17436,7 +17375,6 @@ "xpack.enterpriseSearch.content.connector_detail.configurationConnector.steps.waitingForConnector.callout.finishLaterButton.label": "Terminer le déploiement plus tard", "xpack.enterpriseSearch.content.connector_detail.configurationConnector.steps.waitingForConnector.callout.title": "En attente de votre connecteur", "xpack.enterpriseSearch.content.connector_detail.configurationConnector.steps.waitingForConnector.title": "En attente du contrôle de votre connecteur", - "xpack.enterpriseSearch.content.connector_detail.nativeConfigurationConnector.apiKey.title": "Clé d'API", "xpack.enterpriseSearch.content.connector_detail.nativeConfigurationConnector.configuration.title": "Configuration", "xpack.enterpriseSearch.content.connectors.breadcrumb": "Connecteurs", "xpack.enterpriseSearch.content.connectors.connectorDetail.configurationTabLabel": "Configuration", @@ -17603,8 +17541,6 @@ "xpack.enterpriseSearch.content.indices.configurationConnector.nativeConnector.convertConnector.description": "Vous souhaitez héberger vous-même ce connecteur ? Convertissez-le en {link} afin qu'il soit géré sur votre propre infrastructure. Vous devez convertir ce connecteur si vous souhaitez personnaliser le code à l'aide de notre cadre Python.", "xpack.enterpriseSearch.content.indices.configurationConnector.nativeConnector.convertConnector.linkTitle": "connecteur autogéré", "xpack.enterpriseSearch.content.indices.configurationConnector.nativeConnector.convertConnector.title": "Autogestion de ce connecteur", - "xpack.enterpriseSearch.content.indices.configurationConnector.nativeConnector.entSearchWarning.text": "Les connecteurs gérés par Elastic nécessitent une instance Enterprise Search en cours d'exécution.", - "xpack.enterpriseSearch.content.indices.configurationConnector.nativeConnector.entSearchWarning.title": "Aucune instance Enterprise Search en cours d'exécution détectée", "xpack.enterpriseSearch.content.indices.configurationConnector.nativeConnectorAdvancedConfiguration.description": "Finalisez votre connecteur en déclenchant une synchronisation unique, ou en définissant un calendrier de synchronisation récurrent.", "xpack.enterpriseSearch.content.indices.configurationConnector.nativeConnectorAdvancedConfiguration.schedulingButtonLabel": "Définir un calendrier et synchroniser", "xpack.enterpriseSearch.content.indices.configurationConnector.researchConfiguration.connectorDocumentationLinkLabel": "Documentation", @@ -17957,7 +17893,6 @@ "xpack.enterpriseSearch.content.playground.breadcrumb": "Playground", "xpack.enterpriseSearch.content.searchIndex.cancelSync.successMessage": "Annulation réussie de la synchronisation", "xpack.enterpriseSearch.content.searchIndex.cancelSyncs.successMessage": "Annulation réussie des synchronisations", - "xpack.enterpriseSearch.content.searchIndex.cannotConnect.body": "Le robot d'indexation Elastic requiert Enterprise Search. {link}", "xpack.enterpriseSearch.content.searchIndex.configurationTabLabel": "Configuration", "xpack.enterpriseSearch.content.searchIndex.connectorErrorCallOut.title": "Votre connecteur a rapporté une erreur", "xpack.enterpriseSearch.content.searchIndex.crawlerConfigurationTabLabel": "Configuration", @@ -18295,7 +18230,6 @@ "xpack.enterpriseSearch.createConnector.configurationStep.configurationLabel": "Configuration", "xpack.enterpriseSearch.createConnector.configurationStep.h4.finishUpLabel": "Terminer", "xpack.enterpriseSearch.createConnector.configurationStep.p.description": "Vous pouvez synchroniser manuellement vos données, planifier une synchronisation récurrente ou gérer vos domaines.", - "xpack.enterpriseSearch.createConnector.connectorDescriptionBadge.notAvailableTitle": "Ce connecteur n'est pas disponible en tant que connecteur géré par Elastic", "xpack.enterpriseSearch.createConnector.connectorDocsLinkLabel": "référence du connecteur", "xpack.enterpriseSearch.createConnector.DeploymentStep.Configuration.description": "Maintenant, configurez votre robot Elastic et synchronisez les données.", "xpack.enterpriseSearch.createConnector.DeploymentStep.Configuration.title": "Configuration", @@ -18370,17 +18304,6 @@ "xpack.enterpriseSearch.enterpriseSearch.setupGuide.videoAlt": "Premiers pas avec Enterprise Search", "xpack.enterpriseSearch.enterpriseSearchCard.cta": "En savoir plus", "xpack.enterpriseSearch.entSearch.productCardDescription": "Applications standalone adaptées à des expériences de recherche plus simples, conviviales et axées sur les entreprises.", - "xpack.enterpriseSearch.errorConnectingCallout.setupGuideCta": "Consulter le guide de configuration", - "xpack.enterpriseSearch.errorConnectingCallout.title": "Impossible de se connecter à Enterprise Search", - "xpack.enterpriseSearch.errorConnectingState.cloudErrorMessage": "Les nœuds Enterprise Search fonctionnent-ils dans votre déploiement cloud ? {deploymentSettingsLink}", - "xpack.enterpriseSearch.errorConnectingState.cloudErrorMessageLinkText": "Vérifier vos paramètres de déploiement", - "xpack.enterpriseSearch.errorConnectingState.description1": "Impossible d'établir une connexion à Enterprise Search avec l'URL hôte {enterpriseSearchUrl} en raison de l'erreur suivante :", - "xpack.enterpriseSearch.errorConnectingState.description2": "Vérifiez que l'URL hôte est correctement configurée dans {configFile}.", - "xpack.enterpriseSearch.errorConnectingState.description3": "Assurez-vous que le serveur d'Enterprise Search est en état de répondre.", - "xpack.enterpriseSearch.errorConnectingState.setupGuideCta": "Consulter le guide de configuration", - "xpack.enterpriseSearch.errorConnectingState.title": "Impossible d'établir une connexion", - "xpack.enterpriseSearch.errorConnectingState.troubleshootAuth": "Vérifiez votre authentification utilisateur :", - "xpack.enterpriseSearch.errorConnectingState.troubleshootAuthMessage": "Contactez votre administrateur pour installer un mapping des rôles pour vous donner accès à Enterprise Search", "xpack.enterpriseSearch.exampleConnectorLabel": "Exemple", "xpack.enterpriseSearch.finishUpStep.euiButton.viewInDiscoverLabel": "Afficher dans Discover", "xpack.enterpriseSearch.getConnectorTypeBadge.connectorClientBadgeLabel": "Autogéré", @@ -18529,9 +18452,6 @@ "xpack.enterpriseSearch.navigation.contentPlaygroundLinkLabel": "Playground", "xpack.enterpriseSearch.navigation.contentWebcrawlersLinkLabel": "Robots d'indexation", "xpack.enterpriseSearch.navigation.relevanceInferenceEndpointsLinkLabel": "Points de terminaison d'inférence", - "xpack.enterpriseSearch.noEntSearch.noCrawler": "Le robot d'indexation d'Elastic n'est pas disponible sans Entreprise Search.", - "xpack.enterpriseSearch.noEntSearch.setupGuideCta": "Consulter le guide de configuration", - "xpack.enterpriseSearch.noEntSearchConfigured.title": "Enterprise Search n'a pas encore été configuré", "xpack.enterpriseSearch.notFound.action1": "Retour à votre tableau de bord", "xpack.enterpriseSearch.notFound.action2": "Contacter le support technique", "xpack.enterpriseSearch.notFound.description": "Impossible de trouver la page que vous recherchez.", @@ -18800,7 +18720,6 @@ "xpack.enterpriseSearch.searchApplications.searchApplication.indices.searchPlaceholder": "Filtrer les index", "xpack.enterpriseSearch.searchApplications.searchApplication.indices.someUnknownIndicesCallout.description": "Certaines données peuvent être inaccessibles à partir de cette application de recherche. Recherchez les opérations en attente ou les erreurs sur les index concernés, ou supprimez les index qui ne doivent plus être utilisés par cette application de recherche.", "xpack.enterpriseSearch.searchApplications.searchApplication.indices.someUnknownIndicesCallout.title": "Certains de vos index ne sont pas disponibles.", - "xpack.enterpriseSearch.searchApplications.searchApplication.notFound.action1": "Revenir aux applications de recherche", "xpack.enterpriseSearch.searchApplications.searchApplication.schema.conflictsCallOut.button": "Afficher les conflits", "xpack.enterpriseSearch.searchApplications.searchApplication.schema.conflictsCallOut.description": "Les conflits de type de champ de schéma peuvent être résolus en navigant directement sur l’index source et en mettant à jour le type de champ du ou des champs conflictuels afin qu’il corresponde à celui des autres index sources.", "xpack.enterpriseSearch.searchApplications.searchApplication.schema.conflictsCallOut.title": "Problèmes potentiels de mapping de champ trouvés", @@ -19014,10 +18933,6 @@ "xpack.enterpriseSearch.vectorSearch.guide.query.title": "Effectuer une recherche vectorielle", "xpack.enterpriseSearch.vectorSearch.navTitle": "Recherche vectorielle", "xpack.enterpriseSearch.vectorSearch.productName": "Recherche vectorielle", - "xpack.enterpriseSearch.versionMismatch.body": "Vos versions de Kibana et d'Enterprise Search ne correspondent pas. Pour accéder à Enterprise Search, utilisez la même version majeure et mineure pour chaque service.", - "xpack.enterpriseSearch.versionMismatch.enterpriseSearchVersionText": "Version d'Enterprise Search : {enterpriseSearchVersion}", - "xpack.enterpriseSearch.versionMismatch.kibanaVersionText": "Version de Kibana: {kibanaVersion}", - "xpack.enterpriseSearch.versionMismatch.title": "Erreur de version incompatible", "xpack.enterpriseSearch.welcomeBanner.header.greeting.customTitle": "👋 Bonjour {name} !", "xpack.enterpriseSearch.welcomeBanner.header.greeting.defaultTitle": "👋 Bonjour", "xpack.enterpriseSearch.welcomeBanner.header.title": "Ajouter des données à Elasticsearch et rechercher, vectoriser ou visualiser", @@ -22644,10 +22559,6 @@ "xpack.idxMgmt.home.componentTemplates.list.loadingMessage": "Chargement des modèles de composants en cours…", "xpack.idxMgmt.home.componentTemplatesTabTitle": "Modèles de composants", "xpack.idxMgmt.home.dataStreamsTabTitle": "Flux de données", - "xpack.idxMgmt.home.enrichPolicies.checkingPrivilegesDescription": "Vérification des privilèges…", - "xpack.idxMgmt.home.enrichPolicies.checkingPrivilegesErrorMessage": "Erreur lors de la récupération des privilèges utilisateur depuis le serveur.", - "xpack.idxMgmt.home.enrichPolicies.deniedPrivilegeDescription": "Pour utiliser les Politiques d'enrichissement, vous devez disposer des privilèges de cluster suivants : {missingPrivileges}.", - "xpack.idxMgmt.home.enrichPolicies.deniedPrivilegeTitle": "Gestion des privilèges d'enrichissement requise", "xpack.idxMgmt.home.enrichPoliciesTabTitle": "Politiques d'enrichissement", "xpack.idxMgmt.home.idxMgmtDescription": "Mettez à jour vos index Elasticsearch individuellement ou par lots. {learnMoreLink}", "xpack.idxMgmt.home.idxMgmtDocsLinkText": "Documentation sur la gestion des index", @@ -37184,8 +37095,6 @@ "xpack.securitySolution.assistant.quickPrompts.alertSummarizationTitle": "Synthèse de l’alerte", "xpack.securitySolution.assistant.quickPrompts.AutomationPrompt": "Quelle intégration d’Elastic Agent activée par Fleet dois-je utiliser pour collecter des logs et des évènements de :", "xpack.securitySolution.assistant.quickPrompts.AutomationTitle": "Conseil sur l’intégration d’agent", - "xpack.securitySolution.assistant.quickPrompts.esqlQueryGenerationPrompt": "En tant qu'utilisateur expert d'Elastic Security, veuillez générer une requête ESQL valide et précise pour détecter le cas d'utilisation ci-dessous. Votre réponse doit être formatée pour pouvoir être utilisée immédiatement dans une chronologie ou une règle de détection d’Elastic Security. Prenez votre temps pour répondre, vérifiez bien vos connaissances et toutes les fonctions que je vous demande. Pour les réponses ES|QL en particulier, vous devez toujours répondre uniquement avec ce qui est disponible dans vos connaissances personnelles. Je ne peux pas me permettre que les requêtes soient inexactes. Supposez que j'utilise le Elastic Common Schema et l'agent Elastic. Veillez à ce que les réponses soient formatées de manière à pouvoir être facilement copiées sous la forme d'un bloc de code distinct dans le markdown.", - "xpack.securitySolution.assistant.quickPrompts.esqlQueryGenerationTitle": "Génération de requête ES|QL", "xpack.securitySolution.assistant.quickPrompts.ruleCreationPrompt": "En tant qu’utilisateur expert d’Elastic Security, veuillez générer une requête EQL valide et précise pour détecter le cas d’utilisation ci-dessous. Votre réponse doit être formatée pour pouvoir être utilisée immédiatement dans une chronologie ou une règle de détection d’Elastic Security. Si Elastic Security a déjà une règle prédéfinie pour le cas d’utilisation ou pour un cas similaire, veuillez fournir un lien vers cette règle et la décrire.", "xpack.securitySolution.assistant.quickPrompts.ruleCreationTitle": "Génération de requête", "xpack.securitySolution.assistant.quickPrompts.splQueryConversionPrompt": "J’ai la requête suivante d’une plateforme SIEM précédente. En tant qu’utilisateur expert d’Elastic Security, veuillez suggérer un équivalent EQL Elastic. Je dois être capable de la copier immédiatement dans une chronologie Elastic Security.", @@ -40397,7 +40306,6 @@ "xpack.securitySolution.entityAnalytics.assetCriticalityUploadPage.noPermissionTitle": "Privilèges d'index insuffisants pour effectuer le chargement de fichiers CSV", "xpack.securitySolution.entityAnalytics.assetCriticalityUploadPage.resultsStepTitle": "Résultats", "xpack.securitySolution.entityAnalytics.assetCriticalityUploadPage.selectFileStepTitle": "Sélectionner un fichier", - "xpack.securitySolution.entityAnalytics.assetCriticalityUploadPage.subTitle": "Importer des entités à l'aide d'un fichier texte", "xpack.securitySolution.entityAnalytics.assetCriticalityUploadPage.unavailable": "La fonctionnalité de chargement de fichiers CSV de criticité des ressources n'est pas disponible.", "xpack.securitySolution.entityAnalytics.assetCriticalityUploadPage.unsupportedFileTypeError": "Format de fichier sélectionné non valide. Veuillez choisir un fichier {supportedFileExtensions} et réessayer", "xpack.securitySolution.entityAnalytics.assetCriticalityUploadPage.uploadFileSizeLimit": "La taille maximale de fichier est de : {maxFileSize}", @@ -40439,7 +40347,6 @@ "xpack.securitySolution.entityAnalytics.entityStoreManagementPage.clearEntitiesModal.clearAllEntities": "Effacer toutes les entités", "xpack.securitySolution.entityAnalytics.entityStoreManagementPage.clearEntitiesModal.close": "Fermer", "xpack.securitySolution.entityAnalytics.entityStoreManagementPage.clearEntitiesModal.title": "Effacer les données des entités ?", - "xpack.securitySolution.entityAnalytics.entityStoreManagementPage.clearEntityData": "Supprimez toutes les données d'entité extraites du stockage. Cette action supprimera définitivement les enregistrements d’utilisateur et d'hôte persistants, les données ne seront par ailleurs plus disponibles pour l'analyse. Procédez avec prudence, car cette opération est irréversible. Notez que cette opération ne supprimera pas les données sources, les scores de risque des entités ni les attributions de criticité des ressources.", "xpack.securitySolution.entityAnalytics.entityStoreManagementPage.featureFlagDisabled": "Les fonctionnalités du stockage d'entités ne sont pas disponibles", "xpack.securitySolution.entityAnalytics.entityStoreManagementPage.subTitle": "Permet un monitoring complet des hôtes et des utilisateurs de votre système.", "xpack.securitySolution.entityAnalytics.entityStoreManagementPage.title": "Stockage d'entités", @@ -46260,7 +46167,6 @@ "xpack.synthetics.failedStep.label": "Étape ayant échoué", "xpack.synthetics.fcp.label": "FCP", "xpack.synthetics.featureRegistry.syntheticsFeatureName": "Synthetics et Uptime", - "xpack.synthetics.features.app": "Synthetics", "xpack.synthetics.features.elasticManagedLocations": "Emplacements gérés par Elastic activés", "xpack.synthetics.fieldLabels.cls": "Cumulative Layout Shift (CLS)", "xpack.synthetics.fieldLabels.dcl": "Événement DOMContentLoaded (DCL)", @@ -48635,7 +48541,6 @@ "xpack.triggersActionsUI.updateApiKeyConfirmModal.failureMessage": "Impossible de mettre à jour {idsToUpdate, plural, one {la clé} other {les clés}} de l'API", "xpack.triggersActionsUI.updateApiKeyConfirmModal.title": "Mettre à jour la clé d'API", "xpack.triggersActionsUI.urlSyncedAlertsSearchBar.invalidQueryTitle": "Chaîne de requête non valide", - "xpack.triggersActionsUI.useRuleAADFields.errorMessage": "Impossible de charger les champs d'alerte par type de règle", "xpack.upgradeAssistant.app.deniedPrivilegeDescription": "Afin d'utiliser l'assistant de mise à niveau et de résoudre les problèmes de déclassement, vous devez disposer d'un accès permettant de gérer tous les espaces Kibana.", "xpack.upgradeAssistant.app.deniedPrivilegeTitle": "Rôle d'administrateur Kibana requis", "xpack.upgradeAssistant.appTitle": "Assistant de mise à niveau", diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 76f11aa37e19d..1d077b0f089bf 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -191,14 +191,8 @@ "alertsUIShared.healthCheck.encryptionErrorTitle": "追加の設定が必要です", "alertsUIShared.healthCheck.healthCheck.apiKeysAndEncryptionErrorTitle": "追加の設定が必要です", "alertsUIShared.hooks.useAlertDataView.fetchErrorMessage": "アラートデータビューを読み込めません", - "alertsUIShared.hooks.useFindAlertsQuery.unableToFetchAlertsGroupingAggregations": "アラートグループ集約を取得できません。", "alertsUIShared.hooks.useFindAlertsQuery.unableToFindAlertsQueryMessage": "アラートが見つかりません", "alertsUIShared.hooks.useLoadRuleTypesQuery.unableToLoadRuleTypesMessage": "ルールタイプを読み込めません", - "alertsUIShared.hooks.useRuleAADFields.errorMessage": "ルールタイプごとにアラートフィールドを読み込めません", - "alertsUIShared.licenseCheck.actionTypeDisabledByConfigMessageTitle": "この機能は Kibana の構成で無効になっています。", - "alertsUIShared.licenseCheck.actionTypeDisabledByLicenseLinkTitle": "ライセンスオプションを表示", - "alertsUIShared.licenseCheck.actionTypeDisabledByLicenseMessageDescription": "このアクションを再び有効にするには、ライセンスをアップグレードしてください。", - "alertsUIShared.licenseCheck.actionTypeDisabledByLicenseMessageTitle": "この機能には {minimumLicenseRequired} ライセンスが必要です。", "alertsUIShared.maintenanceWindowCallout.fetchError": "保守時間枠がアクティブであるかどうかを確認できませんでした", "alertsUIShared.maintenanceWindowCallout.fetchErrorDescription": "保守時間枠の実行中は、ルール通知が停止されます。", "alertsUIShared.maintenanceWindowCallout.maintenanceWindowActive": "{categories}ルールの{activeWindowCount, plural, other {保守時間枠}}が実行中です", @@ -2733,11 +2727,7 @@ "discover.advancedSettings.context.tieBreakerFieldsTitle": "タイブレーカーフィールド", "discover.advancedSettings.defaultColumnsText": "デフォルトでDiscoverアプリに表示される列。空の場合、ドキュメントの概要が表示されます。", "discover.advancedSettings.defaultColumnsTitle": "デフォルトの列", - "discover.advancedSettings.disableDocumentExplorer": "ドキュメントエクスプローラーまたはクラシックビュー", - "discover.advancedSettings.disableDocumentExplorerDescription": "クラシックビューではなく、新しい{documentExplorerDocs}を使用するには、このオプションをオフにします。ドキュメントエクスプローラーでは、データの並べ替え、列のサイズ変更、全画面表示といった優れた機能を使用できます。", - "discover.advancedSettings.discover.disableDocumentExplorerDeprecation": "この設定はサポートが終了し、Kibana 9.0では削除されます。", "discover.advancedSettings.discover.fieldStatisticsLinkText": "フィールド統計情報ビュー", - "discover.advancedSettings.discover.maxCellHeightDeprecation": "この設定はサポートが終了し、Kibana 9.0では削除されます。", "discover.advancedSettings.discover.modifyColumnsOnSwitchText": "新しいデータビューで使用できない列を削除します。", "discover.advancedSettings.discover.modifyColumnsOnSwitchTitle": "データビューを変更するときに列を修正", "discover.advancedSettings.discover.multiFieldsLinkText": "マルチフィールド", @@ -2750,13 +2740,10 @@ "discover.advancedSettings.discover.showMultifieldsDescription": "拡張ドキュメントビューに{multiFields}が表示されるかどうかを制御します。ほとんどの場合、マルチフィールドは元のフィールドと同じです。「searchFieldsFromSource」がオフのときにのみこのオプションを使用できます。", "discover.advancedSettings.docTableHideTimeColumnText": "Discover と、ダッシュボードのすべての保存された検索で、「時刻」列を非表示にします。", "discover.advancedSettings.docTableHideTimeColumnTitle": "「時刻」列を非表示", - "discover.advancedSettings.documentExplorerLinkText": "ドキュメントエクスプローラー", "discover.advancedSettings.fieldsPopularLimitText": "最も頻繁に使用されるフィールドのトップNを表示します", "discover.advancedSettings.fieldsPopularLimitTitle": "頻繁に使用されるフィールドの制限", "discover.advancedSettings.maxDocFieldsDisplayedText": "ドキュメント概要でレンダリングされるフィールドの最大数", "discover.advancedSettings.maxDocFieldsDisplayedTitle": "表示される最大ドキュメントフィールド数", - "discover.advancedSettings.params.maxCellHeightText": "表のセルが使用する高さの上限です。切り捨てを無効にするには0に設定します。", - "discover.advancedSettings.params.maxCellHeightTitle": "クラシック表の最大セル高さ", "discover.advancedSettings.params.rowHeightText": "行に追加できる線数。値-1は、コンテンツに合わせて、行の高さを自動的に調整します。値0はコンテンツが1行に表示されます。", "discover.advancedSettings.params.rowHeightTitle": "ドキュメントエクスプローラーの行高さ", "discover.advancedSettings.sampleRowsPerPageText": "ドキュメントテーブルのページごとの行数を制限します。", @@ -2772,7 +2759,6 @@ "discover.alerts.createSearchThreshold": "検索しきい値ルールの作成", "discover.alerts.manageRulesAndConnectors": "ルールとコネクターの管理", "discover.alerts.missedTimeFieldToolTip": "データビューには時間フィールドがありません。", - "discover.backToTopLinkText": "最上部へ戻る。", "discover.badge.readOnly.text": "読み取り専用", "discover.badge.readOnly.tooltip": "検索を保存できません", "discover.context.breadcrumb": "周りのドキュメント", @@ -2781,7 +2767,6 @@ "discover.context.failedToLoadAnchorDocumentErrorDescription": "アンカードキュメントの読み込みに失敗しました。", "discover.context.invalidTieBreakerFiledSetting": "無効なタイブレーカーフィールド設定", "discover.context.loadButtonLabel": "読み込み", - "discover.context.loadingDescription": "読み込み中...", "discover.context.newerDocumentsAriaLabel": "新しいドキュメントの数", "discover.context.newerDocumentsDescription": "新しいドキュメント", "discover.context.newerDocumentsWarning": "アンカーよりも新しいドキュメントは{docCount}件しか見つかりませんでした。", @@ -2818,38 +2803,8 @@ "discover.doc.pageTitle": "1つのドキュメント - #{id}", "discover.doc.somethingWentWrongDescription": "{indexName}が見つかりません。", "discover.doc.somethingWentWrongDescriptionAddon": "インデックスが存在することを確認してください。", - "discover.docExplorerCallout.closeButtonAriaLabel": "閉じる", - "discover.docExplorerCallout.documentExplorer": "ドキュメントエクスプローラー", - "discover.docExplorerCallout.headerMessage": "より効率的な探索方法", - "discover.docExplorerCallout.learnMore": "詳細", - "discover.docExplorerCallout.tryDocumentExplorer": "ドキュメントエクスプローラーを試す", - "discover.docTable.documentsNavigation": "ドキュメントナビゲーション", - "discover.docTable.limitedSearchResultLabel": "{resultCount}件の結果のみが表示されます。検索結果を絞り込みます。", - "discover.docTable.noResultsTitle": "結果が見つかりませんでした", - "discover.docTable.rows": "行", - "discover.docTable.tableHeader.documentHeader": "ドキュメント", - "discover.docTable.tableHeader.moveColumnLeftButtonAriaLabel": "{columnName}列を左に移動", - "discover.docTable.tableHeader.moveColumnLeftButtonTooltip": "列を左に移動", - "discover.docTable.tableHeader.moveColumnRightButtonAriaLabel": "{columnName}列を右に移動", - "discover.docTable.tableHeader.moveColumnRightButtonTooltip": "列を右に移動", - "discover.docTable.tableHeader.removeColumnButtonAriaLabel": "{columnName}列を削除", - "discover.docTable.tableHeader.removeColumnButtonTooltip": "列の削除", - "discover.docTable.tableHeader.sortByColumnAscendingAriaLabel": "{columnName}を昇順に並べ替える", - "discover.docTable.tableHeader.sortByColumnDescendingAriaLabel": "{columnName}を降順に並べ替える", - "discover.docTable.tableHeader.sortByColumnUnsortedAriaLabel": "{columnName}で並べ替えを止める", - "discover.docTable.tableHeader.timeFieldIconTooltip": "このフィールドはイベントの発生時刻を表します。", - "discover.docTable.tableHeader.timeFieldIconTooltipAriaLabel": "{timeFieldName} - このフィールドはイベントの発生時刻を表します。", - "discover.docTable.tableRow.detailHeading": "拡張ドキュメント", - "discover.docTable.tableRow.filterForValueButtonAriaLabel": "値でフィルター", - "discover.docTable.tableRow.filterForValueButtonTooltip": "値でフィルター", - "discover.docTable.tableRow.filterOutValueButtonAriaLabel": "値を除外", - "discover.docTable.tableRow.filterOutValueButtonTooltip": "値を除外", - "discover.docTable.tableRow.toggleRowDetailsButtonAriaLabel": "行の詳細を切り替える", - "discover.docTable.tableRow.viewSingleDocumentLinkText": "単一のドキュメントを表示", - "discover.docTable.tableRow.viewSurroundingDocumentsLinkText": "周りのドキュメントを表示", "discover.documentsAriaLabel": "ドキュメント", "discover.docViews.logsOverview.title": "ログ概要", - "discover.docViews.table.scoreSortWarningTooltip": "_scoreの値を取得するには、並べ替える必要があります。", "discover.dropZoneTableLabel": "フィールドを列として表に追加するには、ゾーンをドロップします", "discover.embeddable.inspectorRequestDataTitle": "データ", "discover.embeddable.inspectorRequestDescription": "このリクエストはElasticsearchにクエリーをかけ、検索データを取得します。", @@ -2871,7 +2826,6 @@ "discover.globalSearch.esqlSearchTitle": "ES|QLクエリーを作成", "discover.goToDiscoverButtonText": "Discoverに移動", "discover.grid.tableRow.actionsLabel": "アクション", - "discover.grid.tableRow.esqlDetailHeading": "展開された結果", "discover.grid.tableRow.mobileFlyoutActionsButton": "アクション", "discover.grid.tableRow.moreFlyoutActionsButton": "さらにアクションを表示", "discover.grid.tableRow.viewSingleDocumentLinkLabel": "単一のドキュメントを表示", @@ -2882,7 +2836,6 @@ "discover.hitsCounter.hitsPluralTitle": "{formattedHits} {hits, plural, other {結果}}", "discover.hitsCounter.partialHits": "≥{formattedHits}", "discover.hitsCounter.partialHitsPluralTitle": "≥{formattedHits} {hits, plural, other {結果}}", - "discover.howToSeeOtherMatchingDocumentsDescription": "これらは検索条件に一致した初めの {sampleSize} 件のドキュメントです。他の結果を表示するには検索条件を絞ってください。", "discover.inspectorEsqlRequestDescription": "このリクエストはElasticsearchに対してクエリーを実行し、テーブルの結果を取得します。", "discover.inspectorEsqlRequestTitle": "表", "discover.inspectorRequestDataTitleDocuments": "ドキュメント", @@ -2891,7 +2844,6 @@ "discover.invalidFiltersWarnToast.description": "一部の適用されたフィルターのデータビューID参照は、現在のデータビューとは異なります。", "discover.invalidFiltersWarnToast.title": "別のインデックス参照", "discover.loadingDocuments": "ドキュメントを読み込み中", - "discover.loadingResults": "結果を読み込み中", "discover.localMenu.alertsDescription": "アラート", "discover.localMenu.esqlTooltipLabel": "ES|QLはElasticの強力な新しいパイプクエリ言語です。", "discover.localMenu.fallbackReportTitle": "無題のDiscover検索", @@ -8304,24 +8256,16 @@ "unifiedDocViewer.docView.table.searchPlaceHolder": "検索フィールド名または値", "unifiedDocViewer.docViews.json.jsonTitle": "JSON", "unifiedDocViewer.docViews.table.esqlMultivalueFilteringDisabled": "ES|QLでは、多値フィルタリングはサポートされていません。", - "unifiedDocViewer.docViews.table.filterForFieldPresentButtonAriaLabel": "フィールド表示のフィルター", "unifiedDocViewer.docViews.table.filterForFieldPresentButtonTooltip": "フィールド表示のフィルター", - "unifiedDocViewer.docViews.table.filterForValueButtonAriaLabel": "値でフィルター", "unifiedDocViewer.docViews.table.filterForValueButtonTooltip": "値でフィルター", - "unifiedDocViewer.docViews.table.filterOutValueButtonAriaLabel": "値を除外", "unifiedDocViewer.docViews.table.filterOutValueButtonTooltip": "値を除外", "unifiedDocViewer.docViews.table.ignored.multiValueLabel": "無視された値を含む", "unifiedDocViewer.docViews.table.ignored.singleValueLabel": "無視された値", "unifiedDocViewer.docViews.table.ignoredValuesCanNotBeSearchedWarningMessage": "無視された値は検索できません", "unifiedDocViewer.docViews.table.pinFieldLabel": "フィールドを固定", "unifiedDocViewer.docViews.table.tableTitle": "表", - "unifiedDocViewer.docViews.table.toggleColumnInTableButtonAriaLabel": "表の列を切り替える", - "unifiedDocViewer.docViews.table.toggleColumnInTableButtonTooltip": "表の列を切り替える", "unifiedDocViewer.docViews.table.toggleColumnTableButtonTooltip": "表の列を切り替える", - "unifiedDocViewer.docViews.table.unableToFilterForPresenceOfMetaFieldsTooltip": "メタフィールドの有無でフィルタリングできません", - "unifiedDocViewer.docViews.table.unableToFilterForPresenceOfScriptedFieldsTooltip": "スクリプトフィールドの有無でフィルタリングできません", "unifiedDocViewer.docViews.table.unableToFilterForPresenceOfScriptedFieldsWarningMessage": "スクリプトフィールドの有無でフィルタリングできません", - "unifiedDocViewer.docViews.table.unindexedFieldsCanNotBeSearchedTooltip": "インデックスがないフィールドまたは無視された値は検索できません", "unifiedDocViewer.docViews.table.unindexedFieldsCanNotBeSearchedWarningMessage": "インデックスがないフィールドは検索できません", "unifiedDocViewer.docViews.table.unpinFieldLabel": "フィールドを固定解除", "unifiedDocViewer.docViews.table.viewLessButton": "簡易表示", @@ -8331,7 +8275,6 @@ "unifiedDocViewer.fieldActions.filterForValue": "値でフィルター", "unifiedDocViewer.fieldActions.filterOutValue": "値を除外", "unifiedDocViewer.fieldActions.toggleColumn": "表の列を切り替える", - "unifiedDocViewer.fieldChooser.discoverField.actions": "アクション", "unifiedDocViewer.fieldChooser.discoverField.multiField": "複数フィールド", "unifiedDocViewer.fieldChooser.discoverField.multiFieldTooltipContent": "複数フィールドにはフィールドごとに複数の値を入力できます", "unifiedDocViewer.fieldChooser.discoverField.name": "フィールド", @@ -15289,7 +15232,6 @@ "xpack.datasetQuality.details.fetchDataStreamDetailsFailed": "データストリーム詳細を取得できませんでした。", "xpack.datasetQuality.details.fetchDataStreamSettingsFailed": "データストリーム設定を読み込めませんでした。", "xpack.datasetQuality.details.fetchIntegrationDashboardsFailed": "統合ダッシュボードを取得できませんでした。", - "xpack.datasetQuality.details.fetchIntegrationsFailed": "{integrationName}統合情報を取得できませんでした。", "xpack.datasetQuality.details.indexTemplateActionText": "インデックステンプレート", "xpack.datasetQuality.details.integrationActionsText": "統合アクション", "xpack.datasetQuality.details.integrationnameText": "統合", @@ -17385,8 +17327,6 @@ "xpack.enterpriseSearch.content.analytics.api.generateAnalyticsApiKeyModal.done": "完了", "xpack.enterpriseSearch.content.analytics.api.generateAnalyticsApiKeyModal.generateButton": "キーを生成", "xpack.enterpriseSearch.content.analytics.api.generateAnalyticsApiKeyModal.title": "分析APIキーを作成", - "xpack.enterpriseSearch.content.cannotConnect.body": "詳細。", - "xpack.enterpriseSearch.content.cannotConnect.title": "エンタープライズ サーチに接続できません", "xpack.enterpriseSearch.content.conectors.indexHealth": "正常", "xpack.enterpriseSearch.content.connector_detail.configurationConnector.badgeType.connectorClient": "セルフマネージドコネクター", "xpack.enterpriseSearch.content.connector_detail.configurationConnector.badgeType.nativeConnector": "Elasticマネージドコネクター", @@ -17411,7 +17351,6 @@ "xpack.enterpriseSearch.content.connector_detail.configurationConnector.steps.waitingForConnector.callout.finishLaterButton.label": "後でデプロイを完了する", "xpack.enterpriseSearch.content.connector_detail.configurationConnector.steps.waitingForConnector.callout.title": "コネクターを待機しています", "xpack.enterpriseSearch.content.connector_detail.configurationConnector.steps.waitingForConnector.title": "コネクターのチェックインを待機しています", - "xpack.enterpriseSearch.content.connector_detail.nativeConfigurationConnector.apiKey.title": "API キー", "xpack.enterpriseSearch.content.connector_detail.nativeConfigurationConnector.configuration.title": "構成", "xpack.enterpriseSearch.content.connectors.breadcrumb": "コネクター", "xpack.enterpriseSearch.content.connectors.connectorDetail.configurationTabLabel": "構成", @@ -17578,8 +17517,6 @@ "xpack.enterpriseSearch.content.indices.configurationConnector.nativeConnector.convertConnector.description": "このコネクターをセルフホスティングしますか?独自のインフラで管理される{link}に変換します。Pythonフレームワークを使用してコードをカスタマイズしたい場合は、このコネクターを変換する必要があります。", "xpack.enterpriseSearch.content.indices.configurationConnector.nativeConnector.convertConnector.linkTitle": "セルフマネージドコネクター", "xpack.enterpriseSearch.content.indices.configurationConnector.nativeConnector.convertConnector.title": "このコネクターを自己管理", - "xpack.enterpriseSearch.content.indices.configurationConnector.nativeConnector.entSearchWarning.text": "Elasticマネージドコネクターは、実行中のエンタープライズ サーチインスタンスが必要です。", - "xpack.enterpriseSearch.content.indices.configurationConnector.nativeConnector.entSearchWarning.title": "実行中のエンタープライズ サーチインスタンスが検出されません", "xpack.enterpriseSearch.content.indices.configurationConnector.nativeConnectorAdvancedConfiguration.description": "ワンタイム同期をトリガーするか、繰り返し同期スケジュールを設定して、コネクターを確定します。", "xpack.enterpriseSearch.content.indices.configurationConnector.nativeConnectorAdvancedConfiguration.schedulingButtonLabel": "スケジュールを設定して同期", "xpack.enterpriseSearch.content.indices.configurationConnector.researchConfiguration.connectorDocumentationLinkLabel": "ドキュメント", @@ -17931,7 +17868,6 @@ "xpack.enterpriseSearch.content.playground.breadcrumb": "Playground", "xpack.enterpriseSearch.content.searchIndex.cancelSync.successMessage": "同期が正常にキャンセルされました", "xpack.enterpriseSearch.content.searchIndex.cancelSyncs.successMessage": "同期が正常にキャンセルされました", - "xpack.enterpriseSearch.content.searchIndex.cannotConnect.body": "Elastic Webクローラーにはエンタープライズ サーチが必要です。{link}", "xpack.enterpriseSearch.content.searchIndex.configurationTabLabel": "構成", "xpack.enterpriseSearch.content.searchIndex.connectorErrorCallOut.title": "コネクターでエラーが発生しました", "xpack.enterpriseSearch.content.searchIndex.crawlerConfigurationTabLabel": "構成", @@ -18269,7 +18205,6 @@ "xpack.enterpriseSearch.createConnector.configurationStep.configurationLabel": "構成", "xpack.enterpriseSearch.createConnector.configurationStep.h4.finishUpLabel": "終了", "xpack.enterpriseSearch.createConnector.configurationStep.p.description": "データを手動で同期したり、繰り返し同期をスケジュールしたり、ドメインを管理したりできます。", - "xpack.enterpriseSearch.createConnector.connectorDescriptionBadge.notAvailableTitle": "このコネクターは、Elasticマネージドコネクターとして利用できません。", "xpack.enterpriseSearch.createConnector.connectorDocsLinkLabel": "コネクター参照", "xpack.enterpriseSearch.createConnector.DeploymentStep.Configuration.description": "次に、Elasticクローラーを構成し、データを同期します。", "xpack.enterpriseSearch.createConnector.DeploymentStep.Configuration.title": "構成", @@ -18344,17 +18279,6 @@ "xpack.enterpriseSearch.enterpriseSearch.setupGuide.videoAlt": "エンタープライズ サーチの基本操作", "xpack.enterpriseSearch.enterpriseSearchCard.cta": "詳細", "xpack.enterpriseSearch.entSearch.productCardDescription": "よりシンプルで使いやすく、ビジネスに特化した検索エクスペリエンスを提供するスタンドアロンアプリケーション。", - "xpack.enterpriseSearch.errorConnectingCallout.setupGuideCta": "セットアップガイドを確認", - "xpack.enterpriseSearch.errorConnectingCallout.title": "エンタープライズ サーチに接続できません", - "xpack.enterpriseSearch.errorConnectingState.cloudErrorMessage": "クラウドデプロイのエンタープライズ サーチノードが実行中ですか?{deploymentSettingsLink}", - "xpack.enterpriseSearch.errorConnectingState.cloudErrorMessageLinkText": "デプロイ設定を確認", - "xpack.enterpriseSearch.errorConnectingState.description1": "次のエラーのため、ホストURL {enterpriseSearchUrl}では、エンタープライズ サーチへの接続を確立できません。", - "xpack.enterpriseSearch.errorConnectingState.description2": "ホストURLが{configFile}で正しく構成されていることを確認してください。", - "xpack.enterpriseSearch.errorConnectingState.description3": "エンタープライズ サーチサーバーが応答していることを確認してください。", - "xpack.enterpriseSearch.errorConnectingState.setupGuideCta": "セットアップガイドを確認", - "xpack.enterpriseSearch.errorConnectingState.title": "接続できません", - "xpack.enterpriseSearch.errorConnectingState.troubleshootAuth": "ユーザー認証を確認してください。", - "xpack.enterpriseSearch.errorConnectingState.troubleshootAuthMessage": "管理者に連絡して、エンタープライズ サーチのロールマッピングを設定し、エンタープライズ サーチへのアクセスを許可してください", "xpack.enterpriseSearch.exampleConnectorLabel": "例", "xpack.enterpriseSearch.finishUpStep.euiButton.viewInDiscoverLabel": "Discoverに表示", "xpack.enterpriseSearch.getConnectorTypeBadge.connectorClientBadgeLabel": "セルフマネージド", @@ -18501,9 +18425,6 @@ "xpack.enterpriseSearch.navigation.contentPlaygroundLinkLabel": "Playground", "xpack.enterpriseSearch.navigation.contentWebcrawlersLinkLabel": "Webクローラー", "xpack.enterpriseSearch.navigation.relevanceInferenceEndpointsLinkLabel": "推論エンドポイント", - "xpack.enterpriseSearch.noEntSearch.noCrawler": "Elastic Webクローラーはエンタープライズ サーチなしでは利用できません。", - "xpack.enterpriseSearch.noEntSearch.setupGuideCta": "セットアップガイドを確認", - "xpack.enterpriseSearch.noEntSearchConfigured.title": "エンタープライズ サーチが構成されていません", "xpack.enterpriseSearch.notFound.action1": "ダッシュボードに戻す", "xpack.enterpriseSearch.notFound.action2": "サポートに問い合わせる", "xpack.enterpriseSearch.notFound.description": "お探しのページは見つかりませんでした。", @@ -18771,7 +18692,6 @@ "xpack.enterpriseSearch.searchApplications.searchApplication.indices.searchPlaceholder": "インデックスのフィルター", "xpack.enterpriseSearch.searchApplications.searchApplication.indices.someUnknownIndicesCallout.description": "この検索アプリケーションからは一部のデータに接続できない場合があります。影響を受けるインデックスで保留中の処理またはエラーがあるかどうかを確認するか、この検索アプリケーションで使用されないインデックスを削除してください。", "xpack.enterpriseSearch.searchApplications.searchApplication.indices.someUnknownIndicesCallout.title": "一部のインデックスが使用できません。", - "xpack.enterpriseSearch.searchApplications.searchApplication.notFound.action1": "検索アプリケーションに戻る", "xpack.enterpriseSearch.searchApplications.searchApplication.schema.conflictsCallOut.button": "不一致を表示", "xpack.enterpriseSearch.searchApplications.searchApplication.schema.conflictsCallOut.description": "スキーマフィールド型の競合は、ソースインデックスに直接移動し、競合するフィールドのフィールド型を他のソースインデックスのフィールド型と一致するように更新することで解決できます。", "xpack.enterpriseSearch.searchApplications.searchApplication.schema.conflictsCallOut.title": "フィールドマッピングに潜在的な問題が見つかりました", @@ -18984,10 +18904,6 @@ "xpack.enterpriseSearch.vectorSearch.guide.query.title": "ベクトル検索を実行", "xpack.enterpriseSearch.vectorSearch.navTitle": "ベクトル検索", "xpack.enterpriseSearch.vectorSearch.productName": "ベクトル検索", - "xpack.enterpriseSearch.versionMismatch.body": "Kibanaとエンタープライズ サーチのバージョンが一致しません。エンタープライズ サーチにアクセスするには、各サービスで同じメジャーおよびマイナーバージョンを使用してください。", - "xpack.enterpriseSearch.versionMismatch.enterpriseSearchVersionText": "エンタープライズ サーチバージョン:{enterpriseSearchVersion}", - "xpack.enterpriseSearch.versionMismatch.kibanaVersionText": "Kibanaバージョン:{kibanaVersion}", - "xpack.enterpriseSearch.versionMismatch.title": "互換性のないバージョンエラー", "xpack.enterpriseSearch.welcomeBanner.header.greeting.customTitle": "👋 こんにちは、{name}さん!", "xpack.enterpriseSearch.welcomeBanner.header.greeting.defaultTitle": "👋 こんにちは", "xpack.enterpriseSearch.welcomeBanner.header.title": "Elasticsearchにデータを追加し、検索、ベクトル化、可視化", @@ -22615,10 +22531,6 @@ "xpack.idxMgmt.home.componentTemplates.list.loadingMessage": "コンポーネントテンプレートを読み込んでいます…", "xpack.idxMgmt.home.componentTemplatesTabTitle": "コンポーネントテンプレート", "xpack.idxMgmt.home.dataStreamsTabTitle": "データストリーム", - "xpack.idxMgmt.home.enrichPolicies.checkingPrivilegesDescription": "権限を確認中…", - "xpack.idxMgmt.home.enrichPolicies.checkingPrivilegesErrorMessage": "サーバーからユーザー特権を取得中にエラーが発生。", - "xpack.idxMgmt.home.enrichPolicies.deniedPrivilegeDescription": "エンリッチポリシーを使用するには、以下のクラスター権限が必要です:{missingPrivileges}。", - "xpack.idxMgmt.home.enrichPolicies.deniedPrivilegeTitle": "必要なエンリッチ権限を管理", "xpack.idxMgmt.home.enrichPoliciesTabTitle": "エンリッチポリシー", "xpack.idxMgmt.home.idxMgmtDescription": "Elasticsearch インデックスを個々に、または一斉に更新します。{learnMoreLink}", "xpack.idxMgmt.home.idxMgmtDocsLinkText": "インデックス管理ドキュメント", @@ -37156,8 +37068,6 @@ "xpack.securitySolution.assistant.quickPrompts.alertSummarizationTitle": "アラート要約", "xpack.securitySolution.assistant.quickPrompts.AutomationPrompt": "ログやイベントの収集には、どのFleet対応Elasticエージェント統合を使用すべきですか。", "xpack.securitySolution.assistant.quickPrompts.AutomationTitle": "エージェント統合のアドバイス", - "xpack.securitySolution.assistant.quickPrompts.esqlQueryGenerationPrompt": "Elasticセキュリティのエキスパートユーザーとして、以下のユースケースを検出するための正確で有効なESQLクエリを作成してください。回答は、Elasticセキュリティのタイムラインまたは検出ルールですぐに使用できるように書式設定してください。答えに時間をかけて、求められているすべての機能について、あなたの知識をよく確認してください。ES|QLの回答は、特に、あなたの個人的な知識で利用可能なもののみを答えてください。クエリが不正確であることは許容できません。Elastic Common SchemaとElasticエージェントを使用していると仮定します。回答がマークダウンの独立したコードブロックとして簡単にコピーできるように書式設定されていることを確認してください。", - "xpack.securitySolution.assistant.quickPrompts.esqlQueryGenerationTitle": "ES|QLクエリ生成", "xpack.securitySolution.assistant.quickPrompts.ruleCreationPrompt": "Elasticセキュリティのエキスパートユーザーとして、以下のユースケースを検出するための正確で有効なEQLクエリを作成してください。回答は、Elasticセキュリティのタイムラインまたは検出ルールですぐに使用できるように書式設定してください。そのユースケースに対応するルールがすでにElasticセキュリティに組み込まれている場合、または類似のルールが組み込まれている場合は、そのルールへのリンクと説明を入力してください。", "xpack.securitySolution.assistant.quickPrompts.ruleCreationTitle": "クエリ生成", "xpack.securitySolution.assistant.quickPrompts.splQueryConversionPrompt": "以前のSIEMプラットフォームから次のクエリを受け取りました。Elasticセキュリティのエキスパートユーザーとして、同等のElastic EQLを提案してください。すぐにそれをElasticのセキュリティタイムラインにコピーできます。", @@ -40366,7 +40276,6 @@ "xpack.securitySolution.entityAnalytics.assetCriticalityUploadPage.noPermissionTitle": "CSVアップロードを実行する十分なインデックス権限がありません", "xpack.securitySolution.entityAnalytics.assetCriticalityUploadPage.resultsStepTitle": "結果", "xpack.securitySolution.entityAnalytics.assetCriticalityUploadPage.selectFileStepTitle": "ファイルを選択", - "xpack.securitySolution.entityAnalytics.assetCriticalityUploadPage.subTitle": "テキストファイルを使用してエンティティをインポート", "xpack.securitySolution.entityAnalytics.assetCriticalityUploadPage.unavailable": "アセット重要度CSVファイルアップロード機能が利用できません。", "xpack.securitySolution.entityAnalytics.assetCriticalityUploadPage.unsupportedFileTypeError": "無効なファイル形式が選択されました。{supportedFileExtensions}ファイルを選択して再試行してください。", "xpack.securitySolution.entityAnalytics.assetCriticalityUploadPage.uploadFileSizeLimit": "最大ファイルサイズ:{maxFileSize}", @@ -40408,7 +40317,6 @@ "xpack.securitySolution.entityAnalytics.entityStoreManagementPage.clearEntitiesModal.clearAllEntities": "すべてのエンティティを消去", "xpack.securitySolution.entityAnalytics.entityStoreManagementPage.clearEntitiesModal.close": "閉じる", "xpack.securitySolution.entityAnalytics.entityStoreManagementPage.clearEntitiesModal.title": "エンティティデータを消去しますか?", - "xpack.securitySolution.entityAnalytics.entityStoreManagementPage.clearEntityData": "すべての抽出されたエンティティデータをストアから削除します。このアクションにより、永続化されたユーザーおよびホストレコードが完全に削除され、データは分析で使用できなくなります。注意して続行してください。この操作は元に戻せません。この処理では、ソースデータ、エンティティリスクスコア、アセット重要度割り当ては削除されません。", "xpack.securitySolution.entityAnalytics.entityStoreManagementPage.featureFlagDisabled": "エンティティストア機能を利用できません", "xpack.securitySolution.entityAnalytics.entityStoreManagementPage.subTitle": "システムのホストとユーザーを包括的に監視できます。", "xpack.securitySolution.entityAnalytics.entityStoreManagementPage.title": "エンティティストア", @@ -46225,7 +46133,6 @@ "xpack.synthetics.failedStep.label": "失敗したステップ", "xpack.synthetics.fcp.label": "FCP", "xpack.synthetics.featureRegistry.syntheticsFeatureName": "Syntheticsとアップタイム", - "xpack.synthetics.features.app": "Synthetics", "xpack.synthetics.features.elasticManagedLocations": "Elasticで管理されている場所が有効です", "xpack.synthetics.fieldLabels.cls": "累積レイアウト変更(CLS)", "xpack.synthetics.fieldLabels.dcl": "DOMContentLoadedイベント(DCL)", @@ -48594,8 +48501,7 @@ "xpack.triggersActionsUI.updateApiKeyConfirmModal.description": "古いAPI {idsToUpdate, plural, other {キー}}は回復できません", "xpack.triggersActionsUI.updateApiKeyConfirmModal.failureMessage": "API {idsToUpdate, plural, other {キー}}を更新できませんでした", "xpack.triggersActionsUI.updateApiKeyConfirmModal.title": "APIキーの更新", - "xpack.triggersActionsUI.urlSyncedAlertsSearchBar.invalidQueryTitle": "無効なクエリー文字列", - "xpack.triggersActionsUI.useRuleAADFields.errorMessage": "ルールタイプごとにアラートフィールドを読み込めません", + "xpack.triggersActionsUI.urlSyncedAlertsSearchBar.invalidQueryTitle": "無効なクエリ文字列", "xpack.upgradeAssistant.app.deniedPrivilegeDescription": "アップグレードアシスタントを使用して、廃止予定の問題を解決するには、すべてのKibanaスペースを管理するためのアクセス権が必要です。", "xpack.upgradeAssistant.app.deniedPrivilegeTitle": "Kibana管理者ロールが必要です", "xpack.upgradeAssistant.appTitle": "アップグレードアシスタント", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index e32da14dbe9e6..e7ae369eb8c2b 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -191,14 +191,8 @@ "alertsUIShared.healthCheck.encryptionErrorTitle": "需要其他设置", "alertsUIShared.healthCheck.healthCheck.apiKeysAndEncryptionErrorTitle": "需要其他设置", "alertsUIShared.hooks.useAlertDataView.fetchErrorMessage": "无法加载告警数据视图", - "alertsUIShared.hooks.useFindAlertsQuery.unableToFetchAlertsGroupingAggregations": "无法提取告警分组聚合", "alertsUIShared.hooks.useFindAlertsQuery.unableToFindAlertsQueryMessage": "无法找到告警", "alertsUIShared.hooks.useLoadRuleTypesQuery.unableToLoadRuleTypesMessage": "无法加载规则类型", - "alertsUIShared.hooks.useRuleAADFields.errorMessage": "无法按规则类型加载告警字段", - "alertsUIShared.licenseCheck.actionTypeDisabledByConfigMessageTitle": "此功能已由 Kibana 配置禁用。", - "alertsUIShared.licenseCheck.actionTypeDisabledByLicenseLinkTitle": "查看许可证选项", - "alertsUIShared.licenseCheck.actionTypeDisabledByLicenseMessageDescription": "要重新启用此操作,请升级您的许可证。", - "alertsUIShared.licenseCheck.actionTypeDisabledByLicenseMessageTitle": "此功能需要{minimumLicenseRequired}许可证。", "alertsUIShared.maintenanceWindowCallout.fetchError": "无法检查维护窗口是否处于活动状态", "alertsUIShared.maintenanceWindowCallout.fetchErrorDescription": "维护窗口正在运行时会停止规则通知。", "alertsUIShared.maintenanceWindowCallout.maintenanceWindowActive": "{activeWindowCount, plural, other {维护窗口正}}针对 {categories} 规则运行", @@ -2694,11 +2688,7 @@ "discover.advancedSettings.context.tieBreakerFieldsTitle": "平分决胜字段", "discover.advancedSettings.defaultColumnsText": "Discover 应用中默认显示的列。如果为空,将显示文档摘要。", "discover.advancedSettings.defaultColumnsTitle": "默认列", - "discover.advancedSettings.disableDocumentExplorer": "Document Explorer 或经典视图", - "discover.advancedSettings.disableDocumentExplorerDescription": "要使用新的 {documentExplorerDocs},而非经典视图,请关闭此选项。Document Explorer 提供了更合理的数据排序、可调整大小的列和全屏视图。", - "discover.advancedSettings.discover.disableDocumentExplorerDeprecation": "此设置已过时,将在 Kibana 9.0 中移除。", "discover.advancedSettings.discover.fieldStatisticsLinkText": "字段统计信息视图", - "discover.advancedSettings.discover.maxCellHeightDeprecation": "此设置已过时,将在 Kibana 9.0 中移除。", "discover.advancedSettings.discover.modifyColumnsOnSwitchText": "移除新数据视图中不存在的列。", "discover.advancedSettings.discover.modifyColumnsOnSwitchTitle": "在更改数据视图时修改列", "discover.advancedSettings.discover.multiFieldsLinkText": "多字段", @@ -2711,13 +2701,10 @@ "discover.advancedSettings.discover.showMultifieldsDescription": "控制 {multiFields} 是否显示在展开的文档视图中。多数情况下,多字段与原始字段相同。此选项仅在 `searchFieldsFromSource` 关闭时可用。", "discover.advancedSettings.docTableHideTimeColumnText": "在 Discover 中和仪表板上的所有已保存搜索中隐藏'时间'列。", "discover.advancedSettings.docTableHideTimeColumnTitle": "隐藏'时间'列", - "discover.advancedSettings.documentExplorerLinkText": "Document Explorer", "discover.advancedSettings.fieldsPopularLimitText": "要显示的排名前 N 最常见字段", "discover.advancedSettings.fieldsPopularLimitTitle": "常见字段限制", "discover.advancedSettings.maxDocFieldsDisplayedText": "在文档摘要中渲染的最大字段数目", "discover.advancedSettings.maxDocFieldsDisplayedTitle": "显示的最大文档字段数", - "discover.advancedSettings.params.maxCellHeightText": "表单元格应占用的最大高度。设置为 0 可禁用截断。", - "discover.advancedSettings.params.maxCellHeightTitle": "经典表中的最大单元格高度", "discover.advancedSettings.params.rowHeightText": "一行中允许的文本行数。值为 -1 时,会自动调整行高以适应内容。值为 0 时,会在单文本行中显示内容。", "discover.advancedSettings.params.rowHeightTitle": "Document Explorer 中的行高", "discover.advancedSettings.sampleRowsPerPageText": "限制文档表中每页的行数。", @@ -2733,7 +2720,6 @@ "discover.alerts.createSearchThreshold": "创建搜索阈值规则", "discover.alerts.manageRulesAndConnectors": "管理规则和连接器", "discover.alerts.missedTimeFieldToolTip": "数据视图没有时间字段。", - "discover.backToTopLinkText": "返回顶部。", "discover.badge.readOnly.text": "只读", "discover.badge.readOnly.tooltip": "无法保存搜索", "discover.context.breadcrumb": "周围文档", @@ -2742,7 +2728,6 @@ "discover.context.failedToLoadAnchorDocumentErrorDescription": "无法加载定位点文档。", "discover.context.invalidTieBreakerFiledSetting": "无效的平分决胜字段设置", "discover.context.loadButtonLabel": "加载", - "discover.context.loadingDescription": "正在加载……", "discover.context.newerDocumentsAriaLabel": "较新文档数目", "discover.context.newerDocumentsDescription": "较新文档", "discover.context.newerDocumentsWarning": "仅可以找到 {docCount} 个比定位标记新的文档。", @@ -2779,34 +2764,8 @@ "discover.doc.pageTitle": "单个文档 - #{id}", "discover.doc.somethingWentWrongDescription": "{indexName} 缺失。", "discover.doc.somethingWentWrongDescriptionAddon": "请确保索引存在。", - "discover.docExplorerCallout.bodyMessage": "使用 {documentExplorer} 快速排序、选择和比较数据,调整列大小并以全屏方式查看文档。", - "discover.docExplorerCallout.closeButtonAriaLabel": "关闭", - "discover.docExplorerCallout.documentExplorer": "Document Explorer", - "discover.docExplorerCallout.headerMessage": "更好的浏览方式", - "discover.docExplorerCallout.learnMore": "了解详情", - "discover.docExplorerCallout.tryDocumentExplorer": "试用 Document Explorer", - "discover.docTable.documentsNavigation": "文档导航", - "discover.docTable.limitedSearchResultLabel": "仅限于 {resultCount} 个结果。优化您的搜索。", - "discover.docTable.noResultsTitle": "找不到结果", - "discover.docTable.rows": "行", - "discover.docTable.rowsPerPage": "每页行数:{pageSize}", - "discover.docTable.tableHeader.documentHeader": "文档", - "discover.docTable.tableHeader.moveColumnLeftButtonTooltip": "向左移动列", - "discover.docTable.tableHeader.moveColumnRightButtonTooltip": "向右移动列", - "discover.docTable.tableHeader.removeColumnButtonTooltip": "移除列", - "discover.docTable.tableHeader.timeFieldIconTooltip": "此字段表示事件发生的时间。", - "discover.docTable.tableHeader.timeFieldIconTooltipAriaLabel": "{timeFieldName} - 此字段表示事件发生的时间。", - "discover.docTable.tableRow.detailHeading": "已展开文档", - "discover.docTable.tableRow.filterForValueButtonAriaLabel": "筛留值", - "discover.docTable.tableRow.filterForValueButtonTooltip": "筛留值", - "discover.docTable.tableRow.filterOutValueButtonAriaLabel": "筛除值", - "discover.docTable.tableRow.filterOutValueButtonTooltip": "筛除值", - "discover.docTable.tableRow.toggleRowDetailsButtonAriaLabel": "切换行详细信息", - "discover.docTable.tableRow.viewSingleDocumentLinkText": "查看单个文档", - "discover.docTable.tableRow.viewSurroundingDocumentsLinkText": "查看周围文档", "discover.documentsAriaLabel": "文档", "discover.docViews.logsOverview.title": "日志概览", - "discover.docViews.table.scoreSortWarningTooltip": "要检索 _score 的值,必须按其筛选。", "discover.dropZoneTableLabel": "放置区域以将字段作为列添加到表中", "discover.embeddable.inspectorRequestDataTitle": "数据", "discover.embeddable.inspectorRequestDescription": "此请求将查询 Elasticsearch 以获取搜索的数据。", @@ -2828,7 +2787,6 @@ "discover.globalSearch.esqlSearchTitle": "创建 ES|QL 查询", "discover.goToDiscoverButtonText": "前往 Discover", "discover.grid.tableRow.actionsLabel": "操作", - "discover.grid.tableRow.esqlDetailHeading": "已展开结果", "discover.grid.tableRow.mobileFlyoutActionsButton": "操作", "discover.grid.tableRow.moreFlyoutActionsButton": "更多操作", "discover.grid.tableRow.viewSingleDocumentLinkLabel": "查看单个文档", @@ -2839,7 +2797,6 @@ "discover.hitsCounter.hitsPluralTitle": "{formattedHits} 个{hits, plural, other {结果}}", "discover.hitsCounter.partialHits": "≥{formattedHits}", "discover.hitsCounter.partialHitsPluralTitle": "≥{formattedHits} 个{hits, plural, other {结果}}", - "discover.howToSeeOtherMatchingDocumentsDescription": "下面是与您的搜索匹配的前 {sampleSize} 个文档,请优化您的搜索以查看其他文档。", "discover.inspectorEsqlRequestDescription": "此请求将查询 Elasticsearch 以获取该表的结果。", "discover.inspectorEsqlRequestTitle": "表", "discover.inspectorRequestDataTitleDocuments": "文档", @@ -2848,7 +2805,6 @@ "discover.invalidFiltersWarnToast.description": "某些应用的筛选中的数据视图 ID 引用与当前数据视图不同。", "discover.invalidFiltersWarnToast.title": "不同的索引引用", "discover.loadingDocuments": "正在加载文档", - "discover.loadingResults": "正在加载结果", "discover.localMenu.alertsDescription": "告警", "discover.localMenu.esqlTooltipLabel": "ES|QL 是 Elastic 支持的功能强大的全新管道查询语言。", "discover.localMenu.fallbackReportTitle": "未命名 Discover 搜索", @@ -8147,24 +8103,16 @@ "unifiedDocViewer.docView.table.searchPlaceHolder": "搜索字段名称或值", "unifiedDocViewer.docViews.json.jsonTitle": "JSON", "unifiedDocViewer.docViews.table.esqlMultivalueFilteringDisabled": "ES|QL 中不支持多值筛选", - "unifiedDocViewer.docViews.table.filterForFieldPresentButtonAriaLabel": "筛留存在的字段", "unifiedDocViewer.docViews.table.filterForFieldPresentButtonTooltip": "字段是否存在筛选", - "unifiedDocViewer.docViews.table.filterForValueButtonAriaLabel": "筛留值", "unifiedDocViewer.docViews.table.filterForValueButtonTooltip": "筛留值", - "unifiedDocViewer.docViews.table.filterOutValueButtonAriaLabel": "筛除值", "unifiedDocViewer.docViews.table.filterOutValueButtonTooltip": "筛除值", "unifiedDocViewer.docViews.table.ignored.multiValueLabel": "包含被忽略的值", "unifiedDocViewer.docViews.table.ignored.singleValueLabel": "被忽略的值", "unifiedDocViewer.docViews.table.ignoredValuesCanNotBeSearchedWarningMessage": "无法搜索被忽略的值", "unifiedDocViewer.docViews.table.pinFieldLabel": "固定字段", "unifiedDocViewer.docViews.table.tableTitle": "表", - "unifiedDocViewer.docViews.table.toggleColumnInTableButtonAriaLabel": "在表中切换列", - "unifiedDocViewer.docViews.table.toggleColumnInTableButtonTooltip": "在表中切换列", "unifiedDocViewer.docViews.table.toggleColumnTableButtonTooltip": "在表中切换列", - "unifiedDocViewer.docViews.table.unableToFilterForPresenceOfMetaFieldsTooltip": "无法筛选元数据字段是否存在", - "unifiedDocViewer.docViews.table.unableToFilterForPresenceOfScriptedFieldsTooltip": "无法筛选脚本字段是否存在", "unifiedDocViewer.docViews.table.unableToFilterForPresenceOfScriptedFieldsWarningMessage": "无法筛选脚本字段是否存在", - "unifiedDocViewer.docViews.table.unindexedFieldsCanNotBeSearchedTooltip": "无法搜索未编入索引的字段或被忽略的值", "unifiedDocViewer.docViews.table.unindexedFieldsCanNotBeSearchedWarningMessage": "无法搜索未编入索引的字段", "unifiedDocViewer.docViews.table.unpinFieldLabel": "取消固定字段", "unifiedDocViewer.docViews.table.viewLessButton": "查看更少", @@ -8174,7 +8122,6 @@ "unifiedDocViewer.fieldActions.filterForValue": "筛留值", "unifiedDocViewer.fieldActions.filterOutValue": "筛除值", "unifiedDocViewer.fieldActions.toggleColumn": "在表中切换列", - "unifiedDocViewer.fieldChooser.discoverField.actions": "操作", "unifiedDocViewer.fieldChooser.discoverField.multiField": "多字段", "unifiedDocViewer.fieldChooser.discoverField.multiFieldTooltipContent": "多字段的每个字段可以有多个值", "unifiedDocViewer.fieldChooser.discoverField.name": "字段", @@ -14983,7 +14930,6 @@ "xpack.datasetQuality.details.fetchDataStreamDetailsFailed": "无法获取数据流详情。", "xpack.datasetQuality.details.fetchDataStreamSettingsFailed": "无法加载数据流设置。", "xpack.datasetQuality.details.fetchIntegrationDashboardsFailed": "无法获取集成仪表板。", - "xpack.datasetQuality.details.fetchIntegrationsFailed": "无法获取 {integrationName} 集成信息。", "xpack.datasetQuality.details.indexTemplateActionText": "索引模板", "xpack.datasetQuality.details.integrationActionsText": "集成操作", "xpack.datasetQuality.details.integrationnameText": "集成", @@ -17053,8 +16999,6 @@ "xpack.enterpriseSearch.content.analytics.api.generateAnalyticsApiKeyModal.done": "完成", "xpack.enterpriseSearch.content.analytics.api.generateAnalyticsApiKeyModal.generateButton": "生成密钥", "xpack.enterpriseSearch.content.analytics.api.generateAnalyticsApiKeyModal.title": "创建分析 API 密钥", - "xpack.enterpriseSearch.content.cannotConnect.body": "更多信息。", - "xpack.enterpriseSearch.content.cannotConnect.title": "无法连接到 Enterprise Search", "xpack.enterpriseSearch.content.conectors.indexHealth": "运行正常", "xpack.enterpriseSearch.content.connector_detail.configurationConnector.badgeType.connectorClient": "自管型连接器", "xpack.enterpriseSearch.content.connector_detail.configurationConnector.badgeType.nativeConnector": "Elastic 托管连接器", @@ -17079,7 +17023,6 @@ "xpack.enterpriseSearch.content.connector_detail.configurationConnector.steps.waitingForConnector.callout.finishLaterButton.label": "稍后完成部署", "xpack.enterpriseSearch.content.connector_detail.configurationConnector.steps.waitingForConnector.callout.title": "等候您的连接器", "xpack.enterpriseSearch.content.connector_detail.configurationConnector.steps.waitingForConnector.title": "等待您的连接器签入", - "xpack.enterpriseSearch.content.connector_detail.nativeConfigurationConnector.apiKey.title": "API 密钥", "xpack.enterpriseSearch.content.connector_detail.nativeConfigurationConnector.configuration.title": "配置", "xpack.enterpriseSearch.content.connectors.breadcrumb": "连接器", "xpack.enterpriseSearch.content.connectors.connectorDetail.configurationTabLabel": "配置", @@ -17246,8 +17189,6 @@ "xpack.enterpriseSearch.content.indices.configurationConnector.nativeConnector.convertConnector.description": "是否要自我托管此连接器?将其转换为将在您自己的基础设施上进行托管的 {link}。如果希望使用我们的 Python 框架定制代码,您需要转换此连接器。", "xpack.enterpriseSearch.content.indices.configurationConnector.nativeConnector.convertConnector.linkTitle": "自管型连接器", "xpack.enterpriseSearch.content.indices.configurationConnector.nativeConnector.convertConnector.title": "自我管理此连接器", - "xpack.enterpriseSearch.content.indices.configurationConnector.nativeConnector.entSearchWarning.text": "Elastic 托管连接器需要正在运行的 Enterprise Search 实例。", - "xpack.enterpriseSearch.content.indices.configurationConnector.nativeConnector.entSearchWarning.title": "未检测到正在运行的 Enterprise Search 实例", "xpack.enterpriseSearch.content.indices.configurationConnector.nativeConnectorAdvancedConfiguration.description": "通过触发一次时间同步或设置重复同步计划来最终确定您的连接器。", "xpack.enterpriseSearch.content.indices.configurationConnector.nativeConnectorAdvancedConfiguration.schedulingButtonLabel": "设置计划并同步", "xpack.enterpriseSearch.content.indices.configurationConnector.researchConfiguration.connectorDocumentationLinkLabel": "文档", @@ -17597,7 +17538,6 @@ "xpack.enterpriseSearch.content.playground.breadcrumb": "Playground", "xpack.enterpriseSearch.content.searchIndex.cancelSync.successMessage": "已成功取消同步", "xpack.enterpriseSearch.content.searchIndex.cancelSyncs.successMessage": "已成功取消同步", - "xpack.enterpriseSearch.content.searchIndex.cannotConnect.body": "Elastic 网络爬虫需要 Enterprise Search。{link}", "xpack.enterpriseSearch.content.searchIndex.configurationTabLabel": "配置", "xpack.enterpriseSearch.content.searchIndex.connectorErrorCallOut.title": "您的连接器报告了错误", "xpack.enterpriseSearch.content.searchIndex.crawlerConfigurationTabLabel": "配置", @@ -17932,7 +17872,6 @@ "xpack.enterpriseSearch.createConnector.configurationStep.configurationLabel": "配置", "xpack.enterpriseSearch.createConnector.configurationStep.h4.finishUpLabel": "结束", "xpack.enterpriseSearch.createConnector.configurationStep.p.description": "您可以手动同步数据,计划重复同步或管理您的域。", - "xpack.enterpriseSearch.createConnector.connectorDescriptionBadge.notAvailableTitle": "此连接器不可用作 Elastic 托管连接器", "xpack.enterpriseSearch.createConnector.connectorDocsLinkLabel": "连接器参考", "xpack.enterpriseSearch.createConnector.DeploymentStep.Configuration.description": "立即配置您的 Elastic 网络爬虫并同步数据。", "xpack.enterpriseSearch.createConnector.DeploymentStep.Configuration.title": "配置", @@ -18007,17 +17946,6 @@ "xpack.enterpriseSearch.enterpriseSearch.setupGuide.videoAlt": "企业搜索入门", "xpack.enterpriseSearch.enterpriseSearchCard.cta": "了解详情", "xpack.enterpriseSearch.entSearch.productCardDescription": "为构建更简单、用户友好且以业务为中心的搜索体验而量身定制的独立应用程序。", - "xpack.enterpriseSearch.errorConnectingCallout.setupGuideCta": "阅读设置指南", - "xpack.enterpriseSearch.errorConnectingCallout.title": "无法连接到 Enterprise Search", - "xpack.enterpriseSearch.errorConnectingState.cloudErrorMessage": "您的云部署是否正在运行 Enterprise Search 节点?{deploymentSettingsLink}", - "xpack.enterpriseSearch.errorConnectingState.cloudErrorMessageLinkText": "检查您的部署设置", - "xpack.enterpriseSearch.errorConnectingState.description1": "由于以下错误,我们无法与主机 URL {enterpriseSearchUrl} 的 Enterprise Search 建立连接:", - "xpack.enterpriseSearch.errorConnectingState.description2": "确保在 {configFile} 中已正确配置主机 URL。", - "xpack.enterpriseSearch.errorConnectingState.description3": "确认企业搜索服务器响应。", - "xpack.enterpriseSearch.errorConnectingState.setupGuideCta": "阅读设置指南", - "xpack.enterpriseSearch.errorConnectingState.title": "无法连接", - "xpack.enterpriseSearch.errorConnectingState.troubleshootAuth": "检查您的用户身份验证:", - "xpack.enterpriseSearch.errorConnectingState.troubleshootAuthMessage": "请联系管理员设置 Enterprise Search 角色映射,为您提供 Enterprise Search 的访问权限", "xpack.enterpriseSearch.exampleConnectorLabel": "示例", "xpack.enterpriseSearch.finishUpStep.euiButton.viewInDiscoverLabel": "在 Discover 中查看", "xpack.enterpriseSearch.getConnectorTypeBadge.connectorClientBadgeLabel": "自管型", @@ -18165,9 +18093,6 @@ "xpack.enterpriseSearch.navigation.contentPlaygroundLinkLabel": "Playground", "xpack.enterpriseSearch.navigation.contentWebcrawlersLinkLabel": "网络爬虫", "xpack.enterpriseSearch.navigation.relevanceInferenceEndpointsLinkLabel": "推理终端", - "xpack.enterpriseSearch.noEntSearch.noCrawler": "如果没有 Enterprise Search,Elastic 网络爬虫将不可用。", - "xpack.enterpriseSearch.noEntSearch.setupGuideCta": "阅读设置指南", - "xpack.enterpriseSearch.noEntSearchConfigured.title": "尚未配置 Enterprise Search", "xpack.enterpriseSearch.notFound.action1": "返回到您的仪表板", "xpack.enterpriseSearch.notFound.action2": "联系支持人员", "xpack.enterpriseSearch.notFound.description": "找不到您要查找的页面。", @@ -18436,7 +18361,6 @@ "xpack.enterpriseSearch.searchApplications.searchApplication.indices.searchPlaceholder": "筛选索引", "xpack.enterpriseSearch.searchApplications.searchApplication.indices.someUnknownIndicesCallout.description": "可能无法从此搜索应用程序访问某些数据。在受影响的索引上检查任何待处理操作或错误,或移除应不再被此搜索应用程序使用的索引。", "xpack.enterpriseSearch.searchApplications.searchApplication.indices.someUnknownIndicesCallout.title": "您的某些索引不可用。", - "xpack.enterpriseSearch.searchApplications.searchApplication.notFound.action1": "返回到搜索应用程序", "xpack.enterpriseSearch.searchApplications.searchApplication.schema.conflictsCallOut.button": "查看冲突", "xpack.enterpriseSearch.searchApplications.searchApplication.schema.conflictsCallOut.description": "可以通过直接导航到源索引并更新冲突字段的字段类型,使其与其他源索引的字段类型相匹配,从而解决架构字段类型冲突。", "xpack.enterpriseSearch.searchApplications.searchApplication.schema.conflictsCallOut.title": "发现潜在的字段映射问题", @@ -18649,10 +18573,6 @@ "xpack.enterpriseSearch.vectorSearch.guide.query.title": "执行向量搜索", "xpack.enterpriseSearch.vectorSearch.navTitle": "矢量搜索", "xpack.enterpriseSearch.vectorSearch.productName": "矢量搜索", - "xpack.enterpriseSearch.versionMismatch.body": "您的 Kibana 和 Enterprise Search 版本不匹配。要访问 Enterprise Search,请对每项服务使用相同的主要和次要版本。", - "xpack.enterpriseSearch.versionMismatch.enterpriseSearchVersionText": "Enterprise Search 版本:{enterpriseSearchVersion}", - "xpack.enterpriseSearch.versionMismatch.kibanaVersionText": "Kibana 版本:{kibanaVersion}", - "xpack.enterpriseSearch.versionMismatch.title": "版本不兼容错误", "xpack.enterpriseSearch.welcomeBanner.header.greeting.customTitle": "👋 {name} 您好!", "xpack.enterpriseSearch.welcomeBanner.header.greeting.defaultTitle": "👋 您好", "xpack.enterpriseSearch.welcomeBanner.header.title": "将数据添加到 Elasticsearch,然后进行搜索、向量化或可视化", @@ -22223,10 +22143,6 @@ "xpack.idxMgmt.home.componentTemplates.list.loadingMessage": "正在加载组件模板……", "xpack.idxMgmt.home.componentTemplatesTabTitle": "组件模板", "xpack.idxMgmt.home.dataStreamsTabTitle": "数据流", - "xpack.idxMgmt.home.enrichPolicies.checkingPrivilegesDescription": "正在检查权限……", - "xpack.idxMgmt.home.enrichPolicies.checkingPrivilegesErrorMessage": "从服务器获取用户权限时出错。", - "xpack.idxMgmt.home.enrichPolicies.deniedPrivilegeDescription": "要使用扩充策略,必须具有以下集群权限:{missingPrivileges}。", - "xpack.idxMgmt.home.enrichPolicies.deniedPrivilegeTitle": "管理所需的扩充权限", "xpack.idxMgmt.home.enrichPoliciesTabTitle": "扩充策略", "xpack.idxMgmt.home.idxMgmtDescription": "分别或批量更新您的 Elasticsearch 索引。{learnMoreLink}", "xpack.idxMgmt.home.idxMgmtDocsLinkText": "索引管理文档", @@ -36551,8 +36467,6 @@ "xpack.securitySolution.assistant.quickPrompts.alertSummarizationTitle": "告警汇总", "xpack.securitySolution.assistant.quickPrompts.AutomationPrompt": "我应使用哪个启用 Fleet 的 Elastic 代理集成从以下项中收集日志和事件:", "xpack.securitySolution.assistant.quickPrompts.AutomationTitle": "代理集成建议", - "xpack.securitySolution.assistant.quickPrompts.esqlQueryGenerationPrompt": "作为 Elastic Security 的专家用户,请生成准确、有效的 ESQL 查询来检测以下用例。应对您的响应进行格式化,以便可以立即在 Elastic Security 时间线或检测规则中使用。请花点时间提供答案,检验您是否清楚了解我所询问的所有功能。具体来说,对于 ES|QL 答案,您应仅根据自己的个人观点进行解答。我无法承担查询不准确的后果。假设我正使用 Elastic Common Schema 和 Elastic 代理。确保以可轻松复制为 Markdown 中的独立代码块的方式设置答案的格式。", - "xpack.securitySolution.assistant.quickPrompts.esqlQueryGenerationTitle": "ES|QL 查询生成", "xpack.securitySolution.assistant.quickPrompts.ruleCreationPrompt": "作为 Elastic Security 的专家用户,请生成准确、有效的 EQL 查询来检测以下用例。应对您的响应进行格式化,以便可以立即在 Elastic Security 时间线或检测规则中使用。如果 Elastic Security 已经为此用例预构建了规则,或具有类似规则,请提供该规则的链接并做出描述。", "xpack.securitySolution.assistant.quickPrompts.ruleCreationTitle": "查询生成", "xpack.securitySolution.assistant.quickPrompts.splQueryConversionPrompt": "我具有以下来自之前 SIEM 平台的查询。作为 Elastic Security 的专家用户,请提议一个 Elastic EQL 等价查询。我应能够立即将其复制到 Elastic Security 时间线。", @@ -39738,7 +39652,6 @@ "xpack.securitySolution.entityAnalytics.assetCriticalityUploadPage.noPermissionTitle": "索引权限不足,无法执行 CSV 上传", "xpack.securitySolution.entityAnalytics.assetCriticalityUploadPage.resultsStepTitle": "结果", "xpack.securitySolution.entityAnalytics.assetCriticalityUploadPage.selectFileStepTitle": "选择文件", - "xpack.securitySolution.entityAnalytics.assetCriticalityUploadPage.subTitle": "使用文本文件导入实体", "xpack.securitySolution.entityAnalytics.assetCriticalityUploadPage.unavailable": "资产关键度 CSV 文件上传功能不可用。", "xpack.securitySolution.entityAnalytics.assetCriticalityUploadPage.unsupportedFileTypeError": "选定的文件格式无效。请选择 {supportedFileExtensions} 文件,然后重试", "xpack.securitySolution.entityAnalytics.assetCriticalityUploadPage.uploadFileSizeLimit": "最大文件大小:{maxFileSize}", @@ -39780,7 +39693,6 @@ "xpack.securitySolution.entityAnalytics.entityStoreManagementPage.clearEntitiesModal.clearAllEntities": "清除所有实体", "xpack.securitySolution.entityAnalytics.entityStoreManagementPage.clearEntitiesModal.close": "关闭", "xpack.securitySolution.entityAnalytics.entityStoreManagementPage.clearEntitiesModal.title": "清除实体数据?", - "xpack.securitySolution.entityAnalytics.entityStoreManagementPage.clearEntityData": "移除从仓库中提取的所有实体数据。此操作将永久删除持久化用户和主机记录,并且数据将不再可用于分析。请谨慎操作,因为此操作无法撤消。请注意,此操作不会删除源数据、实体风险分数或资产关键度分配。", "xpack.securitySolution.entityAnalytics.entityStoreManagementPage.featureFlagDisabled": "实体仓库功能不可用", "xpack.securitySolution.entityAnalytics.entityStoreManagementPage.subTitle": "允许全面监测您系统的主机和用户。", "xpack.securitySolution.entityAnalytics.entityStoreManagementPage.title": "实体仓库", @@ -45510,7 +45422,6 @@ "xpack.synthetics.failedStep.label": "失败的步骤", "xpack.synthetics.fcp.label": "FCP", "xpack.synthetics.featureRegistry.syntheticsFeatureName": "Synthetics 和 Uptime", - "xpack.synthetics.features.app": "Synthetics", "xpack.synthetics.features.elasticManagedLocations": "已启用 Elastic 托管位置", "xpack.synthetics.fieldLabels.cls": "累计布局偏移 (CLS)", "xpack.synthetics.fieldLabels.dcl": "DOMContentLoaded 事件 (DCL)", @@ -47848,7 +47759,6 @@ "xpack.triggersActionsUI.updateApiKeyConfirmModal.failureMessage": "无法更新 API {idsToUpdate, plural, other {密钥}}", "xpack.triggersActionsUI.updateApiKeyConfirmModal.title": "更新 API 密钥", "xpack.triggersActionsUI.urlSyncedAlertsSearchBar.invalidQueryTitle": "字符串查询无效", - "xpack.triggersActionsUI.useRuleAADFields.errorMessage": "无法按规则类型加载告警字段", "xpack.upgradeAssistant.app.deniedPrivilegeDescription": "要使用升级助手并解决弃用问题,必须具有管理所有 Kibana 工作区的访问权限。", "xpack.upgradeAssistant.app.deniedPrivilegeTitle": "需要 Kibana 管理员角色", "xpack.upgradeAssistant.appTitle": "升级助手", diff --git a/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_load_alert_summary.test.ts b/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_load_alert_summary.test.ts index 92c1e3bc5ca69..b21439038cd72 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_load_alert_summary.test.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_load_alert_summary.test.ts @@ -6,7 +6,6 @@ */ import { waitFor, renderHook } from '@testing-library/react'; -import { ValidFeatureId } from '@kbn/rule-data-utils'; import { useKibana } from '../../common/lib/kibana'; import { mockedAlertSummaryResponse, @@ -18,7 +17,7 @@ jest.mock('../../common/lib/kibana'); const useKibanaMock = useKibana as jest.Mocked; describe('useLoadAlertSummary', () => { - const featureIds: ValidFeatureId[] = ['apm']; + const ruleTypeIds: string[] = ['apm']; const mockedPostAPI = jest.fn(); beforeAll(() => { @@ -36,7 +35,7 @@ describe('useLoadAlertSummary', () => { const { result } = renderHook(() => useLoadAlertSummary({ - featureIds, + ruleTypeIds, timeRange: mockedAlertSummaryTimeRange, }) ); @@ -72,7 +71,7 @@ describe('useLoadAlertSummary', () => { renderHook(() => useLoadAlertSummary({ - featureIds, + ruleTypeIds, timeRange: mockedAlertSummaryTimeRange, filter, }) @@ -82,7 +81,7 @@ describe('useLoadAlertSummary', () => { fixed_interval: fixedInterval, gte: utcFrom, lte: utcTo, - featureIds, + ruleTypeIds, filter: [filter], }); @@ -102,7 +101,7 @@ describe('useLoadAlertSummary', () => { const { result } = renderHook(() => useLoadAlertSummary({ - featureIds, + ruleTypeIds, timeRange: mockedAlertSummaryTimeRange, }) ); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_load_alert_summary.ts b/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_load_alert_summary.ts index 10ce201885098..c8053ca571477 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_load_alert_summary.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_load_alert_summary.ts @@ -6,7 +6,6 @@ */ import { useEffect, useState, useCallback, useRef } from 'react'; -import type { ValidFeatureId } from '@kbn/rule-data-utils'; import { estypes } from '@elastic/elasticsearch'; import { AsApiContract } from '@kbn/actions-plugin/common'; import { HttpSetup } from '@kbn/core/public'; @@ -15,7 +14,8 @@ import { useKibana } from '../../common/lib/kibana'; import { Alert, AlertSummaryTimeRange } from '../sections/alert_summary_widget/types'; interface UseLoadAlertSummaryProps { - featureIds?: ValidFeatureId[]; + ruleTypeIds?: string[]; + consumers?: string[]; timeRange: AlertSummaryTimeRange; filter?: estypes.QueryDslQueryContainer; } @@ -32,7 +32,12 @@ interface LoadAlertSummaryResponse { error?: string; } -export function useLoadAlertSummary({ featureIds, timeRange, filter }: UseLoadAlertSummaryProps) { +export function useLoadAlertSummary({ + ruleTypeIds, + consumers, + timeRange, + filter, +}: UseLoadAlertSummaryProps) { const { http } = useKibana().services; const [alertSummary, setAlertSummary] = useState({ isLoading: true, @@ -45,14 +50,15 @@ export function useLoadAlertSummary({ featureIds, timeRange, filter }: UseLoadAl const isCancelledRef = useRef(false); const abortCtrlRef = useRef(new AbortController()); const loadAlertSummary = useCallback(async () => { - if (!featureIds) return; + if (!ruleTypeIds) return; isCancelledRef.current = false; abortCtrlRef.current.abort(); abortCtrlRef.current = new AbortController(); try { const { activeAlertCount, activeAlerts, recoveredAlertCount } = await fetchAlertSummary({ - featureIds, + ruleTypeIds, + consumers, filter, http, signal: abortCtrlRef.current.signal, @@ -80,7 +86,7 @@ export function useLoadAlertSummary({ featureIds, timeRange, filter }: UseLoadAl } } } - }, [featureIds, filter, http, timeRange]); + }, [ruleTypeIds, consumers, filter, http, timeRange]); useEffect(() => { loadAlertSummary(); @@ -90,26 +96,29 @@ export function useLoadAlertSummary({ featureIds, timeRange, filter }: UseLoadAl } async function fetchAlertSummary({ - featureIds, + ruleTypeIds, + consumers, filter, http, signal, timeRange: { utcFrom, utcTo, fixedInterval }, }: { http: HttpSetup; - featureIds: ValidFeatureId[]; + ruleTypeIds: string[]; + consumers?: string[]; signal: AbortSignal; timeRange: AlertSummaryTimeRange; filter?: estypes.QueryDslQueryContainer; }): Promise { - const res = featureIds.length + const res = ruleTypeIds.length ? await http.post>(`${BASE_RAC_ALERTS_API_PATH}/_alert_summary`, { signal, body: JSON.stringify({ fixed_interval: fixedInterval, gte: utcFrom, lte: utcTo, - featureIds, + ruleTypeIds, + consumers, filter: [filter], }), }) diff --git a/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_load_rule_aggregations.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_load_rule_aggregations.test.tsx index e1cb5f6f4f5ee..b84e1b529b493 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_load_rule_aggregations.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_load_rule_aggregations.test.tsx @@ -6,7 +6,10 @@ */ import React from 'react'; import { waitFor, renderHook } from '@testing-library/react'; -import { useLoadRuleAggregationsQuery as useLoadRuleAggregations } from './use_load_rule_aggregations_query'; +import { + UseLoadRuleAggregationsQueryProps, + useLoadRuleAggregationsQuery as useLoadRuleAggregations, +} from './use_load_rule_aggregations_query'; import { RuleStatus } from '../../types'; import { useKibana } from '../../common/lib/kibana'; import { IToasts } from '@kbn/core-notifications-browser'; @@ -59,10 +62,9 @@ describe('useLoadRuleAggregations', () => { }); it('should call loadRuleAggregations API and handle result', async () => { - const params = { + const params: UseLoadRuleAggregationsQueryProps = { filters: { searchText: '', - types: [], actionTypes: [], ruleExecutionStatuses: [], ruleLastRunOutcomes: [], @@ -72,6 +74,8 @@ describe('useLoadRuleAggregations', () => { }, enabled: true, refresh: undefined, + ruleTypeIds: [], + consumers: [], }; const { rerender, result } = renderHook( @@ -87,12 +91,13 @@ describe('useLoadRuleAggregations', () => { expect(loadRuleAggregationsWithKueryFilter).toBeCalledWith( expect.objectContaining({ searchText: '', - typesFilter: [], actionTypesFilter: [], ruleExecutionStatusesFilter: [], ruleLastRunOutcomesFilter: [], ruleStatusesFilter: [], tagsFilter: [], + ruleTypeIds: [], + consumers: [], }) ); expect(result.current.rulesStatusesTotal).toEqual(MOCK_AGGS.ruleExecutionStatus); @@ -100,10 +105,9 @@ describe('useLoadRuleAggregations', () => { }); it('should call loadRuleAggregation API with params and handle result', async () => { - const params = { + const params: UseLoadRuleAggregationsQueryProps = { filters: { searchText: 'test', - types: ['type1', 'type2'], actionTypes: ['action1', 'action2'], ruleExecutionStatuses: ['status1', 'status2'], ruleParams: {}, @@ -113,6 +117,8 @@ describe('useLoadRuleAggregations', () => { }, enabled: true, refresh: undefined, + ruleTypeIds: ['foo'], + consumers: ['bar'], }; const { rerender, result } = renderHook(() => useLoadRuleAggregations(params), { @@ -125,12 +131,13 @@ describe('useLoadRuleAggregations', () => { expect(loadRuleAggregationsWithKueryFilter).toBeCalledWith( expect.objectContaining({ searchText: 'test', - typesFilter: ['type1', 'type2'], actionTypesFilter: ['action1', 'action2'], ruleExecutionStatusesFilter: ['status1', 'status2'], ruleStatusesFilter: ['enabled', 'snoozed'] as RuleStatus[], tagsFilter: ['tag1', 'tag2'], ruleLastRunOutcomesFilter: ['outcome1', 'outcome2'], + ruleTypeIds: ['foo'], + consumers: ['bar'], }) ); expect(result.current.rulesStatusesTotal).toEqual(MOCK_AGGS.ruleExecutionStatus); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_load_rule_aggregations_query.ts b/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_load_rule_aggregations_query.ts index b7f5be0325729..c588959dedf52 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_load_rule_aggregations_query.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_load_rule_aggregations_query.ts @@ -22,15 +22,16 @@ const initializeAggregationResult = (values: readonly string[]) => { ); }; -interface UseLoadRuleAggregationsQueryProps { +export interface UseLoadRuleAggregationsQueryProps { filters: RulesListFilters; enabled: boolean; - filterConsumers?: string[]; + ruleTypeIds?: string[]; + consumers?: string[]; refresh?: Date; } export const useLoadRuleAggregationsQuery = (props: UseLoadRuleAggregationsQueryProps) => { - const { filters, enabled, refresh, filterConsumers } = props; + const { filters, enabled, refresh, ruleTypeIds, consumers } = props; const { http, @@ -41,13 +42,13 @@ export const useLoadRuleAggregationsQuery = (props: UseLoadRuleAggregationsQuery return loadRuleAggregationsWithKueryFilter({ http, searchText: filters.searchText, - typesFilter: filters.types, actionTypesFilter: filters.actionTypes, ruleExecutionStatusesFilter: filters.ruleExecutionStatuses, ruleLastRunOutcomesFilter: filters.ruleLastRunOutcomes, ruleStatusesFilter: filters.ruleStatuses, tagsFilter: filters.tags, - filterConsumers, + ruleTypeIds, + consumers, }); }; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_load_rules_query.ts b/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_load_rules_query.ts index 795e316786892..7806e6ce1e6aa 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_load_rules_query.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_load_rules_query.ts @@ -20,7 +20,8 @@ type UseLoadRulesQueryProps = Omit & { sort: LoadRulesProps['sort']; enabled: boolean; refresh?: Date; - filterConsumers?: string[]; + ruleTypeIds?: string[]; + consumers?: string[]; hasReference?: { type: string; id: string; @@ -28,7 +29,8 @@ type UseLoadRulesQueryProps = Omit & { }; export const useLoadRulesQuery = (props: UseLoadRulesQueryProps) => { - const { filterConsumers, filters, page, sort, onPage, enabled, refresh, hasReference } = props; + const { ruleTypeIds, consumers, filters, page, sort, onPage, enabled, refresh, hasReference } = + props; const { http, notifications: { toasts }, @@ -56,7 +58,7 @@ export const useLoadRulesQuery = (props: UseLoadRulesQueryProps) => { { refresh: refresh?.toISOString(), }, - filterConsumers, + ruleTypeIds, hasReference, ], queryFn: () => { @@ -73,7 +75,8 @@ export const useLoadRulesQuery = (props: UseLoadRulesQueryProps) => { tagsFilter: filters.tags, kueryNode: filters.kueryNode, sort, - filterConsumers, + ruleTypeIds, + consumers, hasReference, }); }, 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 deleted file mode 100644 index 91aaf19776d8b..0000000000000 --- a/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_rule_aad_fields.ts +++ /dev/null @@ -1,58 +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 { DataViewField } from '@kbn/data-views-plugin/common'; -import { useKibana } from '@kbn/kibana-react-plugin/public'; -import { useQuery } from '@tanstack/react-query'; -import { i18n } from '@kbn/i18n'; -import { useMemo } from 'react'; -import { fetchRuleTypeAadTemplateFields } from '@kbn/alerts-ui-shared/src/common/apis/fetch_rule_type_aad_template_fields'; -import { TriggersAndActionsUiServices } from '../..'; - -const EMPTY_AAD_FIELDS: DataViewField[] = []; - -export function useRuleAADFields(ruleTypeId?: string): { - aadFields: DataViewField[]; - loading: boolean; -} { - const { - http, - notifications: { toasts }, - } = useKibana().services; - - const queryAadFieldsFn = () => { - return fetchRuleTypeAadTemplateFields({ http, ruleTypeId }); - }; - - const onErrorFn = () => { - toasts.addDanger( - i18n.translate('xpack.triggersActionsUI.useRuleAADFields.errorMessage', { - defaultMessage: 'Unable to load alert fields per rule type', - }) - ); - }; - - const { - data: aadFields = EMPTY_AAD_FIELDS, - isInitialLoading, - isLoading, - } = useQuery({ - queryKey: ['loadAlertAadFieldsPerRuleType', ruleTypeId], - queryFn: queryAadFieldsFn, - onError: onErrorFn, - refetchOnWindowFocus: false, - enabled: ruleTypeId !== undefined, - }); - - 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/check_rule_type_enabled.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/lib/check_rule_type_enabled.test.tsx index 0668fb56c4ef1..5771b505ae0c4 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/check_rule_type_enabled.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/check_rule_type_enabled.test.tsx @@ -33,6 +33,7 @@ describe('checkRuleTypeEnabled', () => { authorizedConsumers: {}, minimumLicenseRequired: 'basic', enabledInLicense: true, + category: 'my-category', }; expect(checkRuleTypeEnabled(alertType)).toMatchInlineSnapshot(` Object { @@ -57,6 +58,7 @@ describe('checkRuleTypeEnabled', () => { authorizedConsumers: {}, minimumLicenseRequired: 'gold', enabledInLicense: false, + category: 'my-category', }; expect(checkRuleTypeEnabled(alertType)).toMatchInlineSnapshot(` Object { diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/execution_duration_utils.test.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/execution_duration_utils.test.ts index f7ade3778f287..7bce422f5f9f3 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/execution_duration_utils.test.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/execution_duration_utils.test.ts @@ -63,6 +63,7 @@ function mockRuleType(overwrites: Partial = {}): RuleType { producer: 'alerts', minimumLicenseRequired: 'basic', enabledInLicense: true, + category: 'my-category', ...overwrites, }; } diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/aggregate.test.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/aggregate.test.ts index a5ae973f14d97..b546748d695e4 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/aggregate.test.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/aggregate.test.ts @@ -113,7 +113,7 @@ describe('loadRuleAggregations', () => { `); }); - test('should call aggregate API with typesFilter', async () => { + test('should call aggregate API with ruleTypeIds', async () => { const resolvedValue = { rule_execution_status: { ok: 4, @@ -127,7 +127,7 @@ describe('loadRuleAggregations', () => { const result = await loadRuleAggregations({ http, - typesFilter: ['foo', 'bar'], + ruleTypeIds: ['foo', 'bar'], }); expect(result).toEqual({ ruleExecutionStatus: { @@ -142,13 +142,13 @@ describe('loadRuleAggregations', () => { Array [ "/internal/alerting/rules/_aggregate", Object { - "body": "{\\"filter\\":\\"alert.attributes.alertTypeId:(foo or bar)\\",\\"default_search_operator\\":\\"AND\\"}", + "body": "{\\"default_search_operator\\":\\"AND\\",\\"rule_type_ids\\":[\\"foo\\",\\"bar\\"]}", }, ] `); }); - test('should call aggregate API with actionTypesFilter and typesFilter', async () => { + test('should call aggregate API with actionTypesFilter and ruleTypeIds', async () => { const resolvedValue = { rule_execution_status: { ok: 4, @@ -164,7 +164,7 @@ describe('loadRuleAggregations', () => { http, searchText: 'baz', actionTypesFilter: ['action', 'type'], - typesFilter: ['foo', 'bar'], + ruleTypeIds: ['foo', 'bar'], }); expect(result).toEqual({ ruleExecutionStatus: { @@ -179,7 +179,7 @@ describe('loadRuleAggregations', () => { Array [ "/internal/alerting/rules/_aggregate", Object { - "body": "{\\"search_fields\\":\\"[\\\\\\"name\\\\\\",\\\\\\"tags\\\\\\"]\\",\\"search\\":\\"baz\\",\\"filter\\":\\"alert.attributes.alertTypeId:(foo or bar) and (alert.attributes.actions:{ actionTypeId:action } OR alert.attributes.actions:{ actionTypeId:type })\\",\\"default_search_operator\\":\\"AND\\"}", + "body": "{\\"search_fields\\":\\"[\\\\\\"name\\\\\\",\\\\\\"tags\\\\\\"]\\",\\"search\\":\\"baz\\",\\"filter\\":\\"(alert.attributes.actions:{ actionTypeId:action } OR alert.attributes.actions:{ actionTypeId:type })\\",\\"default_search_operator\\":\\"AND\\",\\"rule_type_ids\\":[\\"foo\\",\\"bar\\"]}", }, ] `); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/aggregate.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/aggregate.ts index 8edb10811bd8e..af855075cca87 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/aggregate.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/aggregate.ts @@ -39,15 +39,14 @@ export async function loadRuleTags({ export async function loadRuleAggregations({ http, searchText, - typesFilter, actionTypesFilter, ruleExecutionStatusesFilter, ruleStatusesFilter, tagsFilter, - filterConsumers, + ruleTypeIds, + consumers, }: LoadRuleAggregationsProps): Promise { const filters = mapFiltersToKql({ - typesFilter, actionTypesFilter, ruleExecutionStatusesFilter, ruleStatusesFilter, @@ -61,7 +60,8 @@ export async function loadRuleAggregations({ search: searchText, filter: filters.length ? filters.join(' and ') : undefined, default_search_operator: 'AND', - filter_consumers: filterConsumers, + rule_type_ids: ruleTypeIds, + consumers, }), } ); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/aggregate_helpers.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/aggregate_helpers.ts index 29462f07d5eec..fb787c249aeb9 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/aggregate_helpers.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/aggregate_helpers.ts @@ -61,13 +61,13 @@ export const rewriteTagsBodyRes: RewriteRequestCase = ({ export interface LoadRuleAggregationsProps { http: HttpSetup; searchText?: string; - typesFilter?: string[]; actionTypesFilter?: string[]; ruleExecutionStatusesFilter?: string[]; ruleLastRunOutcomesFilter?: string[]; ruleStatusesFilter?: RuleStatus[]; tagsFilter?: string[]; - filterConsumers?: string[]; + ruleTypeIds?: string[]; + consumers?: string[]; } export interface LoadRuleTagsProps { diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/aggregate_kuery_filter.test.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/aggregate_kuery_filter.test.ts new file mode 100644 index 0000000000000..a76147033fe65 --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/aggregate_kuery_filter.test.ts @@ -0,0 +1,115 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor 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 { httpServiceMock } from '@kbn/core/public/mocks'; +import { loadRuleAggregationsWithKueryFilter } from './aggregate_kuery_filter'; + +const http = httpServiceMock.createStartContract(); + +describe('loadRuleAggregationsWithKueryFilter', () => { + beforeEach(() => jest.resetAllMocks()); + + test('should call aggregate API with base parameters', async () => { + const resolvedValue = { + rule_execution_status: { + ok: 4, + active: 2, + error: 1, + pending: 1, + unknown: 0, + }, + }; + http.post.mockResolvedValueOnce(resolvedValue); + + const result = await loadRuleAggregationsWithKueryFilter({ http }); + expect(result).toEqual({ + ruleExecutionStatus: { + ok: 4, + active: 2, + error: 1, + pending: 1, + unknown: 0, + }, + }); + expect(http.post.mock.calls[0]).toMatchInlineSnapshot(` + Array [ + "/internal/alerting/rules/_aggregate", + Object { + "body": "{\\"default_search_operator\\":\\"AND\\"}", + }, + ] + `); + }); + + test('should call aggregate API with ruleTypeIds', async () => { + const resolvedValue = { + rule_execution_status: { + ok: 4, + active: 2, + error: 1, + pending: 1, + unknown: 0, + }, + }; + + http.post.mockResolvedValueOnce(resolvedValue); + + const result = await loadRuleAggregationsWithKueryFilter({ http, ruleTypeIds: ['foo'] }); + expect(result).toEqual({ + ruleExecutionStatus: { + ok: 4, + active: 2, + error: 1, + pending: 1, + unknown: 0, + }, + }); + + expect(http.post.mock.calls[0]).toMatchInlineSnapshot(` + Array [ + "/internal/alerting/rules/_aggregate", + Object { + "body": "{\\"rule_type_ids\\":[\\"foo\\"],\\"default_search_operator\\":\\"AND\\"}", + }, + ] + `); + }); + + test('should call aggregate API with consumers', async () => { + const resolvedValue = { + rule_execution_status: { + ok: 4, + active: 2, + error: 1, + pending: 1, + unknown: 0, + }, + }; + + http.post.mockResolvedValueOnce(resolvedValue); + + const result = await loadRuleAggregationsWithKueryFilter({ http, consumers: ['foo'] }); + expect(result).toEqual({ + ruleExecutionStatus: { + ok: 4, + active: 2, + error: 1, + pending: 1, + unknown: 0, + }, + }); + + expect(http.post.mock.calls[0]).toMatchInlineSnapshot(` + Array [ + "/internal/alerting/rules/_aggregate", + Object { + "body": "{\\"default_search_operator\\":\\"AND\\",\\"consumers\\":[\\"foo\\"]}", + }, + ] + `); + }); +}); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/aggregate_kuery_filter.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/aggregate_kuery_filter.ts index a0e270ddf2f67..dce41afcc8110 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/aggregate_kuery_filter.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/aggregate_kuery_filter.ts @@ -16,15 +16,14 @@ import { mapFiltersToKueryNode } from './map_filters_to_kuery_node'; export async function loadRuleAggregationsWithKueryFilter({ http, searchText, - typesFilter, actionTypesFilter, ruleExecutionStatusesFilter, ruleStatusesFilter, tagsFilter, - filterConsumers, + ruleTypeIds, + consumers, }: LoadRuleAggregationsProps): Promise { const filtersKueryNode = mapFiltersToKueryNode({ - typesFilter, actionTypesFilter, tagsFilter, ruleExecutionStatusesFilter, @@ -37,8 +36,9 @@ export async function loadRuleAggregationsWithKueryFilter({ { body: JSON.stringify({ ...(filtersKueryNode ? { filter: JSON.stringify(filtersKueryNode) } : {}), - filter_consumers: filterConsumers, + rule_type_ids: ruleTypeIds, default_search_operator: 'AND', + consumers, }), } ); 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 deleted file mode 100644 index 7be5b3eec0e69..0000000000000 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/alert_fields.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; 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 deleted file mode 100644 index 8ac678664168b..0000000000000 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/alert_index.ts +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { 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/lib/rule_api/rule_types.test.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/rule_types.test.ts index cd9e829c8045e..0c42a21d7d436 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/rule_types.test.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/rule_types.test.ts @@ -30,6 +30,7 @@ describe('loadRuleTypes', () => { authorizedConsumers: {}, minimumLicenseRequired: 'basic', enabledInLicense: true, + category: 'my-category', }, ]; http.get.mockResolvedValueOnce(resolvedValue); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/rules.test.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/rules.test.ts index b5a09e5a716f9..5fa4f83509650 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/rules.test.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/rules.test.ts @@ -240,6 +240,55 @@ describe('loadRules', () => { `); }); + test('should call find API with searchText and tagsFilter and ruleTypeIds and consumers', async () => { + const resolvedValue = { + page: 1, + per_page: 10, + total: 0, + data: [], + }; + http.get.mockResolvedValueOnce(resolvedValue); + + const result = await loadRules({ + http, + searchText: 'apples, foo, baz', + typesFilter: ['foo', 'bar'], + ruleTypeIds: ['one', 'two'], + consumers: ['my-consumer'], + page: { index: 0, size: 10 }, + }); + expect(result).toEqual({ + page: 1, + perPage: 10, + total: 0, + data: [], + }); + expect(http.get.mock.calls[0]).toMatchInlineSnapshot(` + Array [ + "/internal/alerting/rules/_find", + Object { + "query": Object { + "consumers": Array [ + "my-consumer", + ], + "default_search_operator": "AND", + "filter": "alert.attributes.alertTypeId:(foo or bar)", + "page": 1, + "per_page": 10, + "rule_type_ids": Array [ + "one", + "two", + ], + "search": "apples, foo, baz", + "search_fields": "[\\"name\\",\\"tags\\"]", + "sort_field": "name", + "sort_order": "asc", + }, + }, + ] + `); + }); + test('should call find API with ruleStatusesFilter', async () => { const resolvedValue = { page: 1, @@ -374,4 +423,90 @@ describe('loadRules', () => { ] `); }); + + test('should call find API with ruleTypeIds', async () => { + const resolvedValue = { + page: 1, + per_page: 10, + total: 0, + data: [], + }; + http.get.mockResolvedValueOnce(resolvedValue); + + const result = await loadRules({ + http, + ruleTypeIds: ['foo', 'bar'], + page: { index: 0, size: 10 }, + }); + expect(result).toEqual({ + page: 1, + perPage: 10, + total: 0, + data: [], + }); + expect(http.get.mock.calls[0]).toMatchInlineSnapshot(` + Array [ + "/internal/alerting/rules/_find", + Object { + "query": Object { + "default_search_operator": "AND", + "filter": undefined, + "page": 1, + "per_page": 10, + "rule_type_ids": Array [ + "foo", + "bar", + ], + "search": undefined, + "search_fields": undefined, + "sort_field": "name", + "sort_order": "asc", + }, + }, + ] + `); + }); + + test('should call find API with consumers', async () => { + const resolvedValue = { + page: 1, + per_page: 10, + total: 0, + data: [], + }; + http.get.mockResolvedValueOnce(resolvedValue); + + const result = await loadRules({ + http, + consumers: ['foo', 'bar'], + page: { index: 0, size: 10 }, + }); + expect(result).toEqual({ + page: 1, + perPage: 10, + total: 0, + data: [], + }); + expect(http.get.mock.calls[0]).toMatchInlineSnapshot(` + Array [ + "/internal/alerting/rules/_find", + Object { + "query": Object { + "consumers": Array [ + "foo", + "bar", + ], + "default_search_operator": "AND", + "filter": undefined, + "page": 1, + "per_page": 10, + "search": undefined, + "search_fields": undefined, + "sort_field": "name", + "sort_order": "asc", + }, + }, + ] + `); + }); }); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/rules.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/rules.ts index 07a992c66c96c..8c17f18065c84 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/rules.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/rules.ts @@ -21,6 +21,8 @@ export async function loadRules({ ruleStatusesFilter, tagsFilter, sort = { field: 'name', direction: 'asc' }, + ruleTypeIds, + consumers, }: LoadRulesProps): Promise<{ page: number; perPage: number; @@ -51,6 +53,8 @@ export async function loadRules({ default_search_operator: 'AND', sort_field: sort.field, sort_order: sort.direction, + ...(ruleTypeIds ? { rule_type_ids: ruleTypeIds } : {}), + ...(consumers ? { consumers } : {}), }, }); return { diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/rules_helpers.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/rules_helpers.ts index 4f8a8627bab52..aa1e2d1dac26f 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/rules_helpers.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/rules_helpers.ts @@ -24,7 +24,8 @@ export interface LoadRulesProps { ruleStatusesFilter?: RuleStatus[]; sort?: Sorting; kueryNode?: KueryNode; - filterConsumers?: string[]; + ruleTypeIds?: string[]; + consumers?: string[]; hasReference?: { type: string; id: string; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/rules_kuery_filter.test.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/rules_kuery_filter.test.ts new file mode 100644 index 0000000000000..9e9821b8d82cb --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/rules_kuery_filter.test.ts @@ -0,0 +1,384 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor 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 { httpServiceMock } from '@kbn/core/public/mocks'; +import { loadRulesWithKueryFilter } from './rules_kuery_filter'; + +const http = httpServiceMock.createStartContract(); + +describe('loadRulesWithKueryFilter', () => { + beforeEach(() => jest.resetAllMocks()); + + test('should call find API with base parameters', async () => { + const resolvedValue = { + page: 1, + per_page: 10, + total: 0, + data: [], + }; + http.post.mockResolvedValueOnce(resolvedValue); + + const result = await loadRulesWithKueryFilter({ http, page: { index: 0, size: 10 } }); + expect(result).toEqual({ + page: 1, + perPage: 10, + total: 0, + data: [], + }); + expect(http.post.mock.calls[0]).toMatchInlineSnapshot(` + Array [ + "/internal/alerting/rules/_find", + Object { + "body": "{\\"page\\":1,\\"per_page\\":10,\\"sort_field\\":\\"name\\",\\"sort_order\\":\\"asc\\"}", + }, + ] + `); + }); + + test('should call find API with searchText', async () => { + const resolvedValue = { + page: 1, + per_page: 10, + total: 0, + data: [], + }; + http.post.mockResolvedValueOnce(resolvedValue); + + const result = await loadRulesWithKueryFilter({ + http, + searchText: 'apples', + page: { index: 0, size: 10 }, + }); + expect(result).toEqual({ + page: 1, + perPage: 10, + total: 0, + data: [], + }); + expect(http.post.mock.calls[0]).toMatchInlineSnapshot(` + Array [ + "/internal/alerting/rules/_find", + Object { + "body": "{\\"page\\":1,\\"per_page\\":10,\\"filter\\":\\"{\\\\\\"type\\\\\\":\\\\\\"function\\\\\\",\\\\\\"function\\\\\\":\\\\\\"or\\\\\\",\\\\\\"arguments\\\\\\":[{\\\\\\"type\\\\\\":\\\\\\"function\\\\\\",\\\\\\"function\\\\\\":\\\\\\"is\\\\\\",\\\\\\"arguments\\\\\\":[{\\\\\\"type\\\\\\":\\\\\\"literal\\\\\\",\\\\\\"value\\\\\\":\\\\\\"alert.attributes.name\\\\\\",\\\\\\"isQuoted\\\\\\":false},{\\\\\\"type\\\\\\":\\\\\\"wildcard\\\\\\",\\\\\\"value\\\\\\":\\\\\\"apples\\\\\\"}]},{\\\\\\"type\\\\\\":\\\\\\"function\\\\\\",\\\\\\"function\\\\\\":\\\\\\"is\\\\\\",\\\\\\"arguments\\\\\\":[{\\\\\\"type\\\\\\":\\\\\\"literal\\\\\\",\\\\\\"value\\\\\\":\\\\\\"alert.attributes.tags\\\\\\",\\\\\\"isQuoted\\\\\\":false},{\\\\\\"type\\\\\\":\\\\\\"wildcard\\\\\\",\\\\\\"value\\\\\\":\\\\\\"apples\\\\\\"}]}]}\\",\\"sort_field\\":\\"name\\",\\"sort_order\\":\\"asc\\"}", + }, + ] + `); + }); + + test('should call find API with actionTypesFilter', async () => { + const resolvedValue = { + page: 1, + per_page: 10, + total: 0, + data: [], + }; + http.post.mockResolvedValueOnce(resolvedValue); + + const result = await loadRulesWithKueryFilter({ + http, + searchText: 'foo', + page: { index: 0, size: 10 }, + }); + expect(result).toEqual({ + page: 1, + perPage: 10, + total: 0, + data: [], + }); + expect(http.post.mock.calls[0]).toMatchInlineSnapshot(` + Array [ + "/internal/alerting/rules/_find", + Object { + "body": "{\\"page\\":1,\\"per_page\\":10,\\"filter\\":\\"{\\\\\\"type\\\\\\":\\\\\\"function\\\\\\",\\\\\\"function\\\\\\":\\\\\\"or\\\\\\",\\\\\\"arguments\\\\\\":[{\\\\\\"type\\\\\\":\\\\\\"function\\\\\\",\\\\\\"function\\\\\\":\\\\\\"is\\\\\\",\\\\\\"arguments\\\\\\":[{\\\\\\"type\\\\\\":\\\\\\"literal\\\\\\",\\\\\\"value\\\\\\":\\\\\\"alert.attributes.name\\\\\\",\\\\\\"isQuoted\\\\\\":false},{\\\\\\"type\\\\\\":\\\\\\"wildcard\\\\\\",\\\\\\"value\\\\\\":\\\\\\"foo\\\\\\"}]},{\\\\\\"type\\\\\\":\\\\\\"function\\\\\\",\\\\\\"function\\\\\\":\\\\\\"is\\\\\\",\\\\\\"arguments\\\\\\":[{\\\\\\"type\\\\\\":\\\\\\"literal\\\\\\",\\\\\\"value\\\\\\":\\\\\\"alert.attributes.tags\\\\\\",\\\\\\"isQuoted\\\\\\":false},{\\\\\\"type\\\\\\":\\\\\\"wildcard\\\\\\",\\\\\\"value\\\\\\":\\\\\\"foo\\\\\\"}]}]}\\",\\"sort_field\\":\\"name\\",\\"sort_order\\":\\"asc\\"}", + }, + ] + `); + }); + + test('should call find API with typesFilter', async () => { + const resolvedValue = { + page: 1, + per_page: 10, + total: 0, + data: [], + }; + http.post.mockResolvedValueOnce(resolvedValue); + + const result = await loadRulesWithKueryFilter({ + http, + typesFilter: ['foo', 'bar'], + page: { index: 0, size: 10 }, + }); + expect(result).toEqual({ + page: 1, + perPage: 10, + total: 0, + data: [], + }); + expect(http.post.mock.calls[0]).toMatchInlineSnapshot(` + Array [ + "/internal/alerting/rules/_find", + Object { + "body": "{\\"page\\":1,\\"per_page\\":10,\\"filter\\":\\"{\\\\\\"type\\\\\\":\\\\\\"function\\\\\\",\\\\\\"function\\\\\\":\\\\\\"or\\\\\\",\\\\\\"arguments\\\\\\":[{\\\\\\"type\\\\\\":\\\\\\"function\\\\\\",\\\\\\"function\\\\\\":\\\\\\"is\\\\\\",\\\\\\"arguments\\\\\\":[{\\\\\\"type\\\\\\":\\\\\\"literal\\\\\\",\\\\\\"value\\\\\\":\\\\\\"alert.attributes.alertTypeId\\\\\\",\\\\\\"isQuoted\\\\\\":false},{\\\\\\"type\\\\\\":\\\\\\"literal\\\\\\",\\\\\\"value\\\\\\":\\\\\\"foo\\\\\\",\\\\\\"isQuoted\\\\\\":false}]},{\\\\\\"type\\\\\\":\\\\\\"function\\\\\\",\\\\\\"function\\\\\\":\\\\\\"is\\\\\\",\\\\\\"arguments\\\\\\":[{\\\\\\"type\\\\\\":\\\\\\"literal\\\\\\",\\\\\\"value\\\\\\":\\\\\\"alert.attributes.alertTypeId\\\\\\",\\\\\\"isQuoted\\\\\\":false},{\\\\\\"type\\\\\\":\\\\\\"literal\\\\\\",\\\\\\"value\\\\\\":\\\\\\"bar\\\\\\",\\\\\\"isQuoted\\\\\\":false}]}]}\\",\\"sort_field\\":\\"name\\",\\"sort_order\\":\\"asc\\"}", + }, + ] + `); + }); + + test('should call find API with actionTypesFilter and typesFilter', async () => { + const resolvedValue = { + page: 1, + per_page: 10, + total: 0, + data: [], + }; + http.post.mockResolvedValueOnce(resolvedValue); + + const result = await loadRulesWithKueryFilter({ + http, + searchText: 'baz', + typesFilter: ['foo', 'bar'], + page: { index: 0, size: 10 }, + }); + expect(result).toEqual({ + page: 1, + perPage: 10, + total: 0, + data: [], + }); + expect(http.post.mock.calls[0]).toMatchInlineSnapshot(` + Array [ + "/internal/alerting/rules/_find", + Object { + "body": "{\\"page\\":1,\\"per_page\\":10,\\"filter\\":\\"{\\\\\\"type\\\\\\":\\\\\\"function\\\\\\",\\\\\\"function\\\\\\":\\\\\\"and\\\\\\",\\\\\\"arguments\\\\\\":[{\\\\\\"type\\\\\\":\\\\\\"function\\\\\\",\\\\\\"function\\\\\\":\\\\\\"or\\\\\\",\\\\\\"arguments\\\\\\":[{\\\\\\"type\\\\\\":\\\\\\"function\\\\\\",\\\\\\"function\\\\\\":\\\\\\"is\\\\\\",\\\\\\"arguments\\\\\\":[{\\\\\\"type\\\\\\":\\\\\\"literal\\\\\\",\\\\\\"value\\\\\\":\\\\\\"alert.attributes.alertTypeId\\\\\\",\\\\\\"isQuoted\\\\\\":false},{\\\\\\"type\\\\\\":\\\\\\"literal\\\\\\",\\\\\\"value\\\\\\":\\\\\\"foo\\\\\\",\\\\\\"isQuoted\\\\\\":false}]},{\\\\\\"type\\\\\\":\\\\\\"function\\\\\\",\\\\\\"function\\\\\\":\\\\\\"is\\\\\\",\\\\\\"arguments\\\\\\":[{\\\\\\"type\\\\\\":\\\\\\"literal\\\\\\",\\\\\\"value\\\\\\":\\\\\\"alert.attributes.alertTypeId\\\\\\",\\\\\\"isQuoted\\\\\\":false},{\\\\\\"type\\\\\\":\\\\\\"literal\\\\\\",\\\\\\"value\\\\\\":\\\\\\"bar\\\\\\",\\\\\\"isQuoted\\\\\\":false}]}]},{\\\\\\"type\\\\\\":\\\\\\"function\\\\\\",\\\\\\"function\\\\\\":\\\\\\"or\\\\\\",\\\\\\"arguments\\\\\\":[{\\\\\\"type\\\\\\":\\\\\\"function\\\\\\",\\\\\\"function\\\\\\":\\\\\\"is\\\\\\",\\\\\\"arguments\\\\\\":[{\\\\\\"type\\\\\\":\\\\\\"literal\\\\\\",\\\\\\"value\\\\\\":\\\\\\"alert.attributes.name\\\\\\",\\\\\\"isQuoted\\\\\\":false},{\\\\\\"type\\\\\\":\\\\\\"wildcard\\\\\\",\\\\\\"value\\\\\\":\\\\\\"baz\\\\\\"}]},{\\\\\\"type\\\\\\":\\\\\\"function\\\\\\",\\\\\\"function\\\\\\":\\\\\\"is\\\\\\",\\\\\\"arguments\\\\\\":[{\\\\\\"type\\\\\\":\\\\\\"literal\\\\\\",\\\\\\"value\\\\\\":\\\\\\"alert.attributes.tags\\\\\\",\\\\\\"isQuoted\\\\\\":false},{\\\\\\"type\\\\\\":\\\\\\"wildcard\\\\\\",\\\\\\"value\\\\\\":\\\\\\"baz\\\\\\"}]}]}]}\\",\\"sort_field\\":\\"name\\",\\"sort_order\\":\\"asc\\"}", + }, + ] + `); + }); + + test('should call find API with searchText and tagsFilter and typesFilter', async () => { + const resolvedValue = { + page: 1, + per_page: 10, + total: 0, + data: [], + }; + http.post.mockResolvedValueOnce(resolvedValue); + + const result = await loadRulesWithKueryFilter({ + http, + searchText: 'apples, foo, baz', + typesFilter: ['foo', 'bar'], + page: { index: 0, size: 10 }, + }); + expect(result).toEqual({ + page: 1, + perPage: 10, + total: 0, + data: [], + }); + expect(http.post.mock.calls[0]).toMatchInlineSnapshot(` + Array [ + "/internal/alerting/rules/_find", + Object { + "body": "{\\"page\\":1,\\"per_page\\":10,\\"filter\\":\\"{\\\\\\"type\\\\\\":\\\\\\"function\\\\\\",\\\\\\"function\\\\\\":\\\\\\"and\\\\\\",\\\\\\"arguments\\\\\\":[{\\\\\\"type\\\\\\":\\\\\\"function\\\\\\",\\\\\\"function\\\\\\":\\\\\\"or\\\\\\",\\\\\\"arguments\\\\\\":[{\\\\\\"type\\\\\\":\\\\\\"function\\\\\\",\\\\\\"function\\\\\\":\\\\\\"is\\\\\\",\\\\\\"arguments\\\\\\":[{\\\\\\"type\\\\\\":\\\\\\"literal\\\\\\",\\\\\\"value\\\\\\":\\\\\\"alert.attributes.alertTypeId\\\\\\",\\\\\\"isQuoted\\\\\\":false},{\\\\\\"type\\\\\\":\\\\\\"literal\\\\\\",\\\\\\"value\\\\\\":\\\\\\"foo\\\\\\",\\\\\\"isQuoted\\\\\\":false}]},{\\\\\\"type\\\\\\":\\\\\\"function\\\\\\",\\\\\\"function\\\\\\":\\\\\\"is\\\\\\",\\\\\\"arguments\\\\\\":[{\\\\\\"type\\\\\\":\\\\\\"literal\\\\\\",\\\\\\"value\\\\\\":\\\\\\"alert.attributes.alertTypeId\\\\\\",\\\\\\"isQuoted\\\\\\":false},{\\\\\\"type\\\\\\":\\\\\\"literal\\\\\\",\\\\\\"value\\\\\\":\\\\\\"bar\\\\\\",\\\\\\"isQuoted\\\\\\":false}]}]},{\\\\\\"type\\\\\\":\\\\\\"function\\\\\\",\\\\\\"function\\\\\\":\\\\\\"or\\\\\\",\\\\\\"arguments\\\\\\":[{\\\\\\"type\\\\\\":\\\\\\"function\\\\\\",\\\\\\"function\\\\\\":\\\\\\"is\\\\\\",\\\\\\"arguments\\\\\\":[{\\\\\\"type\\\\\\":\\\\\\"literal\\\\\\",\\\\\\"value\\\\\\":\\\\\\"alert.attributes.name\\\\\\",\\\\\\"isQuoted\\\\\\":false},{\\\\\\"type\\\\\\":\\\\\\"wildcard\\\\\\",\\\\\\"value\\\\\\":\\\\\\"apples, foo, baz\\\\\\"}]},{\\\\\\"type\\\\\\":\\\\\\"function\\\\\\",\\\\\\"function\\\\\\":\\\\\\"is\\\\\\",\\\\\\"arguments\\\\\\":[{\\\\\\"type\\\\\\":\\\\\\"literal\\\\\\",\\\\\\"value\\\\\\":\\\\\\"alert.attributes.tags\\\\\\",\\\\\\"isQuoted\\\\\\":false},{\\\\\\"type\\\\\\":\\\\\\"wildcard\\\\\\",\\\\\\"value\\\\\\":\\\\\\"apples, foo, baz\\\\\\"}]}]}]}\\",\\"sort_field\\":\\"name\\",\\"sort_order\\":\\"asc\\"}", + }, + ] + `); + }); + + test('should call find API with searchText and tagsFilter and ruleTypeIds and consumers', async () => { + const resolvedValue = { + page: 1, + per_page: 10, + total: 0, + data: [], + }; + http.post.mockResolvedValueOnce(resolvedValue); + + const result = await loadRulesWithKueryFilter({ + http, + searchText: 'apples, foo, baz', + typesFilter: ['foo', 'bar'], + ruleTypeIds: ['one', 'two'], + consumers: ['my-consumer'], + page: { index: 0, size: 10 }, + }); + expect(result).toEqual({ + page: 1, + perPage: 10, + total: 0, + data: [], + }); + expect(http.post.mock.calls[0]).toMatchInlineSnapshot(` + Array [ + "/internal/alerting/rules/_find", + Object { + "body": "{\\"page\\":1,\\"per_page\\":10,\\"filter\\":\\"{\\\\\\"type\\\\\\":\\\\\\"function\\\\\\",\\\\\\"function\\\\\\":\\\\\\"and\\\\\\",\\\\\\"arguments\\\\\\":[{\\\\\\"type\\\\\\":\\\\\\"function\\\\\\",\\\\\\"function\\\\\\":\\\\\\"or\\\\\\",\\\\\\"arguments\\\\\\":[{\\\\\\"type\\\\\\":\\\\\\"function\\\\\\",\\\\\\"function\\\\\\":\\\\\\"is\\\\\\",\\\\\\"arguments\\\\\\":[{\\\\\\"type\\\\\\":\\\\\\"literal\\\\\\",\\\\\\"value\\\\\\":\\\\\\"alert.attributes.alertTypeId\\\\\\",\\\\\\"isQuoted\\\\\\":false},{\\\\\\"type\\\\\\":\\\\\\"literal\\\\\\",\\\\\\"value\\\\\\":\\\\\\"foo\\\\\\",\\\\\\"isQuoted\\\\\\":false}]},{\\\\\\"type\\\\\\":\\\\\\"function\\\\\\",\\\\\\"function\\\\\\":\\\\\\"is\\\\\\",\\\\\\"arguments\\\\\\":[{\\\\\\"type\\\\\\":\\\\\\"literal\\\\\\",\\\\\\"value\\\\\\":\\\\\\"alert.attributes.alertTypeId\\\\\\",\\\\\\"isQuoted\\\\\\":false},{\\\\\\"type\\\\\\":\\\\\\"literal\\\\\\",\\\\\\"value\\\\\\":\\\\\\"bar\\\\\\",\\\\\\"isQuoted\\\\\\":false}]}]},{\\\\\\"type\\\\\\":\\\\\\"function\\\\\\",\\\\\\"function\\\\\\":\\\\\\"or\\\\\\",\\\\\\"arguments\\\\\\":[{\\\\\\"type\\\\\\":\\\\\\"function\\\\\\",\\\\\\"function\\\\\\":\\\\\\"is\\\\\\",\\\\\\"arguments\\\\\\":[{\\\\\\"type\\\\\\":\\\\\\"literal\\\\\\",\\\\\\"value\\\\\\":\\\\\\"alert.attributes.name\\\\\\",\\\\\\"isQuoted\\\\\\":false},{\\\\\\"type\\\\\\":\\\\\\"wildcard\\\\\\",\\\\\\"value\\\\\\":\\\\\\"apples, foo, baz\\\\\\"}]},{\\\\\\"type\\\\\\":\\\\\\"function\\\\\\",\\\\\\"function\\\\\\":\\\\\\"is\\\\\\",\\\\\\"arguments\\\\\\":[{\\\\\\"type\\\\\\":\\\\\\"literal\\\\\\",\\\\\\"value\\\\\\":\\\\\\"alert.attributes.tags\\\\\\",\\\\\\"isQuoted\\\\\\":false},{\\\\\\"type\\\\\\":\\\\\\"wildcard\\\\\\",\\\\\\"value\\\\\\":\\\\\\"apples, foo, baz\\\\\\"}]}]}]}\\",\\"sort_field\\":\\"name\\",\\"sort_order\\":\\"asc\\",\\"rule_type_ids\\":[\\"one\\",\\"two\\"],\\"consumers\\":[\\"my-consumer\\"]}", + }, + ] + `); + }); + + test('should call find API with ruleStatusesFilter', async () => { + const resolvedValue = { + page: 1, + per_page: 10, + total: 0, + data: [], + }; + http.post.mockResolvedValue(resolvedValue); + + let result = await loadRulesWithKueryFilter({ + http, + ruleStatusesFilter: ['enabled', 'snoozed'], + page: { index: 0, size: 10 }, + }); + expect(result).toEqual({ + page: 1, + perPage: 10, + total: 0, + data: [], + }); + expect(http.post.mock.calls[0]).toMatchInlineSnapshot(` + Array [ + "/internal/alerting/rules/_find", + Object { + "body": "{\\"page\\":1,\\"per_page\\":10,\\"filter\\":\\"{\\\\\\"type\\\\\\":\\\\\\"function\\\\\\",\\\\\\"function\\\\\\":\\\\\\"or\\\\\\",\\\\\\"arguments\\\\\\":[{\\\\\\"type\\\\\\":\\\\\\"function\\\\\\",\\\\\\"function\\\\\\":\\\\\\"is\\\\\\",\\\\\\"arguments\\\\\\":[{\\\\\\"type\\\\\\":\\\\\\"literal\\\\\\",\\\\\\"value\\\\\\":\\\\\\"alert.attributes.enabled\\\\\\",\\\\\\"isQuoted\\\\\\":false},{\\\\\\"type\\\\\\":\\\\\\"literal\\\\\\",\\\\\\"value\\\\\\":true,\\\\\\"isQuoted\\\\\\":false}]},{\\\\\\"type\\\\\\":\\\\\\"function\\\\\\",\\\\\\"function\\\\\\":\\\\\\"or\\\\\\",\\\\\\"arguments\\\\\\":[{\\\\\\"type\\\\\\":\\\\\\"function\\\\\\",\\\\\\"function\\\\\\":\\\\\\"is\\\\\\",\\\\\\"arguments\\\\\\":[{\\\\\\"type\\\\\\":\\\\\\"literal\\\\\\",\\\\\\"value\\\\\\":\\\\\\"alert.attributes.muteAll\\\\\\",\\\\\\"isQuoted\\\\\\":false},{\\\\\\"type\\\\\\":\\\\\\"literal\\\\\\",\\\\\\"value\\\\\\":true,\\\\\\"isQuoted\\\\\\":false}]},{\\\\\\"type\\\\\\":\\\\\\"function\\\\\\",\\\\\\"function\\\\\\":\\\\\\"nested\\\\\\",\\\\\\"arguments\\\\\\":[{\\\\\\"type\\\\\\":\\\\\\"literal\\\\\\",\\\\\\"value\\\\\\":\\\\\\"alert.attributes.snoozeSchedule\\\\\\",\\\\\\"isQuoted\\\\\\":false},{\\\\\\"type\\\\\\":\\\\\\"function\\\\\\",\\\\\\"function\\\\\\":\\\\\\"range\\\\\\",\\\\\\"arguments\\\\\\":[{\\\\\\"type\\\\\\":\\\\\\"literal\\\\\\",\\\\\\"value\\\\\\":\\\\\\"duration\\\\\\",\\\\\\"isQuoted\\\\\\":false},\\\\\\"gt\\\\\\",{\\\\\\"type\\\\\\":\\\\\\"literal\\\\\\",\\\\\\"value\\\\\\":\\\\\\"0\\\\\\",\\\\\\"isQuoted\\\\\\":false}]}]}]}]}\\",\\"sort_field\\":\\"name\\",\\"sort_order\\":\\"asc\\"}", + }, + ] + `); + + result = await loadRulesWithKueryFilter({ + http, + ruleStatusesFilter: ['disabled'], + page: { index: 0, size: 10 }, + }); + expect(result).toEqual({ + page: 1, + perPage: 10, + total: 0, + data: [], + }); + expect(http.post.mock.calls[1]).toMatchInlineSnapshot(` + Array [ + "/internal/alerting/rules/_find", + Object { + "body": "{\\"page\\":1,\\"per_page\\":10,\\"filter\\":\\"{\\\\\\"type\\\\\\":\\\\\\"function\\\\\\",\\\\\\"function\\\\\\":\\\\\\"is\\\\\\",\\\\\\"arguments\\\\\\":[{\\\\\\"type\\\\\\":\\\\\\"literal\\\\\\",\\\\\\"value\\\\\\":\\\\\\"alert.attributes.enabled\\\\\\",\\\\\\"isQuoted\\\\\\":false},{\\\\\\"type\\\\\\":\\\\\\"literal\\\\\\",\\\\\\"value\\\\\\":false,\\\\\\"isQuoted\\\\\\":false}]}\\",\\"sort_field\\":\\"name\\",\\"sort_order\\":\\"asc\\"}", + }, + ] + `); + + result = await loadRulesWithKueryFilter({ + http, + ruleStatusesFilter: ['enabled', 'disabled', 'snoozed'], + page: { index: 0, size: 10 }, + }); + expect(result).toEqual({ + page: 1, + perPage: 10, + total: 0, + data: [], + }); + expect(http.post.mock.calls[2]).toMatchInlineSnapshot(` + Array [ + "/internal/alerting/rules/_find", + Object { + "body": "{\\"page\\":1,\\"per_page\\":10,\\"filter\\":\\"{\\\\\\"type\\\\\\":\\\\\\"function\\\\\\",\\\\\\"function\\\\\\":\\\\\\"or\\\\\\",\\\\\\"arguments\\\\\\":[{\\\\\\"type\\\\\\":\\\\\\"function\\\\\\",\\\\\\"function\\\\\\":\\\\\\"is\\\\\\",\\\\\\"arguments\\\\\\":[{\\\\\\"type\\\\\\":\\\\\\"literal\\\\\\",\\\\\\"value\\\\\\":\\\\\\"alert.attributes.enabled\\\\\\",\\\\\\"isQuoted\\\\\\":false},{\\\\\\"type\\\\\\":\\\\\\"literal\\\\\\",\\\\\\"value\\\\\\":true,\\\\\\"isQuoted\\\\\\":false}]},{\\\\\\"type\\\\\\":\\\\\\"function\\\\\\",\\\\\\"function\\\\\\":\\\\\\"is\\\\\\",\\\\\\"arguments\\\\\\":[{\\\\\\"type\\\\\\":\\\\\\"literal\\\\\\",\\\\\\"value\\\\\\":\\\\\\"alert.attributes.enabled\\\\\\",\\\\\\"isQuoted\\\\\\":false},{\\\\\\"type\\\\\\":\\\\\\"literal\\\\\\",\\\\\\"value\\\\\\":false,\\\\\\"isQuoted\\\\\\":false}]},{\\\\\\"type\\\\\\":\\\\\\"function\\\\\\",\\\\\\"function\\\\\\":\\\\\\"or\\\\\\",\\\\\\"arguments\\\\\\":[{\\\\\\"type\\\\\\":\\\\\\"function\\\\\\",\\\\\\"function\\\\\\":\\\\\\"is\\\\\\",\\\\\\"arguments\\\\\\":[{\\\\\\"type\\\\\\":\\\\\\"literal\\\\\\",\\\\\\"value\\\\\\":\\\\\\"alert.attributes.muteAll\\\\\\",\\\\\\"isQuoted\\\\\\":false},{\\\\\\"type\\\\\\":\\\\\\"literal\\\\\\",\\\\\\"value\\\\\\":true,\\\\\\"isQuoted\\\\\\":false}]},{\\\\\\"type\\\\\\":\\\\\\"function\\\\\\",\\\\\\"function\\\\\\":\\\\\\"nested\\\\\\",\\\\\\"arguments\\\\\\":[{\\\\\\"type\\\\\\":\\\\\\"literal\\\\\\",\\\\\\"value\\\\\\":\\\\\\"alert.attributes.snoozeSchedule\\\\\\",\\\\\\"isQuoted\\\\\\":false},{\\\\\\"type\\\\\\":\\\\\\"function\\\\\\",\\\\\\"function\\\\\\":\\\\\\"range\\\\\\",\\\\\\"arguments\\\\\\":[{\\\\\\"type\\\\\\":\\\\\\"literal\\\\\\",\\\\\\"value\\\\\\":\\\\\\"duration\\\\\\",\\\\\\"isQuoted\\\\\\":false},\\\\\\"gt\\\\\\",{\\\\\\"type\\\\\\":\\\\\\"literal\\\\\\",\\\\\\"value\\\\\\":\\\\\\"0\\\\\\",\\\\\\"isQuoted\\\\\\":false}]}]}]}]}\\",\\"sort_field\\":\\"name\\",\\"sort_order\\":\\"asc\\"}", + }, + ] + `); + }); + + test('should call find API with tagsFilter', async () => { + const resolvedValue = { + page: 1, + per_page: 10, + total: 0, + data: [], + }; + http.post.mockResolvedValueOnce(resolvedValue); + const result = await loadRulesWithKueryFilter({ + http, + tagsFilter: ['a', 'b', 'c'], + page: { index: 0, size: 10 }, + }); + expect(result).toEqual({ + page: 1, + perPage: 10, + total: 0, + data: [], + }); + expect(http.post.mock.calls[0]).toMatchInlineSnapshot(` + Array [ + "/internal/alerting/rules/_find", + Object { + "body": "{\\"page\\":1,\\"per_page\\":10,\\"filter\\":\\"{\\\\\\"type\\\\\\":\\\\\\"function\\\\\\",\\\\\\"function\\\\\\":\\\\\\"or\\\\\\",\\\\\\"arguments\\\\\\":[{\\\\\\"type\\\\\\":\\\\\\"function\\\\\\",\\\\\\"function\\\\\\":\\\\\\"is\\\\\\",\\\\\\"arguments\\\\\\":[{\\\\\\"type\\\\\\":\\\\\\"literal\\\\\\",\\\\\\"value\\\\\\":\\\\\\"alert.attributes.tags\\\\\\",\\\\\\"isQuoted\\\\\\":false},{\\\\\\"type\\\\\\":\\\\\\"literal\\\\\\",\\\\\\"value\\\\\\":\\\\\\"a\\\\\\",\\\\\\"isQuoted\\\\\\":false}]},{\\\\\\"type\\\\\\":\\\\\\"function\\\\\\",\\\\\\"function\\\\\\":\\\\\\"is\\\\\\",\\\\\\"arguments\\\\\\":[{\\\\\\"type\\\\\\":\\\\\\"literal\\\\\\",\\\\\\"value\\\\\\":\\\\\\"alert.attributes.tags\\\\\\",\\\\\\"isQuoted\\\\\\":false},{\\\\\\"type\\\\\\":\\\\\\"literal\\\\\\",\\\\\\"value\\\\\\":\\\\\\"b\\\\\\",\\\\\\"isQuoted\\\\\\":false}]},{\\\\\\"type\\\\\\":\\\\\\"function\\\\\\",\\\\\\"function\\\\\\":\\\\\\"is\\\\\\",\\\\\\"arguments\\\\\\":[{\\\\\\"type\\\\\\":\\\\\\"literal\\\\\\",\\\\\\"value\\\\\\":\\\\\\"alert.attributes.tags\\\\\\",\\\\\\"isQuoted\\\\\\":false},{\\\\\\"type\\\\\\":\\\\\\"literal\\\\\\",\\\\\\"value\\\\\\":\\\\\\"c\\\\\\",\\\\\\"isQuoted\\\\\\":false}]}]}\\",\\"sort_field\\":\\"name\\",\\"sort_order\\":\\"asc\\"}", + }, + ] + `); + }); + + test('should call find API with ruleTypeIds', async () => { + const resolvedValue = { + page: 1, + per_page: 10, + total: 0, + data: [], + }; + http.post.mockResolvedValueOnce(resolvedValue); + + const result = await loadRulesWithKueryFilter({ + http, + ruleTypeIds: ['foo', 'bar'], + page: { index: 0, size: 10 }, + }); + expect(result).toEqual({ + page: 1, + perPage: 10, + total: 0, + data: [], + }); + expect(http.post.mock.calls[0]).toMatchInlineSnapshot(` + Array [ + "/internal/alerting/rules/_find", + Object { + "body": "{\\"page\\":1,\\"per_page\\":10,\\"sort_field\\":\\"name\\",\\"sort_order\\":\\"asc\\",\\"rule_type_ids\\":[\\"foo\\",\\"bar\\"]}", + }, + ] + `); + }); + + test('should call find API with consumers', async () => { + const resolvedValue = { + page: 1, + per_page: 10, + total: 0, + data: [], + }; + http.post.mockResolvedValueOnce(resolvedValue); + + const result = await loadRulesWithKueryFilter({ + http, + consumers: ['foo', 'bar'], + page: { index: 0, size: 10 }, + }); + expect(result).toEqual({ + page: 1, + perPage: 10, + total: 0, + data: [], + }); + expect(http.post.mock.calls[0]).toMatchInlineSnapshot(` + Array [ + "/internal/alerting/rules/_find", + Object { + "body": "{\\"page\\":1,\\"per_page\\":10,\\"sort_field\\":\\"name\\",\\"sort_order\\":\\"asc\\",\\"consumers\\":[\\"foo\\",\\"bar\\"]}", + }, + ] + `); + }); +}); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/rules_kuery_filter.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/rules_kuery_filter.ts index 7c731dbfb016c..c765f8f478041 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/rules_kuery_filter.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/rules_kuery_filter.ts @@ -24,8 +24,9 @@ export async function loadRulesWithKueryFilter({ tagsFilter, sort = { field: 'name', direction: 'asc' }, kueryNode, - filterConsumers, + ruleTypeIds, hasReference, + consumers, }: LoadRulesProps): Promise<{ page: number; perPage: number; @@ -58,8 +59,9 @@ export async function loadRulesWithKueryFilter({ ...(filtersKueryNode ? { filter: JSON.stringify(filtersKueryNode) } : {}), sort_field: sort.field, sort_order: sort.direction, - filter_consumers: filterConsumers, ...(hasReference ? { has_reference: hasReference } : {}), + ...(ruleTypeIds ? { rule_type_ids: ruleTypeIds } : {}), + ...(consumers ? { consumers } : {}), }), }); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/search_filters.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/search_filters.ts index 3ae6a01633e40..532f49a159c89 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/search_filters.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/search_filters.ts @@ -11,72 +11,78 @@ import { AlertConsumers, DefaultAlertFieldName, } from '@kbn/rule-data-utils'; -import { FILTERS, FilterStateStore, PhraseFilter, PhrasesFilter } from '@kbn/es-query'; +import { FILTERS, FilterStateStore, PhrasesFilter } from '@kbn/es-query'; const $state = { store: FilterStateStore.APP_STATE, }; export type AlertsFeatureIdsFilter = PhrasesFilter & { - meta: Pick & { alertsFeatureIds: AlertConsumers[] }; + meta: PhrasesFilter['meta'] & { ruleTypeIds: string[]; consumers: string[] }; }; /** * Creates a match_phrase filter without an index pattern */ -export const createMatchPhraseFilter = (field: DefaultAlertFieldName, value: unknown) => - ({ - meta: { - field, - type: FILTERS.PHRASE, - key: field, - alias: null, - disabled: false, - index: undefined, - negate: false, - params: { query: value }, - value: undefined, - }, - $state, - query: { - match_phrase: { - [field]: value, - }, +export const createMatchPhraseFilter = ( + field: DefaultAlertFieldName, + value: string +): AlertsFeatureIdsFilter => ({ + meta: { + field, + type: FILTERS.PHRASE, + key: field, + alias: null, + disabled: false, + index: undefined, + negate: false, + // @ts-expect-error + params: { query: value }, + value: undefined, + ruleTypeIds: [], + consumers: [], + }, + $state, + query: { + match_phrase: { + [field]: value, }, - } as PhraseFilter); + }, +}); /** * Creates a match_phrases filter without an index pattern */ export const createMatchPhrasesFilter = ( field: DefaultAlertFieldName, - values: unknown[], + values: string[], alias: string | null = null -) => - ({ - meta: { - field, - type: FILTERS.PHRASES, - key: field, - alias, - disabled: false, - index: undefined, - negate: false, - params: values, - value: undefined, - }, - $state, - query: { - bool: { - minimum_should_match: 1, - should: values.map((v) => ({ - match_phrase: { - [field]: v, - }, - })), - }, +): AlertsFeatureIdsFilter => ({ + meta: { + field, + type: FILTERS.PHRASES, + key: field, + alias, + disabled: false, + index: undefined, + negate: false, + params: values, + value: undefined, + ruleTypeIds: [], + consumers: [], + }, + $state, + query: { + bool: { + minimum_should_match: 1, + should: values.map((v) => ({ + match_phrase: { + [field]: v, + }, + })), }, - } as PhrasesFilter); + }, +}); /** * Creates a match_phrase filter targeted to filtering alerts by producer @@ -88,15 +94,12 @@ export const createRuleProducerFilter = (producer: AlertConsumers) => * Creates a match_phrase filter targeted to filtering alerts by rule type ids */ export const createRuleTypesFilter = ( - featureIds: AlertConsumers[], - alias: string, - ruleTypeIds: string[] + ruleTypeIds: string[], + consumers: string[], + alias: string ) => { - const filter = createMatchPhrasesFilter( - ALERT_RULE_TYPE_ID, - ruleTypeIds, - alias - ) as AlertsFeatureIdsFilter; - filter.meta.alertsFeatureIds = featureIds; + const filter = createMatchPhrasesFilter(ALERT_RULE_TYPE_ID, ruleTypeIds, alias); + filter.meta.ruleTypeIds = ruleTypeIds; + filter.meta.consumers = consumers; return filter; }; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.test.tsx index 74b528ba7a64a..2c5f159d0a76f 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.test.tsx @@ -399,6 +399,7 @@ describe('action_form', () => { } actionTypeRegistry={actionTypeRegistry} setHasActionsWithBrokenConnector={setHasActionsWithBrokenConnector} + ruleTypeId=".es-query" /> ); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_form.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_form.test.tsx index 116b416ac98f1..945ab23c43611 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_form.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_form.test.tsx @@ -136,6 +136,7 @@ describe('action_type_form', () => { const wrapper = mountWithIntl( getActionTypeForm({ index: 1, + ruleTypeId: '.es-query', actionItem: { id: '123', actionTypeId: '.pagerduty', @@ -190,6 +191,7 @@ describe('action_type_form', () => { {getActionTypeForm({ index: 1, + ruleTypeId: '.es-query', actionItem: { id: '123', actionTypeId: '.pagerduty', @@ -239,6 +241,7 @@ describe('action_type_form', () => { {getActionTypeForm({ index: 1, + ruleTypeId: 'siem.esqlRule', actionItem: { id: '123', actionTypeId: '.pagerduty', @@ -288,6 +291,7 @@ describe('action_type_form', () => { const wrapper = mountWithIntl( getActionTypeForm({ index: 1, + ruleTypeId: '.es-query', actionItem: { id: '123', actionTypeId: '.pagerduty', @@ -340,6 +344,7 @@ describe('action_type_form', () => { const wrapper = mountWithIntl( getActionTypeForm({ index: 1, + ruleTypeId: '.es-query', actionItem: { id: '123', actionTypeId: '.pagerduty', @@ -413,6 +418,7 @@ describe('action_type_form', () => { {getActionTypeForm({ index: 1, actionItem, + ruleTypeId: '.es-query', setActionFrequencyProperty: () => { actionItem.frequency = { notifyWhen: RuleNotifyWhen.ACTIVE, @@ -551,6 +557,7 @@ describe('action_type_form', () => { {getActionTypeForm({ index: 1, + ruleTypeId: '.es-query', actionItem, notifyWhenSelectOptions: CUSTOM_NOTIFY_WHEN_OPTIONS, })} @@ -604,6 +611,7 @@ describe('action_type_form', () => { {getActionTypeForm({ index: 1, + ruleTypeId: '.es-query', actionItem, notifyWhenSelectOptions: CUSTOM_NOTIFY_WHEN_OPTIONS, })} @@ -664,7 +672,7 @@ function getActionTypeForm({ messageVariables?: ActionVariables; summaryMessageVariables?: ActionVariables; notifyWhenSelectOptions?: NotifyWhenSelectOptions[]; - ruleTypeId?: string; + ruleTypeId: string; producerId?: string; featureId?: string; }) { 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 9af97b713dff3..8e95473ceca4c 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 { AlertConsumers } from '@kbn/rule-data-utils'; import { EuiFlexGroup, EuiFlexItem, @@ -507,7 +507,6 @@ export const ActionTypeForm = ({ setActionAlertsFilterProperty('query', query, index)} - featureIds={[producerId as ValidFeatureId]} appName={featureId!} ruleTypeId={ruleTypeId} plugins={{ diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_rules_list.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_rules_list.tsx index c2e89eb31fe84..719cd0fef2377 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_rules_list.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_rules_list.tsx @@ -73,7 +73,6 @@ export const ConnectorRulesList = (props: ConnectorRulesListProps) => { const ruleFilters = useMemo(() => { const baseFilters = { searchText: searchFilter, - types: ruleTypeIds, }; if (connector.isPreconfigured) { @@ -105,10 +104,11 @@ export const ConnectorRulesList = (props: ConnectorRulesListProps) => { id: connector.id, }, }; - }, [connector, searchFilter, ruleTypeIds]); + }, [connector, searchFilter]); const { rulesState } = useLoadRulesQuery({ ...ruleFilters, + ruleTypeIds, hasDefaultRuleTypesFiltersOn: ruleTypeIds.length === 0, page, sort, diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_summary_widget/alert_summary_widget.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_summary_widget/alert_summary_widget.test.tsx index 743c475a287b3..84c2e4c5468a9 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_summary_widget/alert_summary_widget.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_summary_widget/alert_summary_widget.test.tsx @@ -52,7 +52,7 @@ describe('AlertSummaryWidget', () => { {}, @@ -34,7 +35,8 @@ export const AlertSummaryWidget = ({ isLoading, error, } = useLoadAlertSummary({ - featureIds, + ruleTypeIds, + consumers, filter, timeRange, }); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_summary_widget/types.ts b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_summary_widget/types.ts index 2393ff9c16a64..88b40289cb6e0 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_summary_widget/types.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_summary_widget/types.ts @@ -8,7 +8,7 @@ import type { BrushEndListener, PartialTheme, SettingsProps, Theme } from '@elastic/charts'; import { estypes } from '@elastic/elasticsearch'; import { IUiSettingsClient } from '@kbn/core-ui-settings-browser'; -import { AlertStatus, ValidFeatureId } from '@kbn/rule-data-utils'; +import { AlertStatus } from '@kbn/rule-data-utils'; import { ChartsPluginStart } from '@kbn/charts-plugin/public'; export interface Alert { @@ -48,7 +48,8 @@ export interface DependencyProps { } export interface AlertSummaryWidgetProps { - featureIds?: ValidFeatureId[]; + ruleTypeIds?: string[]; + consumers?: string[]; filter?: estypes.QueryDslQueryContainer; fullSize?: boolean; onClick?: (status?: AlertStatus) => void; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_page/components/stack_alerts_page.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_page/components/stack_alerts_page.tsx index 26f4c3fd43bf0..f5a39ab5ac0d3 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_page/components/stack_alerts_page.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_page/components/stack_alerts_page.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { lazy, Suspense, useEffect, useMemo, useState } from 'react'; +import React, { lazy, Suspense, useCallback, useEffect, useMemo, useState } from 'react'; import { i18n } from '@kbn/i18n'; import { EuiBetaBadge, @@ -21,9 +21,10 @@ import { ALERT_STATUS_RECOVERED, ALERT_STATUS_UNTRACKED, AlertConsumers, + isSiemRuleType, } from '@kbn/rule-data-utils'; import { QueryClientProvider } from '@tanstack/react-query'; -import { BoolQuery } from '@kbn/es-query'; +import { BoolQuery, Filter } from '@kbn/es-query'; import { FormattedMessage } from '@kbn/i18n-react'; import { ALERTS_PAGE_ID } from '../../../../common/constants'; import { QuickFiltersMenuItem } from '../../alerts_search_bar/quick_filters'; @@ -31,7 +32,6 @@ import { NoPermissionPrompt } from '../../../components/prompts/no_permission_pr import { ALERT_TABLE_GLOBAL_CONFIG_ID } from '../../../constants'; import { useRuleStats } from '../hooks/use_rule_stats'; import { getAlertingSectionBreadcrumb } from '../../../lib/breadcrumb'; -import { NON_SIEM_FEATURE_IDS } from '../../alerts_search_bar/constants'; import { alertProducersData } from '../../alerts_table/constants'; import { UrlSyncedAlertsSearchBar } from '../../alerts_search_bar/url_synced_alerts_search_bar'; import { useKibana } from '../../../../common/lib/kibana'; @@ -41,11 +41,21 @@ import { Provider, } from '../../alerts_search_bar/use_alert_search_bar_state_container'; import { getCurrentDocTitle } from '../../../lib/doc_title'; -import { createMatchPhraseFilter, createRuleTypesFilter } from '../../../lib/search_filters'; +import { + AlertsFeatureIdsFilter, + createMatchPhraseFilter, + createRuleTypesFilter, +} from '../../../lib/search_filters'; import { useLoadRuleTypesQuery } from '../../../hooks/use_load_rule_types_query'; import { nonNullable } from '../../../../../common/utils'; -import { useRuleTypeIdsByFeatureId } from '../hooks/use_rule_type_ids_by_feature_id'; +import { + RuleTypeIdsByFeatureId, + useRuleTypeIdsByFeatureId, +} from '../hooks/use_rule_type_ids_by_feature_id'; import { TECH_PREVIEW_DESCRIPTION, TECH_PREVIEW_LABEL } from '../../translations'; +import { AlertsTableSupportedConsumers } from '../../alerts_table/types'; +import { NON_SIEM_CONSUMERS } from '../../alerts_search_bar/constants'; + const AlertsTable = lazy(() => import('../../alerts_table/alerts_table_state')); /** @@ -55,7 +65,7 @@ export const StackAlertsPage = () => { return ( - + ); @@ -69,61 +79,121 @@ const getFeatureFilterLabel = (featureName: string) => }, }); -const PageContent = () => { +const PageContentWrapperComponent: React.FC = () => { const { chrome: { docTitle }, setBreadcrumbs, - alertsTableConfigurationRegistry, } = useKibana().services; - const [esQuery, setEsQuery] = useState({ bool: {} } as { bool: BoolQuery }); - const [activeFeatureFilters, setActiveFeatureFilters] = useState([]); - const ruleStats = useRuleStats(); const { ruleTypesState: { data: ruleTypesIndex, initialLoad: isInitialLoadingRuleTypes }, authorizedToReadAnyRules, } = useLoadRuleTypesQuery({ filteredRuleTypes: [] }); + const ruleTypeIdsByFeatureId = useRuleTypeIdsByFeatureId(ruleTypesIndex); - const browsingSiem = useMemo( - () => activeFeatureFilters.length === 1 && activeFeatureFilters[0] === AlertConsumers.SIEM, - [activeFeatureFilters] - ); - const filteringBySolution = useMemo( - () => activeFeatureFilters.length > 0, - [activeFeatureFilters.length] + useEffect(() => { + setBreadcrumbs([getAlertingSectionBreadcrumb('alerts')]); + docTitle.change(getCurrentDocTitle('alerts')); + }, [docTitle, setBreadcrumbs]); + + return !isInitialLoadingRuleTypes ? ( + + ) : null; +}; + +const PageContentWrapper = React.memo(PageContentWrapperComponent); + +interface PageContentProps { + isLoading: boolean; + authorizedToReadAnyRules: boolean; + ruleTypeIdsByFeatureId: RuleTypeIdsByFeatureId; +} + +const PageContentComponent: React.FC = ({ + isLoading, + authorizedToReadAnyRules, + ruleTypeIdsByFeatureId, +}) => { + const { alertsTableConfigurationRegistry } = useKibana().services; + const ruleTypeIdsByFeatureIdEntries = Object.entries(ruleTypeIdsByFeatureId); + + const [esQuery, setEsQuery] = useState({ bool: {} } as { bool: BoolQuery }); + const [ruleTypeIds, setRuleTypeIds] = useState(() => + getInitialRuleTypeIds(ruleTypeIdsByFeatureId) ); - const featureIds = useMemo( - () => - filteringBySolution - ? browsingSiem - ? [AlertConsumers.SIEM] - : activeFeatureFilters - : NON_SIEM_FEATURE_IDS, - [activeFeatureFilters, browsingSiem, filteringBySolution] + + const [consumers, setConsumers] = useState(NON_SIEM_CONSUMERS); + + const [selectedFilters, setSelectedFilters] = useState([]); + const ruleStats = useRuleStats({ ruleTypeIds }); + const isFilteringSecurityRules = ruleTypeIds.every(isSiemRuleType); + + const onFilterSelected = useCallback( + (filters: Filter[]) => { + const newRuleTypeIds = [ + ...new Set( + filters + .flatMap((ruleTypeId) => (ruleTypeId as AlertsFeatureIdsFilter).meta.ruleTypeIds) + .filter(nonNullable) + ), + ]; + + const newConsumers = [ + ...new Set( + filters + .flatMap((ruleTypeId) => (ruleTypeId as AlertsFeatureIdsFilter).meta.consumers) + .filter(nonNullable) + ), + ]; + + setSelectedFilters(filters as AlertsFeatureIdsFilter[]); + + if (newRuleTypeIds.length > 0) { + setRuleTypeIds(newRuleTypeIds); + setConsumers(newConsumers); + return; + } + + setRuleTypeIds(getInitialRuleTypeIds(ruleTypeIdsByFeatureId)); + setConsumers(NON_SIEM_CONSUMERS); + }, + [ruleTypeIdsByFeatureId] ); + const quickFilters = useMemo(() => { const filters: QuickFiltersMenuItem[] = []; - if (Object.values(ruleTypeIdsByFeatureId).length > 0) { + if (ruleTypeIdsByFeatureIdEntries.length > 0) { filters.push( - ...Object.entries(ruleTypeIdsByFeatureId) - .map(([featureId, ruleTypeIds]) => { - const producerData = alertProducersData[featureId as AlertConsumers]; + ...ruleTypeIdsByFeatureIdEntries + .map(([consumer, _ruleTypeIds]) => { + const producerData = alertProducersData[consumer as AlertsTableSupportedConsumers]; if (!producerData) { return null; } + const filterLabel = getFeatureFilterLabel(producerData.displayName); - const disabled = - filteringBySolution && featureId === AlertConsumers.SIEM - ? !browsingSiem - : browsingSiem; + const shouldDisable = + (isFilteringSecurityRules && consumer !== AlertConsumers.SIEM) || + (!isFilteringSecurityRules && consumer === AlertConsumers.SIEM); + + const isQuickFilterSelected = _ruleTypeIds.every((ruleTypeId) => + ruleTypeIds.includes(ruleTypeId) + ); + + const disabled = selectedFilters.length > 0 && (shouldDisable || isQuickFilterSelected); + return { name: filterLabel, icon: producerData.icon, filter: createRuleTypesFilter( - producerData.subFeatureIds ?? [featureId as AlertConsumers], - filterLabel, - ruleTypeIds + _ruleTypeIds, + producerData.subFeatureIds ?? [consumer], + filterLabel ), disabled, }; @@ -131,6 +201,7 @@ const PageContent = () => { .filter(nonNullable) ); } + filters.push({ title: i18n.translate('xpack.triggersActionsUI.sections.globalAlerts.quickFilters.status', { defaultMessage: 'Status', @@ -142,17 +213,12 @@ const PageContent = () => { })), }); return filters; - }, [browsingSiem, filteringBySolution, ruleTypeIdsByFeatureId]); - const tableConfigurationId = useMemo( - // TODO in preparation for using solution-specific configurations - () => ALERT_TABLE_GLOBAL_CONFIG_ID, - [] - ); - - useEffect(() => { - setBreadcrumbs([getAlertingSectionBreadcrumb('alerts')]); - docTitle.change(getCurrentDocTitle('alerts')); - }, [docTitle, setBreadcrumbs]); + }, [ + isFilteringSecurityRules, + ruleTypeIds, + ruleTypeIdsByFeatureIdEntries, + selectedFilters.length, + ]); return ( <> @@ -177,28 +243,29 @@ const PageContent = () => { rightSideItems={ruleStats} /> - {!isInitialLoadingRuleTypes && !authorizedToReadAnyRules ? ( + {!isLoading && !authorizedToReadAnyRules ? ( ) : ( }> { ); }; + +const PageContent = React.memo(PageContentComponent); + +const getInitialRuleTypeIds = (ruleTypeIdsByFeatureId: RuleTypeIdsByFeatureId): string[] => + Object.entries(ruleTypeIdsByFeatureId) + .filter(([featureId]) => featureId !== AlertConsumers.SIEM) + .map(([_, _ruleTypeIds]) => _ruleTypeIds) + .flat(); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_page/hooks/use_rule_stats.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_page/hooks/use_rule_stats.tsx index 06e371979d980..4d3841672defb 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_page/hooks/use_rule_stats.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_page/hooks/use_rule_stats.tsx @@ -23,7 +23,12 @@ const Divider = styled.div` height: 100%; `; -export const useRuleStats = () => { +interface Props { + ruleTypeIds?: string[]; + consumers?: string[]; +} + +export const useRuleStats = ({ ruleTypeIds, consumers }: Props = {}) => { const { http, notifications: { toasts }, @@ -46,7 +51,10 @@ export const useRuleStats = () => { try { const response = await loadRuleAggregations({ http, + ruleTypeIds, + consumers, }); + const { ruleExecutionStatus, ruleMutedStatus, ruleEnabledStatus, ruleSnoozedStatus } = response; if (ruleExecutionStatus && ruleMutedStatus && ruleEnabledStatus && ruleSnoozedStatus) { @@ -73,7 +81,7 @@ export const useRuleStats = () => { } finally { setLoading(false); } - }, [http, toasts]); + }, [consumers, http, ruleTypeIds, toasts]); useEffect(() => { loadRuleStats(); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_page/hooks/use_rule_type_ids_by_feature_id.ts b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_page/hooks/use_rule_type_ids_by_feature_id.ts index c8c5eedc3054f..1380f9655d479 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_page/hooks/use_rule_type_ids_by_feature_id.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_page/hooks/use_rule_type_ids_by_feature_id.ts @@ -12,7 +12,7 @@ import { observabilityFeatureIds, stackFeatureIds } from '../../alerts_table/con import { MULTI_CONSUMER_RULE_TYPE_IDS } from '../../../constants'; import { RuleTypeIndex } from '../../../../types'; -type RuleTypeIdsByFeatureId = Partial< +export type RuleTypeIdsByFeatureId = Partial< Record< | typeof AlertConsumers.SIEM | typeof AlertConsumers.OBSERVABILITY @@ -22,17 +22,20 @@ type RuleTypeIdsByFeatureId = Partial< > >; +const EMPTY_OBJECT = {}; + /** * Groups all rule type ids under their respective feature id */ export const useRuleTypeIdsByFeatureId = (ruleTypesIndex: RuleTypeIndex) => useMemo((): RuleTypeIdsByFeatureId => { if (!ruleTypesIndex?.size) { - return {}; + return EMPTY_OBJECT; } + const map = Array.from(ruleTypesIndex.entries()).reduce>>( - (types, [key, value]) => { - let producer = value.producer as keyof RuleTypeIdsByFeatureId; + (types, [ruleTypeId, ruleType]) => { + let producer = ruleType.producer as keyof RuleTypeIdsByFeatureId; // Some o11y apps are listed under 'observability' to create a grouped filter if (observabilityFeatureIds.includes(producer)) { producer = AlertConsumers.OBSERVABILITY; @@ -41,14 +44,15 @@ export const useRuleTypeIdsByFeatureId = (ruleTypesIndex: RuleTypeIndex) => if (stackFeatureIds.includes(producer)) { producer = AlertConsumers.STACK_ALERTS; } + // Multi consumer rule type ids should be listed both in Observability and Stack alerts - if (MULTI_CONSUMER_RULE_TYPE_IDS.includes(value.id)) { + if (MULTI_CONSUMER_RULE_TYPE_IDS.includes(ruleType.id)) { (types[AlertConsumers.OBSERVABILITY] = - types[AlertConsumers.OBSERVABILITY] || new Set()).add(key); + types[AlertConsumers.OBSERVABILITY] || new Set()).add(ruleTypeId); (types[AlertConsumers.STACK_ALERTS] = - types[AlertConsumers.STACK_ALERTS] || new Set()).add(key); + types[AlertConsumers.STACK_ALERTS] || new Set()).add(ruleTypeId); } else { - (types[producer] = types[producer] || new Set()).add(key); + (types[producer] = types[producer] || new Set()).add(ruleTypeId); } return types; }, diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_search_bar/alerts_search_bar.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_search_bar/alerts_search_bar.test.tsx index 61fceacead341..3f285de6ead75 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_search_bar/alerts_search_bar.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_search_bar/alerts_search_bar.test.tsx @@ -12,14 +12,10 @@ import { Filter, FilterStateStore } from '@kbn/es-query'; import { dataPluginMock } from '@kbn/data-plugin/public/mocks'; import { NotificationsStart } from '@kbn/core-notifications-browser'; import { useKibana } from '@kbn/kibana-react-plugin/public'; -import { useLoadRuleTypesQuery } from '../../hooks/use_load_rule_types_query'; -import { useRuleAADFields } from '../../hooks/use_rule_aad_fields'; import { AlertsSearchBar } from './alerts_search_bar'; const mockDataPlugin = dataPluginMock.createStartContract(); jest.mock('@kbn/kibana-utils-plugin/public'); -jest.mock('../../hooks/use_load_rule_types_query'); -jest.mock('../../hooks/use_rule_aad_fields'); jest.mock('@kbn/alerts-ui-shared/src/common/hooks/use_alerts_data_view'); jest.mock('@kbn/kibana-react-plugin/public', () => ({ ...jest.requireActual('@kbn/kibana-react-plugin/public'), @@ -41,43 +37,28 @@ jest.mocked(useAlertsDataView).mockReturnValue({ }, }); -jest.mocked(useLoadRuleTypesQuery).mockReturnValue({ - ruleTypesState: { - initialLoad: false, - data: new Map(), - isLoading: false, - error: undefined, - }, - authorizedToReadAnyRules: false, - hasAnyAuthorizedRuleType: false, - authorizedRuleTypes: [], - authorizedToCreateAnyRules: false, - isSuccess: false, -}); - -jest.mocked(useRuleAADFields).mockReturnValue({ - aadFields: [], - loading: false, -}); - const mockUseKibana = useKibana as jest.Mock; +const unifiedSearchBarMock = jest.fn().mockImplementation((props) => ( + +)); + describe('AlertsSearchBar', () => { beforeEach(() => { + jest.clearAllMocks(); + mockUseKibana.mockReturnValue({ services: { data: mockDataPlugin, unifiedSearch: { ui: { - SearchBar: jest.fn().mockImplementation((props) => ( - - )), + SearchBar: unifiedSearchBarMock, }, }, notifications: { toasts: { addWarning: jest.fn() } } as unknown as NotificationsStart, @@ -85,10 +66,6 @@ describe('AlertsSearchBar', () => { }); }); - beforeEach(() => { - jest.clearAllMocks(); - }); - it('renders correctly', async () => { render( { onSavedQueryUpdated={jest.fn()} onClearSavedQuery={jest.fn()} appName={'test'} - featureIds={['observability', 'stackAlerts']} /> ); expect(await screen.findByTestId('querySubmitButton')).toBeInTheDocument(); @@ -119,7 +95,6 @@ describe('AlertsSearchBar', () => { onSavedQueryUpdated={jest.fn()} onClearSavedQuery={jest.fn()} appName={'test'} - featureIds={['observability', 'stackAlerts']} /> ); @@ -176,7 +151,6 @@ describe('AlertsSearchBar', () => { onSavedQueryUpdated={jest.fn()} onClearSavedQuery={jest.fn()} appName={'test'} - featureIds={['observability', 'stackAlerts']} /> ); @@ -187,4 +161,136 @@ describe('AlertsSearchBar', () => { expect(mockDataPlugin.query.filterManager.setFilters).toHaveBeenCalledWith(filters); }); }); + + it('calls the unifiedSearchBar correctly for security rule types', async () => { + render( + + ); + + await waitFor(() => { + expect(unifiedSearchBarMock).toHaveBeenCalledWith( + expect.objectContaining({ + suggestionsAbstraction: undefined, + }), + {} + ); + }); + }); + + it('calls the unifiedSearchBar correctly for NON security rule types', async () => { + render( + + ); + + await waitFor(() => { + expect(unifiedSearchBarMock).toHaveBeenCalledWith( + expect.objectContaining({ + suggestionsAbstraction: { type: 'alerts', fields: {} }, + }), + {} + ); + }); + }); + + it('calls the unifiedSearchBar with correct index patters', async () => { + render( + + ); + + await waitFor(() => { + expect(unifiedSearchBarMock).toHaveBeenCalledWith( + expect.objectContaining({ + indexPatterns: [ + { + fields: [ + { aggregatable: true, name: 'event.action', searchable: true, type: 'string' }, + ], + title: '.esQuery,apm.anomaly', + }, + ], + }), + {} + ); + }); + }); + + it('calls the unifiedSearchBar with correct index patters without rule types', async () => { + render( + + ); + + await waitFor(() => { + expect(unifiedSearchBarMock).toHaveBeenCalledWith( + expect.objectContaining({ + indexPatterns: [ + { + fields: [ + { aggregatable: true, name: 'event.action', searchable: true, type: 'string' }, + ], + title: '.alerts-*', + }, + ], + }), + {} + ); + }); + }); + + it('calls the unifiedSearchBar with correct index patters without data views', async () => { + jest.mocked(useAlertsDataView).mockReturnValue({ + isLoading: false, + dataView: undefined, + }); + + render( + + ); + + await waitFor(() => { + expect(unifiedSearchBarMock).toHaveBeenCalledWith( + expect.objectContaining({ + indexPatterns: [], + }), + {} + ); + }); + }); }); 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 5e2880e65231c..0a5c18fab9d8c 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,7 +9,7 @@ import React, { useCallback, useMemo, useState } from 'react'; import { useKibana } from '@kbn/kibana-react-plugin/public'; import { compareFilters, Query, TimeRange } from '@kbn/es-query'; import { SuggestionsAbstraction } from '@kbn/unified-search-plugin/public/typeahead/suggestions_component'; -import { AlertConsumers, ValidFeatureId } from '@kbn/rule-data-utils'; +import { isSiemRuleType } from '@kbn/rule-data-utils'; import { EuiContextMenuPanelDescriptor, EuiContextMenuPanelItemDescriptor } from '@elastic/eui'; import { useAlertsDataView } from '@kbn/alerts-ui-shared/src/common/hooks/use_alerts_data_view'; import { isQuickFiltersGroup, QuickFiltersMenuItem } from './quick_filters'; @@ -17,19 +17,15 @@ import { NO_INDEX_PATTERNS } from './constants'; import { SEARCH_BAR_PLACEHOLDER } from './translations'; import { AlertsSearchBarProps, QueryLanguageType } from './types'; 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; -const EMPTY_FEATURE_IDS: ValidFeatureId[] = []; // TODO Share buildEsQuery to be used between AlertsSearchBar and AlertsStateTable component https://github.com/elastic/kibana/issues/144615 // Also TODO: Replace all references to this component with the one from alerts-ui-shared export function AlertsSearchBar({ appName, disableQueryLanguageSwitcher = false, - featureIds = EMPTY_FEATURE_IDS, - ruleTypeId, + ruleTypeIds, query, filters, quickFilters = [], @@ -58,33 +54,25 @@ export function AlertsSearchBar({ const [queryLanguage, setQueryLanguage] = useState('kuery'); const { dataView } = useAlertsDataView({ - featureIds, + ruleTypeIds: ruleTypeIds ?? [], http, dataViewsService, toasts, }); - const { aadFields, loading: fieldsLoading } = useRuleAADFields(ruleTypeId); const indexPatterns = useMemo(() => { - if (ruleTypeId && aadFields?.length) { - return [{ title: ruleTypeId, fields: aadFields }]; + if (ruleTypeIds && dataView?.fields?.length) { + return [{ title: ruleTypeIds.join(','), fields: dataView.fields }]; } + if (dataView) { return [dataView]; } - return null; - }, [aadFields, dataView, ruleTypeId]); - const ruleType = useLoadRuleTypesQuery({ - filteredRuleTypes: ruleTypeId !== undefined ? [ruleTypeId] : [], - enabled: ruleTypeId !== undefined, - }); + return null; + }, [dataView, ruleTypeIds]); - const isSecurity = - (featureIds && featureIds.length === 1 && featureIds.includes(AlertConsumers.SIEM)) || - (ruleType && - ruleTypeId && - ruleType.ruleTypesState.data.get(ruleTypeId)?.producer === AlertConsumers.SIEM); + const isSecurity = ruleTypeIds?.some(isSiemRuleType) ?? false; const onSearchQuerySubmit = useCallback( ( @@ -174,7 +162,7 @@ export function AlertsSearchBar({ appName={appName} disableQueryLanguageSwitcher={disableQueryLanguageSwitcher} // @ts-expect-error - DataView fields prop and SearchBar indexPatterns props are overly broad - indexPatterns={!indexPatterns || fieldsLoading ? NO_INDEX_PATTERNS : indexPatterns} + indexPatterns={!indexPatterns ? NO_INDEX_PATTERNS : indexPatterns} placeholder={placeholder} query={{ query: query ?? '', language: queryLanguage }} filters={filters} diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_search_bar/constants.ts b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_search_bar/constants.ts index 408d4d1714743..3539966400054 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_search_bar/constants.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_search_bar/constants.ts @@ -10,5 +10,6 @@ import { AlertConsumers } from '@kbn/rule-data-utils'; export const NO_INDEX_PATTERNS: DataView[] = []; export const ALERTS_SEARCH_BAR_PARAMS_URL_STORAGE_KEY = 'searchBarParams'; -export const ALL_FEATURE_IDS = Object.values(AlertConsumers); -export const NON_SIEM_FEATURE_IDS = ALL_FEATURE_IDS.filter((fid) => fid !== AlertConsumers.SIEM); +export const NON_SIEM_CONSUMERS = Object.values(AlertConsumers).filter( + (fid) => fid !== AlertConsumers.SIEM +); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_search_bar/types.ts b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_search_bar/types.ts index b1af2746d6cac..a9538bd4888b1 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_search_bar/types.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_search_bar/types.ts @@ -6,7 +6,6 @@ */ import { Filter } from '@kbn/es-query'; -import { ValidFeatureId } from '@kbn/rule-data-utils'; import { SearchBarProps } from '@kbn/unified-search-plugin/public/search_bar/search_bar'; import { QuickFiltersMenuItem } from './quick_filters'; @@ -16,7 +15,6 @@ export interface AlertsSearchBarProps extends Omit, 'query' | 'onQueryChange' | 'onQuerySubmit'> { appName: string; disableQueryLanguageSwitcher?: boolean; - featureIds: ValidFeatureId[]; rangeFrom?: string; rangeTo?: string; query?: string; @@ -27,7 +25,7 @@ export interface AlertsSearchBarProps showSubmitButton?: boolean; placeholder?: string; submitOnBlur?: boolean; - ruleTypeId?: string; + ruleTypeIds?: string[]; onQueryChange?: (query: { dateRange: { from: string; to: string; mode?: 'absolute' | 'relative' }; query?: string; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_search_bar/url_synced_alerts_search_bar.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_search_bar/url_synced_alerts_search_bar.tsx index de89eb9715733..175d9538918e7 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_search_bar/url_synced_alerts_search_bar.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_search_bar/url_synced_alerts_search_bar.tsx @@ -5,20 +5,17 @@ * 2.0. */ -import React, { useCallback, useEffect, useMemo, useState } from 'react'; -import { BoolQuery } from '@kbn/es-query'; -import { AlertConsumers } from '@kbn/rule-data-utils'; +import React, { useCallback, useEffect, useState, useMemo } from 'react'; +import { BoolQuery, Filter } from '@kbn/es-query'; import { i18n } from '@kbn/i18n'; import { AlertFilterControls } from '@kbn/alerts-ui-shared/src/alert_filter_controls'; import { ControlGroupRenderer } from '@kbn/controls-plugin/public'; import { Storage } from '@kbn/kibana-utils-plugin/public'; -import { AlertsFeatureIdsFilter } from '../../lib/search_filters'; import { useKibana } from '../../..'; import { useAlertSearchBarStateContainer } from './use_alert_search_bar_state_container'; import { ALERTS_SEARCH_BAR_PARAMS_URL_STORAGE_KEY } from './constants'; import { AlertsSearchBarProps } from './types'; import AlertsSearchBar from './alerts_search_bar'; -import { nonNullable } from '../../../../common/utils'; import { buildEsQuery } from './build_es_query'; const INVALID_QUERY_STRING_TOAST_TITLE = i18n.translate( @@ -35,16 +32,17 @@ export interface UrlSyncedAlertsSearchBarProps > { showFilterControls?: boolean; onEsQueryChange: (esQuery: { bool: BoolQuery }) => void; - onActiveFeatureFiltersChange?: (value: AlertConsumers[]) => void; + onFilterSelected?: (filters: Filter[]) => void; } /** * An abstraction over AlertsSearchBar that syncs the query state with the url */ export const UrlSyncedAlertsSearchBar = ({ + ruleTypeIds, showFilterControls = false, onEsQueryChange, - onActiveFeatureFiltersChange, + onFilterSelected, ...rest }: UrlSyncedAlertsSearchBarProps) => { const { @@ -91,13 +89,6 @@ export const UrlSyncedAlertsSearchBar = ({ useEffect(() => { try { - onActiveFeatureFiltersChange?.([ - ...new Set( - filters - .flatMap((f) => (f as AlertsFeatureIdsFilter).meta.alertsFeatureIds) - .filter(nonNullable) - ), - ]); onEsQueryChange( buildEsQuery({ timeRange: { @@ -108,6 +99,8 @@ export const UrlSyncedAlertsSearchBar = ({ filters: [...filters, ...controlFilters], }) ); + + onFilterSelected?.(filters); } catch (error) { toasts.addError(error, { title: INVALID_QUERY_STRING_TOAST_TITLE, @@ -118,8 +111,8 @@ export const UrlSyncedAlertsSearchBar = ({ controlFilters, filters, kuery, - onActiveFeatureFiltersChange, onEsQueryChange, + onFilterSelected, onKueryChange, rangeFrom, rangeTo, @@ -154,6 +147,7 @@ export const UrlSyncedAlertsSearchBar = ({ savedQuery={savedQuery} onSavedQueryUpdated={setSavedQuery} onClearSavedQuery={clearSavedQuery} + ruleTypeIds={ruleTypeIds} {...rest} /> {showFilterControls && ( diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_table.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_table.tsx index 61c65eded27b5..cf7e184c50f31 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_table.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_table.tsx @@ -309,7 +309,7 @@ const AlertsTable: React.FunctionComponent = memo((props: Aler dynamicRowHeight, query, querySnapshot, - featureIds, + ruleTypeIds, cases: { data: cases, isLoading: isLoadingCases }, maintenanceWindows: { data: maintenanceWindows, isLoading: isLoadingMaintenanceWindows }, controls, @@ -345,7 +345,7 @@ const AlertsTable: React.FunctionComponent = memo((props: Aler query, useBulkActionsConfig: alertsTableConfiguration.useBulkActions, refresh: refetchAlerts, - featureIds, + ruleTypeIds, hideBulkActions: Boolean(alertsTableConfiguration.hideBulkActions), }; }, [ @@ -355,7 +355,7 @@ const AlertsTable: React.FunctionComponent = memo((props: Aler alertsTableConfiguration.hideBulkActions, query, refetchAlerts, - featureIds, + ruleTypeIds, ]); const { diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_table_state.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_table_state.test.tsx index 13b9433ce4b9e..9db58d26d9251 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_table_state.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_table_state.test.tsx @@ -9,12 +9,7 @@ import { BehaviorSubject } from 'rxjs'; import userEvent from '@testing-library/user-event'; import { get } from 'lodash'; import { fireEvent, render, waitFor, screen, act } from '@testing-library/react'; -import { - AlertConsumers, - ALERT_CASE_IDS, - ALERT_MAINTENANCE_WINDOW_IDS, - ALERT_UUID, -} from '@kbn/rule-data-utils'; +import { ALERT_CASE_IDS, ALERT_MAINTENANCE_WINDOW_IDS, ALERT_UUID } from '@kbn/rule-data-utils'; import { Storage } from '@kbn/kibana-utils-plugin/public'; import { @@ -344,7 +339,7 @@ const browserFields: BrowserFields = { }, }; -jest.mocked(fetchAlertsFields).mockResolvedValue({ browserFields, fields: [] }); +const fetchAlertsFieldsMock = fetchAlertsFields as jest.Mock; const queryClient = new QueryClient({ defaultOptions: { @@ -367,7 +362,7 @@ describe('AlertsTableState', () => { alertsTableConfigurationRegistry: alertsTableConfigurationRegistryMock, configurationId: PLUGIN_ID, id: PLUGIN_ID, - featureIds: [AlertConsumers.LOGS], + ruleTypeIds: ['logs'], query: {}, columns, pagination: { @@ -419,6 +414,8 @@ describe('AlertsTableState', () => { data: maintenanceWindowsMap, isFetching: false, }); + + fetchAlertsFieldsMock.mockResolvedValue({ browserFields, fields: [] }); }); describe('Cases', () => { @@ -837,6 +834,8 @@ describe('AlertsTableState', () => { data: new Map(), isFetching: false, }); + + fetchAlertsFieldsMock.mockResolvedValue({ browserFields, fields: [] }); }); it('should show field browser', async () => { @@ -845,13 +844,13 @@ describe('AlertsTableState', () => { }); it('should remove an already existing element when selected', async () => { - const { getByTestId, queryByTestId } = render(); + const { findByTestId, queryByTestId } = render(); expect(queryByTestId(`dataGridHeaderCell-${AlertsField.name}`)).not.toBe(null); - fireEvent.click(getByTestId('show-field-browser')); - const fieldCheckbox = getByTestId(`field-${AlertsField.name}-checkbox`); + fireEvent.click(await findByTestId('show-field-browser')); + const fieldCheckbox = await findByTestId(`field-${AlertsField.name}-checkbox`); fireEvent.click(fieldCheckbox); - fireEvent.click(getByTestId('close')); + fireEvent.click(await findByTestId('close')); await waitFor(() => { expect(queryByTestId(`dataGridHeaderCell-${AlertsField.name}`)).toBe(null); @@ -877,13 +876,15 @@ describe('AlertsTableState', () => { set: jest.fn(), })); - const { getByTestId, queryByTestId } = render(); + const { getByTestId, findByTestId, queryByTestId } = render( + + ); expect(queryByTestId(`dataGridHeaderCell-${AlertsField.name}`)).toBe(null); - fireEvent.click(getByTestId('show-field-browser')); - const fieldCheckbox = getByTestId(`field-${AlertsField.name}-checkbox`); + fireEvent.click(await findByTestId('show-field-browser')); + const fieldCheckbox = await findByTestId(`field-${AlertsField.name}-checkbox`); fireEvent.click(fieldCheckbox); - fireEvent.click(getByTestId('close')); + fireEvent.click(await findByTestId('close')); await waitFor(() => { expect(queryByTestId(`dataGridHeaderCell-${AlertsField.name}`)).not.toBe(null); @@ -896,13 +897,13 @@ describe('AlertsTableState', () => { }); it('should insert a new field as column when its not a default one', async () => { - const { getByTestId, queryByTestId } = render(); + const { findByTestId, queryByTestId } = render(); expect(queryByTestId(`dataGridHeaderCell-${AlertsField.uuid}`)).toBe(null); - fireEvent.click(getByTestId('show-field-browser')); - const fieldCheckbox = getByTestId(`field-${AlertsField.uuid}-checkbox`); + fireEvent.click(await findByTestId('show-field-browser')); + const fieldCheckbox = await findByTestId(`field-${AlertsField.uuid}-checkbox`); fireEvent.click(fieldCheckbox); - fireEvent.click(getByTestId('close')); + fireEvent.click(await findByTestId('close')); await waitFor(() => { expect(queryByTestId(`dataGridHeaderCell-${AlertsField.uuid}`)).not.toBe(null); @@ -958,6 +959,16 @@ describe('AlertsTableState', () => { expect(result.getByTestId('alertsStateTableEmptyState')).toBeTruthy(); }); + it('should render an empty screen when the data are undefined', async () => { + mockUseSearchAlertsQuery.mockReturnValue({ + data: undefined, + refetch: refetchMock, + }); + + const result = render(); + expect(result.getByTestId('alertsStateTableEmptyState')).toBeTruthy(); + }); + describe('inspect button', () => { it('should hide the inspect button by default', () => { render(); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_table_state.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_table_state.tsx index 62c78a3ad589c..93bb4f18dfe9a 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_table_state.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_table_state.tsx @@ -21,7 +21,6 @@ import { } from '@elastic/eui'; import type { MappingRuntimeFields } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import { ALERT_CASE_IDS, ALERT_MAINTENANCE_WINDOW_IDS } from '@kbn/rule-data-utils'; -import type { ValidFeatureId } from '@kbn/rule-data-utils'; import type { RuleRegistrySearchRequestPagination } from '@kbn/rule-registry-plugin/common'; import type { BrowserFields } from '@kbn/alerting-types'; import { Storage } from '@kbn/kibana-utils-plugin/public'; @@ -68,7 +67,8 @@ export type AlertsTableStateProps = { alertsTableConfigurationRegistry: AlertsTableConfigurationRegistryContract; configurationId: string; id: string; - featureIds: ValidFeatureId[]; + ruleTypeIds: string[]; + consumers?: string[]; query: Pick; initialPageSize?: number; browserFields?: BrowserFields; @@ -192,7 +192,8 @@ const AlertsTableStateWithQueryProvider = memo( alertsTableConfigurationRegistry, configurationId, id, - featureIds, + ruleTypeIds, + consumers, query, initialPageSize = DEFAULT_ALERTS_PAGE_SIZE, leadingControlColumns = DEFAULT_LEADING_CONTROL_COLUMNS, @@ -292,7 +293,7 @@ const AlertsTableStateWithQueryProvider = memo( onColumnResize, fields, } = useColumns({ - featureIds, + ruleTypeIds, storageAlertsTable, storage, id, @@ -301,7 +302,8 @@ const AlertsTableStateWithQueryProvider = memo( }); const [queryParams, setQueryParams] = useState({ - featureIds, + ruleTypeIds, + consumers, fields, query, sort, @@ -312,14 +314,16 @@ const AlertsTableStateWithQueryProvider = memo( useEffect(() => { setQueryParams(({ pageIndex: oldPageIndex, pageSize: oldPageSize, ...prevQueryParams }) => ({ - featureIds, + ruleTypeIds, + consumers, fields, query, sort, runtimeMappings, // Go back to the first page if the query changes pageIndex: !deepEqual(prevQueryParams, { - featureIds, + ruleTypeIds, + consumers, fields, query, sort, @@ -329,7 +333,7 @@ const AlertsTableStateWithQueryProvider = memo( : oldPageIndex, pageSize: oldPageSize, })); - }, [featureIds, fields, query, runtimeMappings, sort]); + }, [ruleTypeIds, fields, query, runtimeMappings, sort, consumers]); const { data: alertsData, @@ -363,11 +367,11 @@ const AlertsTableStateWithQueryProvider = memo( } }, [alerts, isLoading, isSuccess, onLoaded]); - const mutedAlertIds = useMemo(() => { + const mutedRuleIds = useMemo(() => { return [...new Set(alerts.map((a) => a['kibana.alert.rule.uuid']![0]))]; }, [alerts]); - const { data: mutedAlerts } = useGetMutedAlerts(mutedAlertIds); + const { data: mutedAlerts } = useGetMutedAlerts(mutedRuleIds); const overriddenActions = useMemo(() => { return { toggleColumn: onToggleColumn }; }, [onToggleColumn]); @@ -501,7 +505,7 @@ const AlertsTableStateWithQueryProvider = memo( toolbarVisibility, shouldHighlightRow, dynamicRowHeight, - featureIds, + ruleTypeIds, querySnapshot, pageIndex: queryParams.pageIndex, pageSize: queryParams.pageSize, @@ -541,7 +545,7 @@ const AlertsTableStateWithQueryProvider = memo( toolbarVisibility, shouldHighlightRow, dynamicRowHeight, - featureIds, + ruleTypeIds, querySnapshot, queryParams.pageIndex, queryParams.pageSize, @@ -579,7 +583,7 @@ const AlertsTableStateWithQueryProvider = memo( return ( - {!isLoading && alertsCount === 0 && ( + {!isLoading && alertsCount <= 0 && ( field === ALERT_RULE_PRODUCER)?.value?.[0]; - const consumer: AlertConsumers = observabilityFeatureIds.includes(producer) + const consumer: AlertsTableSupportedConsumers = observabilityFeatureIds.includes(producer) ? 'observability' : producer && (value === 'alerts' || value === 'stackAlerts' || value === 'discover') ? producer diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/constants.ts b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/constants.ts index 9605abb085232..54846574c1a10 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/constants.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/constants.ts @@ -19,6 +19,7 @@ import { STACK_MONITORING_DISPLAY_NAME, UPTIME_DISPLAY_NAME, } from '../translations'; +import { AlertsTableSupportedConsumers } from './types'; interface AlertProducerData { displayName: string; @@ -33,13 +34,18 @@ export const observabilityFeatureIds: AlertConsumers[] = [ AlertConsumers.LOGS, AlertConsumers.SLO, AlertConsumers.UPTIME, + AlertConsumers.ALERTS, ]; -export const stackFeatureIds: AlertConsumers[] = [AlertConsumers.STACK_ALERTS, AlertConsumers.ML]; +export const stackFeatureIds: AlertConsumers[] = [ + AlertConsumers.STACK_ALERTS, + AlertConsumers.ML, + AlertConsumers.DISCOVER, +]; export const [_, ...observabilityApps] = observabilityFeatureIds; -export const alertProducersData: Record = { +export const alertProducersData: Record = { [AlertConsumers.OBSERVABILITY]: { displayName: OBSERVABILITY_DISPLAY_NAME, icon: 'logoObservability', @@ -86,4 +92,9 @@ export const alertProducersData: Record = { displayName: 'Example', icon: 'beaker', }, + [AlertConsumers.DISCOVER]: { + displayName: STACK_DISPLAY_NAME, + icon: 'managementApp', + subFeatureIds: stackFeatureIds, + }, }; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/alert_mute/use_get_muted_alerts.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/alert_mute/use_get_muted_alerts.test.tsx index 2718ccd8ca88e..ae75e5472f229 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/alert_mute/use_get_muted_alerts.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/alert_mute/use_get_muted_alerts.test.tsx @@ -37,7 +37,7 @@ describe('useGetMutedAlerts', () => { await waitFor(() => { expect(muteAlertInstanceSpy).toHaveBeenCalledWith( expect.anything(), - { ids: ruleIds }, + { ruleIds }, expect.any(AbortSignal) ); }); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/alert_mute/use_get_muted_alerts.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/alert_mute/use_get_muted_alerts.tsx index 08f172451ca23..1ca6cbb22ea97 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/alert_mute/use_get_muted_alerts.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/alert_mute/use_get_muted_alerts.tsx @@ -25,7 +25,7 @@ export const useGetMutedAlerts = (ruleIds: string[], enabled = true) => { return useQuery( triggersActionsUiQueriesKeys.mutedAlerts(), ({ signal }) => - getMutedAlerts(http, { ids: ruleIds }, signal).then(({ data: rules }) => + getMutedAlerts(http, { ruleIds }, signal).then(({ data: rules }) => rules?.reduce((mutedAlerts, rule) => { mutedAlerts[rule.id] = rule.muted_alert_ids; return mutedAlerts; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/apis/get_rules_muted_alerts.test.ts b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/apis/get_rules_muted_alerts.test.ts new file mode 100644 index 0000000000000..d0f1a39f7cede --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/apis/get_rules_muted_alerts.test.ts @@ -0,0 +1,46 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor 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 { httpServiceMock } from '@kbn/core/public/mocks'; +import { getMutedAlerts } from './get_rules_muted_alerts'; + +const http = httpServiceMock.createStartContract(); + +describe('getMutedAlerts', () => { + const apiRes = { + page: 1, + per_page: 10, + total: 0, + data: [], + }; + + beforeEach(() => { + jest.clearAllMocks(); + + http.post.mockResolvedValueOnce(apiRes); + }); + + test('should call find API with correct params', async () => { + const result = await getMutedAlerts(http, { ruleIds: ['foo'] }); + + expect(result).toEqual({ + page: 1, + per_page: 10, + total: 0, + data: [], + }); + + expect(http.post.mock.calls[0]).toMatchInlineSnapshot(` + Array [ + "/internal/alerting/rules/_find", + Object { + "body": "{\\"rule_type_ids\\":[\\"foo\\"],\\"fields\\":[\\"id\\",\\"mutedInstanceIds\\"],\\"page\\":1,\\"per_page\\":1}", + "signal": undefined, + }, + ] + `); + }); +}); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/apis/get_rules_muted_alerts.ts b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/apis/get_rules_muted_alerts.ts index 5a2f2fcc21c6b..d9baef548dafc 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/apis/get_rules_muted_alerts.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/apis/get_rules_muted_alerts.ts @@ -6,7 +6,6 @@ */ import { HttpStart } from '@kbn/core-http-browser'; -import { nodeBuilder } from '@kbn/es-query'; const INTERNAL_FIND_RULES_URL = '/internal/alerting/rules/_find'; @@ -21,18 +20,15 @@ export interface FindRulesResponse { export const getMutedAlerts = async ( http: HttpStart, - params: { ids: string[] }, + params: { ruleIds: string[] }, signal?: AbortSignal ) => { - const filterNode = nodeBuilder.or( - params.ids.map((id) => nodeBuilder.is('alert.id', `alert:${id}`)) - ); return http.post(INTERNAL_FIND_RULES_URL, { body: JSON.stringify({ - filter: JSON.stringify(filterNode), + rule_type_ids: params.ruleIds, fields: ['id', 'mutedInstanceIds'], page: 1, - per_page: params.ids.length, + per_page: params.ruleIds.length, }), signal, }); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/use_bulk_actions.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/use_bulk_actions.test.tsx index 0f136e15156d7..554febab20210 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/use_bulk_actions.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/use_bulk_actions.test.tsx @@ -392,7 +392,13 @@ describe('bulk action hooks', () => { it('appends only the case bulk actions for SIEM', async () => { const { result } = renderHook( () => - useBulkActions({ alertsCount: 0, query: {}, casesConfig, refresh, featureIds: ['siem'] }), + useBulkActions({ + alertsCount: 0, + query: {}, + casesConfig, + refresh, + ruleTypeIds: ['siem.esqlRule'], + }), { wrapper: appMockRender.AppWrapper, } @@ -476,7 +482,7 @@ describe('bulk action hooks', () => { query: {}, casesConfig, refresh, - featureIds: ['observability'], + ruleTypeIds: ['observability'], }), { wrapper: appMockRender.AppWrapper, @@ -492,7 +498,7 @@ describe('bulk action hooks', () => { query: {}, casesConfig, refresh, - featureIds: ['observability'], + ruleTypeIds: ['observability'], hideBulkActions: true, }), { diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/use_bulk_actions.ts b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/use_bulk_actions.ts index 727ff4f93ebd8..1f35d02f8d72f 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/use_bulk_actions.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/use_bulk_actions.ts @@ -7,7 +7,7 @@ import { useCallback, useContext, useEffect, useMemo } from 'react'; import { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import { useKibana } from '@kbn/kibana-react-plugin/public'; -import { ALERT_CASE_IDS, ValidFeatureId } from '@kbn/rule-data-utils'; +import { ALERT_CASE_IDS, isSiemRuleType } from '@kbn/rule-data-utils'; import { AlertsTableContext } from '../contexts/alerts_table_context'; import { AlertsTableConfigurationRegistry, @@ -40,7 +40,7 @@ interface BulkActionsProps { casesConfig?: AlertsTableConfigurationRegistry['cases']; useBulkActionsConfig?: UseBulkActionsRegistry; refresh: () => void; - featureIds?: ValidFeatureId[]; + ruleTypeIds?: string[]; hideBulkActions?: boolean; } @@ -57,7 +57,7 @@ export interface UseBulkActions { type UseBulkAddToCaseActionsProps = Pick & Pick; -type UseBulkUntrackActionsProps = Pick & +type UseBulkUntrackActionsProps = Pick & Pick & { isAllSelected: boolean; }; @@ -191,7 +191,7 @@ export const useBulkUntrackActions = ({ refresh, clearSelection, query, - featureIds = [], + ruleTypeIds = [], isAllSelected, }: UseBulkUntrackActionsProps) => { const onSuccess = useCallback(() => { @@ -217,7 +217,7 @@ export const useBulkUntrackActions = ({ try { setIsBulkActionsLoading(true); if (isAllSelected) { - await untrackAlertsByQuery({ query, featureIds }); + await untrackAlertsByQuery({ query, ruleTypeIds }); } else { await untrackAlerts({ indices, alertUuids }); } @@ -228,7 +228,7 @@ export const useBulkUntrackActions = ({ }, [ query, - featureIds, + ruleTypeIds, isAllSelected, onSuccess, setIsBulkActionsLoading, @@ -277,7 +277,7 @@ export function useBulkActions({ query, refresh, useBulkActionsConfig = () => [], - featureIds, + ruleTypeIds, hideBulkActions, }: BulkActionsProps): UseBulkActions { const { @@ -300,13 +300,14 @@ export function useBulkActions({ refresh, clearSelection, query, - featureIds, + ruleTypeIds, isAllSelected: bulkActionsState.isAllSelected, }); const initialItems = useMemo(() => { - return [...caseBulkActions, ...(featureIds?.includes('siem') ? [] : untrackBulkActions)]; - }, [caseBulkActions, featureIds, untrackBulkActions]); + return [...caseBulkActions, ...(ruleTypeIds?.some(isSiemRuleType) ? [] : untrackBulkActions)]; + }, [caseBulkActions, ruleTypeIds, untrackBulkActions]); + const bulkActions = useMemo(() => { if (hideBulkActions) { return []; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/use_bulk_untrack_alerts_by_query.test.ts b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/use_bulk_untrack_alerts_by_query.test.ts new file mode 100644 index 0000000000000..5de16dd70ce52 --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/use_bulk_untrack_alerts_by_query.test.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 { act, renderHook } from '@testing-library/react-hooks'; +import { AppMockRenderer, createAppMockRenderer } from '../../test_utils'; +import { AlertsQueryContext } from '@kbn/alerts-ui-shared/src/common/contexts/alerts_query_context'; +import { useBulkUntrackAlertsByQuery } from './use_bulk_untrack_alerts_by_query'; +import { createStartServicesMock } from '../../../../common/lib/kibana/kibana_react.mock'; +import { TriggersAndActionsUiServices } from '../../../..'; + +const mockUseKibanaReturnValue: TriggersAndActionsUiServices = createStartServicesMock(); + +jest.mock('../../../../common/lib/kibana', () => ({ + useKibana: jest.fn(() => ({ + services: mockUseKibanaReturnValue, + })), +})); + +const response = {}; + +describe('useBulkUntrackAlertsByQuery', () => { + const httpMock = mockUseKibanaReturnValue.http.post as jest.Mock; + + let appMockRender: AppMockRenderer; + + beforeEach(() => { + jest.clearAllMocks(); + appMockRender = createAppMockRenderer(AlertsQueryContext); + }); + + it('calls the api when invoked with the correct parameters', async () => { + httpMock.mockResolvedValue(response); + + const { result, waitFor } = renderHook(() => useBulkUntrackAlertsByQuery(), { + wrapper: appMockRender.AppWrapper, + }); + + await act(async () => { + // @ts-expect-error: no need to specify a query + await result.current.mutateAsync({ ruleTypeIds: ['foo'], query: [] }); + }); + + await waitFor(() => { + expect(httpMock).toHaveBeenCalledWith('/internal/alerting/alerts/_bulk_untrack_by_query', { + body: '{"query":[],"rule_type_ids":["foo"]}', + }); + }); + }); +}); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/use_bulk_untrack_alerts_by_query.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/use_bulk_untrack_alerts_by_query.tsx index 321d861e03615..88c878aa47a66 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/use_bulk_untrack_alerts_by_query.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/use_bulk_untrack_alerts_by_query.tsx @@ -9,7 +9,6 @@ import { i18n } from '@kbn/i18n'; import { useMutation } from '@tanstack/react-query'; import { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import { INTERNAL_BASE_ALERTING_API_PATH } from '@kbn/alerting-plugin/common'; -import { ValidFeatureId } from '@kbn/rule-data-utils'; import { AlertsQueryContext } from '@kbn/alerts-ui-shared/src/common/contexts/alerts_query_context'; import { useKibana } from '../../../../common'; @@ -22,14 +21,14 @@ export const useBulkUntrackAlertsByQuery = () => { const untrackAlertsByQuery = useMutation< string, string, - { query: Pick; featureIds: ValidFeatureId[] } + { query: Pick; ruleTypeIds: string[] } >( ['untrackAlerts'], - ({ query, featureIds }) => { + ({ query, ruleTypeIds }) => { try { const body = JSON.stringify({ query: Array.isArray(query) ? query : [query], - feature_ids: featureIds, + rule_type_ids: ruleTypeIds, }); return http.post(`${INTERNAL_BASE_ALERTING_API_PATH}/alerts/_bulk_untrack_by_query`, { body, diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/use_columns/use_columns.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/use_columns/use_columns.test.tsx index d6ecf3d9ab20d..3b742bbd6d620 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/use_columns/use_columns.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/use_columns/use_columns.test.tsx @@ -7,7 +7,6 @@ import React, { FunctionComponent } from 'react'; import { EuiDataGridColumn } from '@elastic/eui'; -import { AlertConsumers } from '@kbn/rule-data-utils'; import { Storage } from '@kbn/kibana-utils-plugin/public'; import { act, waitFor, renderHook } from '@testing-library/react'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; @@ -76,7 +75,7 @@ mockFetchAlertsFields.mockResolvedValue({ browserFields, fields: [] }); describe('useColumns', () => { const id = 'useColumnTest'; - const featureIds: AlertConsumers[] = [AlertConsumers.LOGS, AlertConsumers.APM]; + const ruleTypeIds: string[] = ['apm', 'logs']; let storage = { current: new Storage(mockStorage) }; const getStorageAlertsTableByDefaultColumns = (defaultColumns: EuiDataGridColumn[]) => { @@ -155,7 +154,7 @@ describe('useColumns', () => { () => useColumns({ defaultColumns, - featureIds, + ruleTypeIds, id, storageAlertsTable: localStorageAlertsTable, storage, @@ -187,7 +186,7 @@ describe('useColumns', () => { () => useColumns({ defaultColumns, - featureIds, + ruleTypeIds, id, storageAlertsTable: localStorageAlertsTable, storage, @@ -213,7 +212,7 @@ describe('useColumns', () => { useColumns({ alertsFields, defaultColumns, - featureIds, + ruleTypeIds, id, storageAlertsTable: localStorageAlertsTable, storage, @@ -232,7 +231,7 @@ describe('useColumns', () => { () => useColumns({ defaultColumns, - featureIds, + ruleTypeIds, id, storageAlertsTable: localStorageAlertsTable, storage, @@ -254,7 +253,7 @@ describe('useColumns', () => { () => useColumns({ defaultColumns, - featureIds, + ruleTypeIds, id, storageAlertsTable: localStorageAlertsTable, storage, @@ -283,7 +282,7 @@ describe('useColumns', () => { () => useColumns({ defaultColumns, - featureIds, + ruleTypeIds, id, storageAlertsTable: localStorageAlertsTable, storage, @@ -301,7 +300,7 @@ describe('useColumns', () => { () => useColumns({ defaultColumns: localDefaultColumns, - featureIds, + ruleTypeIds, id, storageAlertsTable: localStorageAlertsTable, storage, @@ -338,7 +337,7 @@ describe('useColumns', () => { () => useColumns({ defaultColumns, - featureIds, + ruleTypeIds, id, storageAlertsTable: localStorageAlertsTable, storage, @@ -357,7 +356,7 @@ describe('useColumns', () => { () => useColumns({ defaultColumns, - featureIds, + ruleTypeIds, id, storageAlertsTable: localStorageAlertsTable, storage, @@ -378,7 +377,7 @@ describe('useColumns', () => { () => useColumns({ defaultColumns, - featureIds, + ruleTypeIds, id, storageAlertsTable: localStorageAlertsTable, storage, @@ -407,7 +406,7 @@ describe('useColumns', () => { () => useColumns({ defaultColumns, - featureIds, + ruleTypeIds, id, storageAlertsTable: localStorageAlertsTable, storage, @@ -440,7 +439,7 @@ describe('useColumns', () => { () => useColumns({ defaultColumns, - featureIds, + ruleTypeIds, id, storageAlertsTable: localStorageAlertsTable, storage, diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/use_columns/use_columns.ts b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/use_columns/use_columns.ts index 30c9ff0ea69ed..3af1d37f10de8 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/use_columns/use_columns.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/use_columns/use_columns.ts @@ -9,7 +9,6 @@ import { EuiDataGridColumn, EuiDataGridOnColumnResizeData } from '@elastic/eui'; import { IStorageWrapper } from '@kbn/kibana-utils-plugin/public'; import { BrowserField, BrowserFields } from '@kbn/alerting-types'; import { MutableRefObject, useCallback, useEffect, useMemo, useRef, useState } from 'react'; -import { AlertConsumers } from '@kbn/rule-data-utils'; import { isEmpty } from 'lodash'; import { useFetchAlertsFieldsQuery } from '@kbn/alerts-ui-shared/src/common/hooks/use_fetch_alerts_fields_query'; import { AlertsQueryContext } from '@kbn/alerts-ui-shared/src/common/contexts/alerts_query_context'; @@ -18,7 +17,7 @@ import { toggleColumn } from './toggle_column'; import { useKibana } from '../../../../../common'; export interface UseColumnsArgs { - featureIds: AlertConsumers[]; + ruleTypeIds: string[]; storageAlertsTable: React.MutableRefObject; storage: React.MutableRefObject; id: string; @@ -155,7 +154,7 @@ const persist = ({ }; export const useColumns = ({ - featureIds, + ruleTypeIds, storageAlertsTable, storage, id, @@ -167,7 +166,7 @@ export const useColumns = ({ const fieldsQuery = useFetchAlertsFieldsQuery( { http, - featureIds, + ruleTypeIds, }, { enabled: !alertsFields, diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/types.ts b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/types.ts index 819cc42bd90e6..46b349ae9bcce 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/types.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/types.ts @@ -20,6 +20,8 @@ export interface Consumer { name: string; } +export type AlertsTableSupportedConsumers = Exclude; + export type ServerError = IHttpFetchError; export interface CellComponentProps { diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule.test.tsx index 23e6f978f4c05..d64c018a07f3e 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule.test.tsx @@ -602,6 +602,7 @@ function mockRuleType(overloads: Partial = {}): RuleType { producer: 'rules', minimumLicenseRequired: 'basic', enabledInLicense: true, + category: 'my-category', ...overloads, }; } diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule.tsx index 34f5a8e65436a..593e0a989b5f3 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule.tsx @@ -8,8 +8,8 @@ import React, { lazy, useCallback, useMemo } from 'react'; import { i18n } from '@kbn/i18n'; import { EuiSpacer, EuiFlexGroup, EuiFlexItem, EuiTabbedContent } from '@elastic/eui'; -import { AlertStatusValues, ALERTING_FEATURE_ID } from '@kbn/alerting-plugin/common'; -import { ALERT_RULE_UUID, AlertConsumers } from '@kbn/rule-data-utils'; +import { AlertStatusValues } from '@kbn/alerting-plugin/common'; +import { ALERT_RULE_UUID } from '@kbn/rule-data-utils'; import { ALERT_TABLE_GENERIC_CONFIG_ID } from '../../../constants'; import { AlertTableConfigRegistry } from '../../../alert_table_config_registry'; import { useKibana } from '../../../../common/lib/kibana'; @@ -106,11 +106,7 @@ export function RuleComponent({ alertsTableConfigurationRegistry={ alertsTableConfigurationRegistry as AlertTableConfigRegistry } - featureIds={ - (rule.consumer === ALERTING_FEATURE_ID - ? [ruleType.producer] - : [rule.consumer]) as AlertConsumers[] - } + ruleTypeIds={[ruleType.id]} query={{ bool: { filter: { term: { [ALERT_RULE_UUID]: rule.id } } } }} showAlertStatusWithFlapping lastReloadRequestTime={lastReloadRequestTime} @@ -131,11 +127,10 @@ export function RuleComponent({ lastReloadRequestTime, onMuteAction, readOnly, - rule.consumer, rule.id, ruleType.hasAlertsMappings, ruleType.hasFieldsForAAD, - ruleType.producer, + ruleType.id, ]); const tabs = [ diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_details.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_details.test.tsx index ffde171117385..23c19642a8701 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_details.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_details.test.tsx @@ -88,6 +88,7 @@ const ruleType: RuleType = { producer: ALERTING_FEATURE_ID, authorizedConsumers, enabledInLicense: true, + category: 'my-category', }; describe('rule_details', () => { diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_route.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_route.test.tsx index 7e660a30f7ec9..b8357c68da20e 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_route.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_route.test.tsx @@ -146,6 +146,7 @@ function mockRuleType(overloads: Partial = {}): RuleType { producer: 'rules', minimumLicenseRequired: 'basic', enabledInLicense: true, + category: 'my-category', ...overloads, }; } diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/test_helpers.ts b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/test_helpers.ts index 01ea94fdea8df..3da317d4e2be1 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/test_helpers.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/test_helpers.ts @@ -79,6 +79,7 @@ export function mockRuleType(overloads: Partial = {}): RuleType { producer: 'rules', minimumLicenseRequired: 'basic', enabledInLicense: true, + category: 'my-category', ...overloads, }; } diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_add.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_add.test.tsx index c7b2876d83d84..0b9109c18831c 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_add.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_add.test.tsx @@ -450,6 +450,7 @@ describe('rule_add', () => { }, ], enabledInLicense: true, + category: 'my-category', defaultActionGroupId: 'threshold.fired', minimumLicenseRequired: 'basic', recoveryActionGroup: { id: 'recovered', name: 'Recovered' }, 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 17bdcc92997ca..a89f7fe76339b 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 @@ -329,6 +329,7 @@ describe('rule_form', () => { state: [], }, enabledInLicense: true, + category: 'my-category', }, { id: 'disabled-by-license', @@ -352,6 +353,7 @@ describe('rule_form', () => { state: [], }, enabledInLicense: false, + category: 'my-category', }, ]; useLoadRuleTypesQuery.mockReturnValue({ @@ -579,6 +581,7 @@ describe('rule_form', () => { }, ], enabledInLicense: true, + category: 'my-category', defaultActionGroupId: 'threshold.fired', minimumLicenseRequired: 'basic', recoveryActionGroup: { id: 'recovered', name: 'Recovered' }, @@ -652,6 +655,7 @@ describe('rule_form', () => { }, ], enabledInLicense: true, + category: 'my-category', defaultActionGroupId: 'threshold.fired', minimumLicenseRequired: 'basic', recoveryActionGroup: { id: 'recovered', name: 'Recovered' }, @@ -730,6 +734,7 @@ describe('rule_form', () => { }, ], enabledInLicense: true, + category: 'my-category', defaultActionGroupId: 'threshold.fired', minimumLicenseRequired: 'basic', recoveryActionGroup: { id: 'recovered', name: 'Recovered' }, @@ -789,6 +794,7 @@ describe('rule_form', () => { }, ], enabledInLicense: true, + category: 'my-category', defaultActionGroupId: 'threshold.fired', minimumLicenseRequired: 'basic', recoveryActionGroup: { id: 'recovered', name: 'Recovered' }, @@ -848,6 +854,7 @@ describe('rule_form', () => { }, ], enabledInLicense: true, + category: 'my-category', defaultActionGroupId: 'threshold.fired', minimumLicenseRequired: 'basic', recoveryActionGroup: { id: 'recovered', name: 'Recovered' }, @@ -907,6 +914,7 @@ describe('rule_form', () => { }, ], enabledInLicense: true, + category: 'my-category', defaultActionGroupId: 'threshold.fired', minimumLicenseRequired: 'basic', recoveryActionGroup: { id: 'recovered', name: 'Recovered' }, @@ -966,6 +974,7 @@ describe('rule_form', () => { }, ], enabledInLicense: true, + category: 'my-category', defaultActionGroupId: 'threshold.fired', minimumLicenseRequired: 'basic', recoveryActionGroup: { id: 'recovered', name: 'Recovered' }, diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_form_consumer_selection.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_form_consumer_selection.test.tsx index bec46c682919b..c98733d377f0e 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_form_consumer_selection.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_form_consumer_selection.test.tsx @@ -9,14 +9,19 @@ import React from 'react'; import { fireEvent, render, screen } from '@testing-library/react'; import { RuleFormConsumerSelection } from './rule_form_consumer_selection'; import { RuleCreationValidConsumer } from '../../../types'; +import { useKibana } from '../../../common/lib/kibana'; const mockConsumers: RuleCreationValidConsumer[] = ['logs', 'infrastructure', 'stackAlerts']; const mockOnChange = jest.fn(); +jest.mock('../../../common/lib/kibana'); +const useKibanaMock = useKibana as jest.Mocked; + describe('RuleFormConsumerSelectionModal', () => { beforeEach(() => { jest.clearAllMocks(); + useKibanaMock().services.isServerless = false; }); it('renders correctly', async () => { @@ -162,41 +167,56 @@ describe('RuleFormConsumerSelectionModal', () => { expect(screen.queryByTestId('ruleFormConsumerSelect')).not.toBeInTheDocument(); }); - it('should display nothing if observability is one of the consumers', () => { + it('should display the initial selected consumer', () => { render( ); - expect(screen.queryByTestId('ruleFormConsumerSelect')).not.toBeInTheDocument(); + expect(screen.getByTestId('comboBoxSearchInput')).toHaveValue('Logs'); }); - it('should display the initial selected consumer', () => { + it('should not display the initial selected consumer if it is not a selectable option', () => { render( ); + expect(screen.getByTestId('comboBoxSearchInput')).toHaveValue(''); + }); - expect(screen.getByTestId('comboBoxSearchInput')).toHaveValue('Logs'); + it('should not show the role visibility dropdown on serverless on an o11y project', () => { + useKibanaMock().services.isServerless = true; + + render( + + ); + expect(screen.queryByTestId('ruleFormConsumerSelect')).not.toBeInTheDocument(); }); - it('should not display the initial selected consumer if it is not a selectable option', () => { + it('should set the consumer correctly on an o11y project', () => { + useKibanaMock().services.isServerless = true; + render( ); - expect(screen.getByTestId('comboBoxSearchInput')).toHaveValue(''); + expect(mockOnChange).toHaveBeenLastCalledWith('observability'); }); }); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_form_consumer_selection.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_form_consumer_selection.tsx index 46ec61cca8a5e..9fff99c1c9998 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_form_consumer_selection.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_form_consumer_selection.tsx @@ -10,6 +10,7 @@ import { EuiComboBox, EuiFormRow, EuiComboBoxOptionOption } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { AlertConsumers, STACK_ALERTS_FEATURE_ID } from '@kbn/rule-data-utils'; import { IErrorObject, RuleCreationValidConsumer } from '../../../types'; +import { useKibana } from '../../../common/lib/kibana'; const SELECT_LABEL: string = i18n.translate( 'xpack.triggersActionsUI.sections.ruleFormConsumerSelectionModal.selectLabel', @@ -80,8 +81,11 @@ export interface RuleFormConsumerSelectionProps { const SINGLE_SELECTION = { asPlainText: true }; export const RuleFormConsumerSelection = (props: RuleFormConsumerSelectionProps) => { + const { isServerless } = useKibana().services; + const { consumers, errors, onChange, selectedConsumer, initialSelectedConsumer } = props; const isInvalid = (errors?.consumer as string[])?.length > 0; + const handleOnChange = useCallback( (selected: Array>) => { if (selected.length > 0) { @@ -93,6 +97,7 @@ export const RuleFormConsumerSelection = (props: RuleFormConsumerSelectionProps) }, [onChange] ); + const validatedSelectedConsumer = useMemo(() => { if ( selectedConsumer && @@ -103,6 +108,7 @@ export const RuleFormConsumerSelection = (props: RuleFormConsumerSelectionProps) } return null; }, [selectedConsumer, consumers]); + const selectedOptions = useMemo( () => validatedSelectedConsumer @@ -149,15 +155,16 @@ export const RuleFormConsumerSelection = (props: RuleFormConsumerSelectionProps) useEffect(() => { if (consumers.length === 1) { onChange(consumers[0] as RuleCreationValidConsumer); - } else if (consumers.includes(AlertConsumers.OBSERVABILITY)) { + } else if (isServerless && consumers.includes(AlertConsumers.OBSERVABILITY)) { onChange(AlertConsumers.OBSERVABILITY as RuleCreationValidConsumer); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [consumers]); - if (consumers.length <= 1 || consumers.includes(AlertConsumers.OBSERVABILITY)) { + if (consumers.length <= 1 || (isServerless && consumers.includes(AlertConsumers.OBSERVABILITY))) { return null; } + return ( { }); }); -// Failing: See https://github.com/elastic/kibana/issues/182435 -describe.skip('rules_list component empty', () => { +describe('rules_list component empty', () => { beforeEach(() => { fetchActiveMaintenanceWindowsMock.mockResolvedValue([]); loadRulesWithKueryFilter.mockResolvedValue({ @@ -282,28 +281,6 @@ describe.skip('rules_list component empty', () => { expect(await screen.findByTestId('createFirstRuleEmptyPrompt')).toBeInTheDocument(); }); - it('renders MaintenanceWindowCallout if one exists', async () => { - fetchActiveMaintenanceWindowsMock.mockResolvedValue([RUNNING_MAINTENANCE_WINDOW_1]); - renderWithProviders(); - expect( - await screen.findByText( - 'Rule notifications are stopped while maintenance windows are running.' - ) - ).toBeInTheDocument(); - expect(fetchActiveMaintenanceWindowsMock).toHaveBeenCalledTimes(1); - }); - - it("hides MaintenanceWindowCallout if filterConsumers does not match the running maintenance window's category", async () => { - fetchActiveMaintenanceWindowsMock.mockResolvedValue([ - { ...RUNNING_MAINTENANCE_WINDOW_1, categoryIds: ['securitySolution'] }, - ]); - renderWithProviders(); - await expect( - screen.findByText('Rule notifications are stopped while maintenance windows are running.') - ).rejects.toThrow(); - expect(fetchActiveMaintenanceWindowsMock).toHaveBeenCalledTimes(1); - }); - it('renders Create rule button', async () => { renderWithProviders(); @@ -319,6 +296,7 @@ describe.skip('rules_list component empty', () => { describe('rules_list ', () => { let ruleTypeRegistry: jest.Mocked; let actionTypeRegistry: jest.Mocked>; + beforeEach(() => { (getIsExperimentalFeatureEnabled as jest.Mock).mockImplementation(() => false); loadRulesWithKueryFilter.mockResolvedValue({ @@ -1403,3 +1381,99 @@ describe('rules_list with show only capability', () => { }); }); }); + +describe('MaintenanceWindowsMock', () => { + beforeEach(() => { + fetchActiveMaintenanceWindowsMock.mockResolvedValue([]); + + loadRulesWithKueryFilter.mockResolvedValue({ + page: 1, + perPage: 10000, + total: 0, + data: [], + }); + + loadActionTypes.mockResolvedValue([ + { + id: 'test', + name: 'Test', + }, + { + id: 'test2', + name: 'Test2', + }, + ]); + + loadRuleTypes.mockResolvedValue([ruleTypeFromApi]); + loadAllActions.mockResolvedValue([]); + loadRuleAggregationsWithKueryFilter.mockResolvedValue({}); + loadRuleTags.mockResolvedValue({ + data: ruleTags, + page: 1, + perPage: 50, + total: 4, + }); + + const actionTypeRegistry = actionTypeRegistryMock.create(); + const ruleTypeRegistry = ruleTypeRegistryMock.create(); + + ruleTypeRegistry.list.mockReturnValue([ruleType]); + actionTypeRegistry.list.mockReturnValue([]); + useKibanaMock().services.application.capabilities = { + ...useKibanaMock().services.application.capabilities, + [MAINTENANCE_WINDOW_FEATURE_ID]: { + save: true, + show: true, + }, + }; + useKibanaMock().services.ruleTypeRegistry = ruleTypeRegistry; + useKibanaMock().services.actionTypeRegistry = actionTypeRegistry; + }); + + afterEach(() => { + jest.clearAllMocks(); + queryClient.clear(); + cleanup(); + }); + + it('renders MaintenanceWindowCallout if one exists', async () => { + fetchActiveMaintenanceWindowsMock.mockResolvedValue([RUNNING_MAINTENANCE_WINDOW_1]); + renderWithProviders(); + + expect( + await screen.findByText('One or more maintenance windows are running') + ).toBeInTheDocument(); + + expect(fetchActiveMaintenanceWindowsMock).toHaveBeenCalledTimes(1); + }); + + it('hides MaintenanceWindowCallout if the category ID is not supported', async () => { + loadRuleTypes.mockResolvedValue([{ ...ruleTypeFromApi, category: 'observability' }]); + fetchActiveMaintenanceWindowsMock.mockResolvedValue([ + { ...RUNNING_MAINTENANCE_WINDOW_1, categoryIds: ['securitySolution'] }, + ]); + + renderWithProviders(); + + await expect( + screen.findByText('Rule notifications are stopped while maintenance windows are running.') + ).rejects.toThrow(); + + expect(fetchActiveMaintenanceWindowsMock).toHaveBeenCalledTimes(1); + }); + + it('shows MaintenanceWindowCallout for a specific category', async () => { + loadRuleTypes.mockResolvedValue([{ ...ruleTypeFromApi, category: 'observability' }]); + fetchActiveMaintenanceWindowsMock.mockResolvedValue([ + { ...RUNNING_MAINTENANCE_WINDOW_1, categoryIds: ['securitySolution', 'observability'] }, + ]); + + renderWithProviders(); + + expect( + await screen.findByText('A maintenance window is running for Observability rules') + ).toBeInTheDocument(); + + expect(fetchActiveMaintenanceWindowsMock).toHaveBeenCalledTimes(1); + }); +}); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rules_list.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rules_list.tsx index d98aa2c5dec67..c0b56fa224519 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rules_list.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rules_list.tsx @@ -117,7 +117,8 @@ const RuleAdd = lazy(() => import('../../rule_form/rule_add')); const RuleEdit = lazy(() => import('../../rule_form/rule_edit')); export interface RulesListProps { - filterConsumers?: string[]; + ruleTypeIds?: string[]; + consumers?: string[]; filteredRuleTypes?: string[]; lastResponseFilter?: string[]; lastRunOutcomeFilter?: string[]; @@ -159,7 +160,8 @@ const initialPercentileOptions = Object.values(Percentiles).map((percentile) => const EMPTY_ARRAY: string[] = []; export const RulesList = ({ - filterConsumers, + ruleTypeIds, + consumers, filteredRuleTypes = EMPTY_ARRAY, lastResponseFilter, lastRunOutcomeFilter, @@ -272,6 +274,7 @@ export const RulesList = ({ const rulesTypesFilter = isEmpty(filters.types) ? authorizedRuleTypes.map((art) => art.id) : filters.types; + const hasDefaultRuleTypesFiltersOn = isEmpty(filters.types); const computedFilter = useMemo(() => { @@ -285,7 +288,8 @@ export const RulesList = ({ // Fetch rules const { rulesState, loadRules, hasData, lastUpdate } = useLoadRulesQuery({ - filterConsumers, + ruleTypeIds, + consumers, filters: computedFilter, hasDefaultRuleTypesFiltersOn, page, @@ -298,7 +302,8 @@ export const RulesList = ({ // Fetch status aggregation const { loadRuleAggregations, rulesStatusesTotal, rulesLastRunOutcomesTotal } = useLoadRuleAggregationsQuery({ - filterConsumers, + ruleTypeIds, + consumers, filters: computedFilter, enabled: canLoadRules, refresh, @@ -766,12 +771,16 @@ export const RulesList = ({ const numberRulesToDelete = rulesToBulkEdit.length || numberOfSelectedItems; + const allRuleCategories = getAllUniqueRuleTypeCategories( + Array.from(ruleTypesState.data.values()) + ); + return ( <> {showSearchBar && !isEmpty(filters.ruleParams) ? ( ) : null} - + ids.includes(rule.id)); } + +const getAllUniqueRuleTypeCategories = (ruleTypes: RuleType[]) => { + const categories = new Set(ruleTypes.map((ruleType) => ruleType.category)); + + return Array.from(categories).filter(Boolean); +}; diff --git a/x-pack/plugins/triggers_actions_ui/public/types.ts b/x-pack/plugins/triggers_actions_ui/public/types.ts index a592b19ae8a79..d6ea582058c1e 100644 --- a/x-pack/plugins/triggers_actions_ui/public/types.ts +++ b/x-pack/plugins/triggers_actions_ui/public/types.ts @@ -26,7 +26,7 @@ import type { RenderCellValue, EuiDataGridCellPopoverElementProps, } from '@elastic/eui'; -import type { RuleCreationValidConsumer, ValidFeatureId } from '@kbn/rule-data-utils'; +import type { RuleCreationValidConsumer } from '@kbn/rule-data-utils'; import { EuiDataGridColumn, EuiDataGridControlColumn, EuiDataGridSorting } from '@elastic/eui'; import { HttpSetup } from '@kbn/core/public'; import { KueryNode } from '@kbn/es-query'; @@ -490,7 +490,7 @@ export type AlertsTableProps = { * Enable when rows may have variable heights (disables virtualization) */ dynamicRowHeight?: boolean; - featureIds?: ValidFeatureId[]; + ruleTypeIds?: string[]; pageIndex: number; pageSize: number; sort: SortCombinations[]; diff --git a/x-pack/plugins/triggers_actions_ui/server/plugin.ts b/x-pack/plugins/triggers_actions_ui/server/plugin.ts index b5cafb0571482..2263af73dbdc7 100644 --- a/x-pack/plugins/triggers_actions_ui/server/plugin.ts +++ b/x-pack/plugins/triggers_actions_ui/server/plugin.ts @@ -6,10 +6,7 @@ */ import { Logger, Plugin, CoreSetup, PluginInitializerContext } from '@kbn/core/server'; -import { - PluginSetupContract as AlertingPluginSetup, - PluginStartContract as AlertingPluginStart, -} from '@kbn/alerting-plugin/server'; +import { AlertingServerSetup, AlertingServerStart } from '@kbn/alerting-plugin/server'; import { EncryptedSavedObjectsPluginSetup } from '@kbn/encrypted-saved-objects-plugin/server'; import { getService, register as registerDataService } from './data'; import { createHealthRoute, createConfigRoute } from './routes'; @@ -21,11 +18,11 @@ export interface PluginStartContract { interface PluginsSetup { encryptedSavedObjects?: EncryptedSavedObjectsPluginSetup; - alerting: AlertingPluginSetup; + alerting: AlertingServerSetup; } interface TriggersActionsPluginStart { - alerting: AlertingPluginStart; + alerting: AlertingServerStart; } export class TriggersActionsPlugin implements Plugin { diff --git a/x-pack/plugins/triggers_actions_ui/server/routes/config.test.ts b/x-pack/plugins/triggers_actions_ui/server/routes/config.test.ts index 010a01b46fbdb..e96d5837b1138 100644 --- a/x-pack/plugins/triggers_actions_ui/server/routes/config.test.ts +++ b/x-pack/plugins/triggers_actions_ui/server/routes/config.test.ts @@ -45,7 +45,7 @@ describe('createConfigRoute', () => { const logger = loggingSystemMock.create().get(); const mockRulesClient = rulesClientMock.create(); - mockRulesClient.listRuleTypes.mockResolvedValueOnce(new Set(ruleTypes)); + mockRulesClient.listRuleTypes.mockResolvedValueOnce(ruleTypes); createConfigRoute({ logger, router, @@ -80,7 +80,7 @@ describe('createConfigRoute', () => { const logger = loggingSystemMock.create().get(); const mockRulesClient = rulesClientMock.create(); - mockRulesClient.listRuleTypes.mockResolvedValueOnce(new Set()); + mockRulesClient.listRuleTypes.mockResolvedValueOnce([]); createConfigRoute({ logger, router, diff --git a/x-pack/plugins/upgrade_assistant/README.md b/x-pack/plugins/upgrade_assistant/README.md index 145f49baf0323..39bebc15e44b1 100644 --- a/x-pack/plugins/upgrade_assistant/README.md +++ b/x-pack/plugins/upgrade_assistant/README.md @@ -15,6 +15,7 @@ Some features of the UA are only needed when upgrading to a new major version. T * ML Snapshots (`featureSet.mlSnapshots`): Machine learning Upgrade mode can be toggled from outside Kibana, the purpose of this feature guard is to hide all ML related deprecations from the end user until the next major upgrade. When we want to enable ML model snapshot deprecation warnings again we need to change the constant `MachineLearningField.MIN_CHECKED_SUPPORTED_SNAPSHOT_VERSION` to something higher than 7.0.0 in the Elasticsearch code. * Migrating system indices (`featureSet.migrateSystemIndices`): Migrating system indices should only be enabled for major version upgrades. This config hides the second step from the UA UI for migrating system indices. +* Reindex Data Streams (`featureSet.migrateDataStreams`): Migrating deprecated Data streams should only be enabled for major version upgrades. The purpose of this feature guard is to hide all data streams related deprecations from the end user until the next major upgrade. * Reindex corrective actions (`featureSet.reindexCorrectiveActions`): Deprecations with reindexing corrective actions are only enabled for major version upgrades. Currently, the reindex actions include some logic that is specific to the [8.0 upgrade](https://github.com/elastic/kibana/blob/main/x-pack/plugins/upgrade_assistant/server/lib/reindexing/index_settings.ts). End users could get into a bad situation if this is enabled before this logic is fixed. ## Deprecations @@ -28,7 +29,7 @@ These surface runtime deprecations, e.g. a Painless script that uses a deprecate request to a deprecated API. These are also generally surfaced as deprecation headers within the response. Even if the cluster state is good, app maintainers need to watch the logs in case deprecations are discovered as data is migrated. Starting in 7.x, deprecation logs can be written to a file or a data stream ([#58924](https://github.com/elastic/elasticsearch/pull/58924)). When the data stream exists, the Upgrade Assistant provides a way to analyze the logs through Observability or Discover ([#106521](https://github.com/elastic/kibana/pull/106521)). -* [**Kibana deprecations API.**](https://github.com/elastic/kibana/blob/main/src/core/server/deprecations/README.mdx) This is information about deprecated features and configs in Kibana. These deprecations are only communicated to the user if the deployment is using these features. Kibana engineers are responsible for adding deprecations to the deprecations API for their respective team. +* [**Kibana deprecations API.**](https://github.com/elastic/kibana/blob/main/src/core/server/docs/kib_core_deprecations_service.mdx) This is information about deprecated features and configs in Kibana. These deprecations are only communicated to the user if the deployment is using these features. Kibana engineers are responsible for adding deprecations to the deprecations API for their respective team. ### Fixing problems diff --git a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/helpers/app_context.mock.ts b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/helpers/app_context.mock.ts index 31fd69648418f..010790e3c5e15 100644 --- a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/helpers/app_context.mock.ts +++ b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/helpers/app_context.mock.ts @@ -80,6 +80,7 @@ export const getAppContextMock = (kibanaVersion: SemVer) => ({ featureSet: { mlSnapshots: true, migrateSystemIndices: true, + migrateDataStreams: true, reindexCorrectiveActions: true, }, kibanaVersionInfo: { diff --git a/x-pack/plugins/upgrade_assistant/common/types.ts b/x-pack/plugins/upgrade_assistant/common/types.ts index 6d7166569d8db..781e4865ee568 100644 --- a/x-pack/plugins/upgrade_assistant/common/types.ts +++ b/x-pack/plugins/upgrade_assistant/common/types.ts @@ -215,7 +215,7 @@ export interface HealthIndicatorAction { export interface EnrichedDeprecationInfo extends Omit { - type: keyof estypes.MigrationDeprecationsResponse | 'health_indicator'; + type: keyof estypes.MigrationDeprecationsResponse | 'health_indicator' | 'data_streams'; isCritical: boolean; status?: estypes.HealthReportIndicatorHealthStatus; index?: string; @@ -296,4 +296,5 @@ export interface FeatureSet { migrateSystemIndices: boolean; mlSnapshots: boolean; reindexCorrectiveActions: boolean; + migrateDataStreams: boolean; } diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/constants.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/constants.tsx index 12babe0b9b468..d0743230f909c 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/constants.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/constants.tsx @@ -6,8 +6,9 @@ */ import { i18n } from '@kbn/i18n'; +import { EnrichedDeprecationInfo } from '../../../common/types'; -export const DEPRECATION_TYPE_MAP = { +export const DEPRECATION_TYPE_MAP: Record = { cluster_settings: i18n.translate( 'xpack.upgradeAssistant.esDeprecations.clusterDeprecationTypeLabel', { @@ -32,6 +33,9 @@ export const DEPRECATION_TYPE_MAP = { defaultMessage: 'Health Indicator', } ), + data_streams: i18n.translate('xpack.upgradeAssistant.esDeprecations.dataStreamsTypeLabel', { + defaultMessage: 'Data Stream', + }), }; export const PAGINATION_CONFIG = { diff --git a/x-pack/plugins/upgrade_assistant/server/config.ts b/x-pack/plugins/upgrade_assistant/server/config.ts index e603780be785b..ecf168c297c96 100644 --- a/x-pack/plugins/upgrade_assistant/server/config.ts +++ b/x-pack/plugins/upgrade_assistant/server/config.ts @@ -47,6 +47,11 @@ const configSchema = schema.object({ * End users could get into a bad situation if this is enabled before this logic is fixed. */ reindexCorrectiveActions: schema.boolean({ defaultValue: false }), + /** + * Migrating deprecated data streams should only be enabled for major version upgrades. + * Currently this is manually set to `true` on every `x.last` version. + */ + migrateDataStreams: schema.boolean({ defaultValue: false }), }), /** * This config allows to hide the UI without disabling the plugin. diff --git a/x-pack/plugins/upgrade_assistant/server/lib/__fixtures__/es_deprecations.ts b/x-pack/plugins/upgrade_assistant/server/lib/__fixtures__/es_deprecations.ts new file mode 100644 index 0000000000000..4ced006a9bb43 --- /dev/null +++ b/x-pack/plugins/upgrade_assistant/server/lib/__fixtures__/es_deprecations.ts @@ -0,0 +1,77 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export const getMockEsDeprecations = () => { + return { + cluster_settings: [], + node_settings: [], + ml_settings: [], + index_settings: {}, + data_streams: {}, + }; +}; + +export const getMockMlSettingsDeprecations = () => { + return { + ml_settings: [ + { + level: 'warning', + message: 'Datafeed [deprecation-datafeed] uses deprecated query options', + url: 'https://www.elastic.co/guide/en/elasticsearch/reference/master/breaking-changes-7.0.html#breaking_70_search_changes', + details: + '[Deprecated field [use_dis_max] used, replaced by [Set [tie_breaker] to 1 instead]]', + // @ts-ignore + resolve_during_rolling_upgrade: false, + }, + { + level: 'critical', + message: + 'model snapshot [1] for job [deprecation_check_job] needs to be deleted or upgraded', + url: '', + details: 'details', + // @ts-ignore + _meta: { snapshot_id: '1', job_id: 'deprecation_check_job' }, + // @ts-ignore + resolve_during_rolling_upgrade: false, + }, + ], + }; +}; + +export const getMockDataStreamDeprecations = () => { + return { + data_streams: { + 'my-v7-data-stream': [ + { + level: 'critical', + message: 'Old data stream with a compatibility version < 8.0', + url: 'https://www.elastic.co/guide/en/elasticsearch/reference/master/breaking-changes-9.0.html', + details: + 'This data stream has backing indices that were created before Elasticsearch 8.0.0', + resolve_during_rolling_upgrade: false, + _meta: { + backing_indices: { + count: 52, + need_upgrading: { + count: 37, + searchable_snapshot: { + count: 23, + fully_mounted: { + count: 7, + }, + partially_mounted: { + count: 16, + }, + }, + }, + }, + }, + }, + ], + }, + }; +}; diff --git a/x-pack/plugins/upgrade_assistant/server/lib/__fixtures__/fake_deprecations.json b/x-pack/plugins/upgrade_assistant/server/lib/__fixtures__/fake_deprecations.json index a83d8d231d142..f53e4176096cc 100644 --- a/x-pack/plugins/upgrade_assistant/server/lib/__fixtures__/fake_deprecations.json +++ b/x-pack/plugins/upgrade_assistant/server/lib/__fixtures__/fake_deprecations.json @@ -148,5 +148,31 @@ "resolve_during_rolling_upgrade": false } ] + }, + "data_streams": { + "my-v7-data-stream" : [{ + "level" : "critical", + "message" : "Old data stream with a compatibility version < 8.0", + "url" : "https://www.elastic.co/guide/en/elasticsearch/reference/master/breaking-changes-9.0.html", + "details" : "This data stream has backing indices that were created before Elasticsearch 8.0.0", + "resolve_during_rolling_upgrade" : false, + "_meta": { + "backing_indices": { + "count": 52, + "need_upgrading": { + "count": 37, + "searchable_snapshot": { + "count": 23, + "fully_mounted": { + "count": 7 + }, + "partially_mounted": { + "count": 16 + } + } + } + } + } + }] } } diff --git a/x-pack/plugins/upgrade_assistant/server/lib/es_deprecations_status.ts b/x-pack/plugins/upgrade_assistant/server/lib/es_deprecations_status.ts deleted file mode 100644 index 05fc4f666f7ba..0000000000000 --- a/x-pack/plugins/upgrade_assistant/server/lib/es_deprecations_status.ts +++ /dev/null @@ -1,340 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; -import { IScopedClusterClient } from '@kbn/core/server'; -import { i18n } from '@kbn/i18n'; -import { EnrichedDeprecationInfo, ESUpgradeStatus, FeatureSet } from '../../common/types'; -import { esIndicesStateCheck } from './es_indices_state_check'; -import { - getESSystemIndicesMigrationStatus, - convertFeaturesToIndicesArray, -} from './es_system_indices_migration'; - -export function getShardCapacityDeprecationInfo({ - symptom, - details, -}: { - details: any; - symptom: any; -}) { - // When we dont have a details field for our indicator, we can only report - // the symptom to the user given that's the only information about the deprecation - // we have. - if (!details) { - return { - details: symptom, - message: symptom, - url: null, - resolveDuringUpgrade: false, - }; - } - - const causes = []; - if (details.indices_with_readonly_block > 0) { - causes.push( - i18n.translate( - 'xpack.upgradeAssistant.esDeprecationsStatus.indicesWithReadonlyBlockCauseMessage', - { - defaultMessage: - 'The number of indices the system enforced a read-only index block (`index.blocks.read_only_allow_delete`) on because the cluster is running out of space.', - } - ) - ); - } - - if (details.nodes_over_high_watermark > 0) { - causes.push( - i18n.translate( - 'xpack.upgradeAssistant.esDeprecationsStatus.nodesOverHighWatermarkCauseMessage', - { - defaultMessage: - 'The number of nodes that are running low on disk and it is likely that they will run out of space. Their disk usage has tripped the <>.', - ignoreTag: true, - } - ) - ); - } - - if (details.nodes_over_flood_stage_watermark > 0) { - causes.push( - i18n.translate( - 'xpack.upgradeAssistant.esDeprecationsStatus.nodesOverFloodStageWatermarkCauseMessage', - { - defaultMessage: - 'The number of nodes that have run out of disk. Their disk usage has tripped the <>.', - ignoreTag: true, - } - ) - ); - } - - return { - details: symptom, - message: symptom, - url: null, - resolveDuringUpgrade: false, - correctiveAction: { - type: 'healthIndicator', - impacts: details, - cause: causes.join('\n'), - }, - }; -} - -export async function getHealthIndicators( - dataClient: IScopedClusterClient -): Promise { - const healthIndicators = await dataClient.asCurrentUser.healthReport(); - const isStatusNotGreen = (indicator?: estypes.HealthReportBaseIndicator): boolean => { - return !!(indicator?.status && indicator?.status !== 'green'); - }; - - // Temporarily ignoring due to untyped ES indicators - // types will be available during 8.9.0 - // @ts-ignore - return [ - ...[ - // @ts-ignore - healthIndicators.indicators.shards_capacity as estypes.HealthReportBaseIndicator, - ] - .filter(isStatusNotGreen) - .flatMap(({ status, symptom, impacts, diagnosis }) => { - // eslint-disable-next-line @typescript-eslint/naming-convention - return (diagnosis || []).map(({ cause, action, help_url }) => ({ - type: 'health_indicator', - details: symptom, - message: cause, - url: help_url, - isCritical: status === 'red', - resolveDuringUpgrade: false, - correctiveAction: { type: 'healthIndicator', cause, action, impacts }, - })); - }), - ...[healthIndicators.indicators.disk as estypes.HealthReportDiskIndicator] - .filter(isStatusNotGreen) - .flatMap(({ status, symptom, details }) => { - return { - type: 'health_indicator', - isCritical: status === 'red', - ...getShardCapacityDeprecationInfo({ symptom, details }), - }; - }), - ]; -} - -export async function getESUpgradeStatus( - dataClient: IScopedClusterClient, - featureSet: FeatureSet -): Promise { - const getCombinedDeprecations = async () => { - const healthIndicators = await getHealthIndicators(dataClient); - const deprecations = await dataClient.asCurrentUser.migration.deprecations(); - const indices = await getCombinedIndexInfos(deprecations, dataClient); - const systemIndices = await getESSystemIndicesMigrationStatus(dataClient.asCurrentUser); - const systemIndicesList = convertFeaturesToIndicesArray(systemIndices.features); - - const enrichedDeprecations = Object.keys(deprecations).reduce( - (combinedDeprecations, deprecationType) => { - if (deprecationType === 'index_settings') { - // We need to exclude all index related deprecations for system indices since - // they are resolved separately through the system indices upgrade section in - // the Overview page. - const withoutSystemIndices = indices.filter( - (index) => !systemIndicesList.includes(index.index!) - ); - - combinedDeprecations = combinedDeprecations.concat(withoutSystemIndices); - } else { - const deprecationsByType = deprecations[ - deprecationType as keyof estypes.MigrationDeprecationsResponse - ] as estypes.MigrationDeprecationsDeprecation[]; - - const enrichedDeprecationInfo = deprecationsByType - .map( - ({ - details, - level, - message, - url, - // @ts-expect-error @elastic/elasticsearch _meta not available yet in MigrationDeprecationInfoResponse - _meta: metadata, - // @ts-expect-error @elastic/elasticsearch resolve_during_rolling_upgrade not available yet in MigrationDeprecationInfoResponse - resolve_during_rolling_upgrade: resolveDuringUpgrade, - }) => { - return { - details, - message, - url, - type: deprecationType as keyof estypes.MigrationDeprecationsResponse, - isCritical: level === 'critical', - resolveDuringUpgrade, - correctiveAction: getCorrectiveAction(message, metadata), - }; - } - ) - .filter(({ correctiveAction, type }) => { - /** - * This disables showing the ML deprecations in the UA if `featureSet.mlSnapshots` - * is set to `false`. - * - * This config should be set to true only on the `x.last` versions, or when - * the constant `MachineLearningField.MIN_CHECKED_SUPPORTED_SNAPSHOT_VERSION` - * is incremented to something higher than 7.0.0 in the Elasticsearch code. - */ - if (!featureSet.mlSnapshots) { - if (type === 'ml_settings' || correctiveAction?.type === 'mlSnapshot') { - return false; - } - } - - /** - * This disables showing the reindexing deprecations in the UA if - * `featureSet.reindexCorrectiveActions` is set to `false`. - */ - if (!featureSet.reindexCorrectiveActions && correctiveAction?.type === 'reindex') { - return false; - } - - return true; - }); - - combinedDeprecations = combinedDeprecations.concat(enrichedDeprecationInfo); - } - - return combinedDeprecations; - }, - [] as EnrichedDeprecationInfo[] - ); - - const enrichedHealthIndicators = healthIndicators.filter(({ status }) => { - return status !== 'green'; - }) as EnrichedDeprecationInfo[]; - - return [...enrichedHealthIndicators, ...enrichedDeprecations]; - }; - - const combinedDeprecations = await getCombinedDeprecations(); - const criticalWarnings = combinedDeprecations.filter(({ isCritical }) => isCritical === true); - - return { - totalCriticalDeprecations: criticalWarnings.length, - deprecations: combinedDeprecations, - }; -} - -// Reformats the index deprecations to an array of deprecation warnings extended with an index field. -const getCombinedIndexInfos = async ( - deprecations: estypes.MigrationDeprecationsResponse, - dataClient: IScopedClusterClient -) => { - const indices = Object.keys(deprecations.index_settings).reduce( - (indexDeprecations, indexName) => { - return indexDeprecations.concat( - deprecations.index_settings[indexName].map( - ({ - details, - message, - url, - level, - // @ts-expect-error @elastic/elasticsearch _meta not available yet in MigrationDeprecationInfoResponse - _meta: metadata, - // @ts-expect-error @elastic/elasticsearch resolve_during_rolling_upgrade not available yet in MigrationDeprecationInfoResponse - resolve_during_rolling_upgrade: resolveDuringUpgrade, - }) => - ({ - details, - message, - url, - index: indexName, - type: 'index_settings', - isCritical: level === 'critical', - correctiveAction: getCorrectiveAction(message, metadata, indexName), - resolveDuringUpgrade, - } as EnrichedDeprecationInfo) - ) - ); - }, - [] as EnrichedDeprecationInfo[] - ); - - const indexNames = indices.map(({ index }) => index!); - - // If we have found deprecation information for index/indices - // check whether the index is open or closed. - if (indexNames.length) { - const indexStates = await esIndicesStateCheck(dataClient.asCurrentUser, indexNames); - - indices.forEach((indexData) => { - if (indexData.correctiveAction?.type === 'reindex') { - indexData.correctiveAction.blockerForReindexing = - indexStates[indexData.index!] === 'closed' ? 'index-closed' : undefined; - } - }); - } - return indices as EnrichedDeprecationInfo[]; -}; - -interface Action { - action_type: 'remove_settings'; - objects: string[]; -} - -interface Actions { - actions: Action[]; -} - -type EsMetadata = Actions & { - [key: string]: string; -}; - -const getCorrectiveAction = ( - message: string, - metadata: EsMetadata, - indexName?: string -): EnrichedDeprecationInfo['correctiveAction'] => { - const indexSettingDeprecation = metadata?.actions?.find( - (action) => action.action_type === 'remove_settings' && indexName - ); - const clusterSettingDeprecation = metadata?.actions?.find( - (action) => action.action_type === 'remove_settings' && typeof indexName === 'undefined' - ); - const requiresReindexAction = /Index created before/.test(message); - const requiresIndexSettingsAction = Boolean(indexSettingDeprecation); - const requiresClusterSettingsAction = Boolean(clusterSettingDeprecation); - const requiresMlAction = /[Mm]odel snapshot/.test(message); - - if (requiresReindexAction) { - return { - type: 'reindex', - }; - } - - if (requiresIndexSettingsAction) { - return { - type: 'indexSetting', - deprecatedSettings: indexSettingDeprecation!.objects, - }; - } - - if (requiresClusterSettingsAction) { - return { - type: 'clusterSetting', - deprecatedSettings: clusterSettingDeprecation!.objects, - }; - } - - if (requiresMlAction) { - const { snapshot_id: snapshotId, job_id: jobId } = metadata!; - - return { - type: 'mlSnapshot', - snapshotId, - jobId, - }; - } -}; diff --git a/x-pack/plugins/upgrade_assistant/server/lib/__snapshots__/es_deprecations_status.test.ts.snap b/x-pack/plugins/upgrade_assistant/server/lib/es_deprecations_status/__snapshots__/index.test.ts.snap similarity index 92% rename from x-pack/plugins/upgrade_assistant/server/lib/__snapshots__/es_deprecations_status.test.ts.snap rename to x-pack/plugins/upgrade_assistant/server/lib/es_deprecations_status/__snapshots__/index.test.ts.snap index de0154037f9ba..b0d5d99a37497 100644 --- a/x-pack/plugins/upgrade_assistant/server/lib/__snapshots__/es_deprecations_status.test.ts.snap +++ b/x-pack/plugins/upgrade_assistant/server/lib/es_deprecations_status/__snapshots__/index.test.ts.snap @@ -6,6 +6,7 @@ Object { Object { "correctiveAction": undefined, "details": "templates using \`template\` field: security_audit_log,watches,.monitoring-alerts,triggered_watches,.ml-anomalies-,.ml-notifications,.ml-meta,.monitoring-kibana,.monitoring-es,.monitoring-logstash,.watch-history-6,.ml-state,security-index-template", + "index": undefined, "isCritical": false, "message": "Template patterns are no longer using \`template\` field, but \`index_patterns\` instead", "resolveDuringUpgrade": false, @@ -15,6 +16,7 @@ Object { Object { "correctiveAction": undefined, "details": "{.monitoring-logstash=[Coercion of boolean fields], .monitoring-es=[Coercion of boolean fields], .ml-anomalies-=[Coercion of boolean fields], .watch-history-6=[Coercion of boolean fields], .monitoring-kibana=[Coercion of boolean fields], security-index-template=[Coercion of boolean fields]}", + "index": undefined, "isCritical": false, "message": "one or more templates use deprecated mapping settings", "resolveDuringUpgrade": false, @@ -24,6 +26,7 @@ Object { Object { "correctiveAction": undefined, "details": "[Deprecated field [use_dis_max] used, replaced by [Set [tie_breaker] to 1 instead]]", + "index": undefined, "isCritical": false, "message": "Datafeed [deprecation-datafeed] uses deprecated query options", "resolveDuringUpgrade": false, @@ -37,6 +40,7 @@ Object { "type": "mlSnapshot", }, "details": "details", + "index": undefined, "isCritical": true, "message": "model snapshot [1] for job [deprecation_check_job] needs to be deleted or upgraded", "resolveDuringUpgrade": false, @@ -46,6 +50,7 @@ Object { Object { "correctiveAction": undefined, "details": "This node thing is wrong", + "index": undefined, "isCritical": true, "message": "A node-level issue", "resolveDuringUpgrade": true, @@ -153,7 +158,17 @@ Object { "type": "index_settings", "url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_mappings_changes.html#_coercion_of_boolean_fields", }, + Object { + "correctiveAction": undefined, + "details": "This data stream has backing indices that were created before Elasticsearch 8.0.0", + "index": "my-v7-data-stream", + "isCritical": true, + "message": "Old data stream with a compatibility version < 8.0", + "resolveDuringUpgrade": false, + "type": "data_streams", + "url": "https://www.elastic.co/guide/en/elasticsearch/reference/master/breaking-changes-9.0.html", + }, ], - "totalCriticalDeprecations": 4, + "totalCriticalDeprecations": 5, } `; diff --git a/x-pack/plugins/upgrade_assistant/server/lib/es_deprecations_status/get_corrective_actions.ts b/x-pack/plugins/upgrade_assistant/server/lib/es_deprecations_status/get_corrective_actions.ts new file mode 100644 index 0000000000000..be696acb18095 --- /dev/null +++ b/x-pack/plugins/upgrade_assistant/server/lib/es_deprecations_status/get_corrective_actions.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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { EnrichedDeprecationInfo } from '../../../common/types'; + +interface Action { + action_type: 'remove_settings'; + objects: string[]; +} + +interface Actions { + actions: Action[]; +} + +type EsMetadata = Actions & { + [key: string]: string; +}; + +export const getCorrectiveAction = ( + message: string, + metadata: EsMetadata, + indexName?: string +): EnrichedDeprecationInfo['correctiveAction'] => { + const indexSettingDeprecation = metadata?.actions?.find( + (action) => action.action_type === 'remove_settings' && indexName + ); + const clusterSettingDeprecation = metadata?.actions?.find( + (action) => action.action_type === 'remove_settings' && typeof indexName === 'undefined' + ); + const requiresReindexAction = /Index created before/.test(message); + const requiresIndexSettingsAction = Boolean(indexSettingDeprecation); + const requiresClusterSettingsAction = Boolean(clusterSettingDeprecation); + const requiresMlAction = /[Mm]odel snapshot/.test(message); + + if (requiresReindexAction) { + return { + type: 'reindex', + }; + } + + if (requiresIndexSettingsAction) { + return { + type: 'indexSetting', + deprecatedSettings: indexSettingDeprecation!.objects, + }; + } + + if (requiresClusterSettingsAction) { + return { + type: 'clusterSetting', + deprecatedSettings: clusterSettingDeprecation!.objects, + }; + } + + if (requiresMlAction) { + const { snapshot_id: snapshotId, job_id: jobId } = metadata!; + + return { + type: 'mlSnapshot', + snapshotId, + jobId, + }; + } +}; diff --git a/x-pack/plugins/upgrade_assistant/server/lib/es_deprecations_status/health_indicators.test.ts b/x-pack/plugins/upgrade_assistant/server/lib/es_deprecations_status/health_indicators.test.ts new file mode 100644 index 0000000000000..3f16d0f9e94ce --- /dev/null +++ b/x-pack/plugins/upgrade_assistant/server/lib/es_deprecations_status/health_indicators.test.ts @@ -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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { elasticsearchServiceMock, ScopedClusterClientMock } from '@kbn/core/server/mocks'; +import { getHealthIndicators } from './health_indicators'; +import * as healthIndicatorsMock from '../__fixtures__/health_indicators'; + +describe('getHealthIndicators', () => { + let esClient: ScopedClusterClientMock; + beforeEach(() => { + esClient = elasticsearchServiceMock.createScopedClusterClient(); + }); + + it('returns empty array on green indicators', async () => { + esClient.asCurrentUser.healthReport.mockResponse({ + cluster_name: 'mock', + indicators: { + disk: healthIndicatorsMock.diskIndicatorGreen, + // @ts-ignore + shards_capacity: healthIndicatorsMock.shardCapacityIndicatorGreen, + }, + }); + + const result = await getHealthIndicators(esClient); + expect(result).toEqual([]); + }); + + it('returns unknown indicators', async () => { + esClient.asCurrentUser.healthReport.mockResponse({ + cluster_name: 'mock', + indicators: { + disk: healthIndicatorsMock.diskIndicatorUnknown, + // @ts-ignore + shards_capacity: healthIndicatorsMock.shardCapacityIndicatorGreen, + }, + }); + + const result = await getHealthIndicators(esClient); + expect(result[0]).toEqual( + expect.objectContaining({ + details: 'No disk usage data.', + }) + ); + }); + + it('returns unhealthy shards_capacity indicator', async () => { + esClient.asCurrentUser.healthReport.mockResponse({ + cluster_name: 'mock', + indicators: { + disk: healthIndicatorsMock.diskIndicatorGreen, + // @ts-ignore + shards_capacity: healthIndicatorsMock.shardCapacityIndicatorRed, + }, + }); + + const result = await getHealthIndicators(esClient); + expect(result).toMatchInlineSnapshot(` + Array [ + Object { + "correctiveAction": Object { + "action": "Increase the value of [cluster.max_shards_per_node] cluster setting or remove data indices to clear up resources.", + "cause": "Elasticsearch is about to reach the maximum number of shards it can host, based on your current settings.", + "impacts": Array [ + Object { + "description": "The cluster has too many used shards to be able to upgrade.", + "id": "elasticsearch:health:shards_capacity:impact:upgrade_blocked", + "impact_areas": "[Array]", + "severity": 1, + }, + Object { + "description": "The cluster is running low on room to add new shards. Adding data to new indices is at risk", + "id": "elasticsearch:health:shards_capacity:impact:creation_of_new_indices_blocked", + "impact_areas": "[Array]", + "severity": 1, + }, + ], + "type": "healthIndicator", + }, + "details": "Cluster is close to reaching the configured maximum number of shards for data nodes.", + "isCritical": true, + "message": "Elasticsearch is about to reach the maximum number of shards it can host, based on your current settings.", + "resolveDuringUpgrade": false, + "type": "health_indicator", + "url": "https://ela.st/fix-shards-capacity", + }, + ] + `); + }); + + it('returns unhealthy disk indicator', async () => { + esClient.asCurrentUser.healthReport.mockResponse({ + cluster_name: 'mock', + indicators: { + disk: healthIndicatorsMock.diskIndicatorRed, + // @ts-ignore + shards_capacity: healthIndicatorsMock.shardCapacityIndicatorGreen, + }, + }); + + const result = await getHealthIndicators(esClient); + expect(result).toMatchInlineSnapshot(` + Array [ + Object { + "correctiveAction": Object { + "cause": "The number of indices the system enforced a read-only index block (\`index.blocks.read_only_allow_delete\`) on because the cluster is running out of space. + The number of nodes that are running low on disk and it is likely that they will run out of space. Their disk usage has tripped the <>. + The number of nodes that have run out of disk. Their disk usage has tripped the <>.", + "impacts": Object { + "indices_with_readonly_block": 1, + "nodes_over_flood_stage_watermark": 1, + "nodes_over_high_watermark": 1, + "nodes_with_enough_disk_space": 1, + "nodes_with_unknown_disk_status": 1, + }, + "type": "healthIndicator", + }, + "details": "The cluster does not have enough available disk space.", + "isCritical": true, + "message": "The cluster does not have enough available disk space.", + "resolveDuringUpgrade": false, + "type": "health_indicator", + "url": null, + }, + ] + `); + }); +}); diff --git a/x-pack/plugins/upgrade_assistant/server/lib/es_deprecations_status/health_indicators.ts b/x-pack/plugins/upgrade_assistant/server/lib/es_deprecations_status/health_indicators.ts new file mode 100644 index 0000000000000..372582220659a --- /dev/null +++ b/x-pack/plugins/upgrade_assistant/server/lib/es_deprecations_status/health_indicators.ts @@ -0,0 +1,123 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; +import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; +import { IScopedClusterClient } from '@kbn/core/server'; +import { EnrichedDeprecationInfo } from '../../../common/types'; + +export async function getHealthIndicators( + dataClient: IScopedClusterClient +): Promise { + const healthIndicators = await dataClient.asCurrentUser.healthReport(); + const isStatusNotGreen = (indicator?: estypes.HealthReportBaseIndicator): boolean => { + return !!(indicator?.status && indicator?.status !== 'green'); + }; + + // Temporarily ignoring due to untyped ES indicators + // types will be available during 8.9.0 + // @ts-ignore + return [ + ...[ + // @ts-ignore + healthIndicators.indicators.shards_capacity as estypes.HealthReportBaseIndicator, + ] + .filter(isStatusNotGreen) + .flatMap(({ status, symptom, impacts, diagnosis }) => { + // eslint-disable-next-line @typescript-eslint/naming-convention + return (diagnosis || []).map(({ cause, action, help_url }) => ({ + type: 'health_indicator', + details: symptom, + message: cause, + url: help_url, + isCritical: status === 'red', + resolveDuringUpgrade: false, + correctiveAction: { type: 'healthIndicator', cause, action, impacts }, + })); + }), + ...[healthIndicators.indicators.disk as estypes.HealthReportDiskIndicator] + .filter(isStatusNotGreen) + .flatMap(({ status, symptom, details }) => { + return { + type: 'health_indicator', + isCritical: status === 'red', + ...getShardCapacityDeprecationInfo({ symptom, details }), + }; + }), + ]; +} + +export function getShardCapacityDeprecationInfo({ + symptom, + details, +}: { + details: any; + symptom: any; +}) { + // When we dont have a details field for our indicator, we can only report + // the symptom to the user given that's the only information about the deprecation + // we have. + if (!details) { + return { + details: symptom, + message: symptom, + url: null, + resolveDuringUpgrade: false, + }; + } + + const causes = []; + if (details.indices_with_readonly_block > 0) { + causes.push( + i18n.translate( + 'xpack.upgradeAssistant.esDeprecationsStatus.indicesWithReadonlyBlockCauseMessage', + { + defaultMessage: + 'The number of indices the system enforced a read-only index block (`index.blocks.read_only_allow_delete`) on because the cluster is running out of space.', + } + ) + ); + } + + if (details.nodes_over_high_watermark > 0) { + causes.push( + i18n.translate( + 'xpack.upgradeAssistant.esDeprecationsStatus.nodesOverHighWatermarkCauseMessage', + { + defaultMessage: + 'The number of nodes that are running low on disk and it is likely that they will run out of space. Their disk usage has tripped the <>.', + ignoreTag: true, + } + ) + ); + } + + if (details.nodes_over_flood_stage_watermark > 0) { + causes.push( + i18n.translate( + 'xpack.upgradeAssistant.esDeprecationsStatus.nodesOverFloodStageWatermarkCauseMessage', + { + defaultMessage: + 'The number of nodes that have run out of disk. Their disk usage has tripped the <>.', + ignoreTag: true, + } + ) + ); + } + + return { + details: symptom, + message: symptom, + url: null, + resolveDuringUpgrade: false, + correctiveAction: { + type: 'healthIndicator', + impacts: details, + cause: causes.join('\n'), + }, + }; +} diff --git a/x-pack/plugins/upgrade_assistant/server/lib/es_deprecations_status.test.ts b/x-pack/plugins/upgrade_assistant/server/lib/es_deprecations_status/index.test.ts similarity index 56% rename from x-pack/plugins/upgrade_assistant/server/lib/es_deprecations_status.test.ts rename to x-pack/plugins/upgrade_assistant/server/lib/es_deprecations_status/index.test.ts index 3a373cbffbfe7..c7a8c13993099 100644 --- a/x-pack/plugins/upgrade_assistant/server/lib/es_deprecations_status.test.ts +++ b/x-pack/plugins/upgrade_assistant/server/lib/es_deprecations_status/index.test.ts @@ -6,142 +6,22 @@ */ import _ from 'lodash'; -import { elasticsearchServiceMock, ScopedClusterClientMock } from '@kbn/core/server/mocks'; +import { elasticsearchServiceMock } from '@kbn/core/server/mocks'; import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; -import { getESUpgradeStatus, getHealthIndicators } from './es_deprecations_status'; -import fakeDeprecations from './__fixtures__/fake_deprecations.json'; -import * as healthIndicatorsMock from './__fixtures__/health_indicators'; - -import type { FeatureSet } from '../../common/types'; +import fakeDeprecations from '../__fixtures__/fake_deprecations.json'; +import * as healthIndicatorsMock from '../__fixtures__/health_indicators'; +import * as esMigrationsMock from '../__fixtures__/es_deprecations'; +import type { FeatureSet } from '../../../common/types'; +import { getESUpgradeStatus } from '.'; const fakeIndexNames = Object.keys(fakeDeprecations.index_settings); -describe('getHealthIndicators', () => { - let esClient: ScopedClusterClientMock; - beforeEach(() => { - esClient = elasticsearchServiceMock.createScopedClusterClient(); - }); - - it('returns empty array on green indicators', async () => { - esClient.asCurrentUser.healthReport.mockResponse({ - cluster_name: 'mock', - indicators: { - disk: healthIndicatorsMock.diskIndicatorGreen, - // @ts-ignore - shards_capacity: healthIndicatorsMock.shardCapacityIndicatorGreen, - }, - }); - - const result = await getHealthIndicators(esClient); - expect(result).toEqual([]); - }); - - it('returns unknown indicators', async () => { - esClient.asCurrentUser.healthReport.mockResponse({ - cluster_name: 'mock', - indicators: { - disk: healthIndicatorsMock.diskIndicatorUnknown, - // @ts-ignore - shards_capacity: healthIndicatorsMock.shardCapacityIndicatorGreen, - }, - }); - - const result = await getHealthIndicators(esClient); - expect(result[0]).toEqual( - expect.objectContaining({ - details: 'No disk usage data.', - }) - ); - }); - - it('returns unhealthy shards_capacity indicator', async () => { - esClient.asCurrentUser.healthReport.mockResponse({ - cluster_name: 'mock', - indicators: { - disk: healthIndicatorsMock.diskIndicatorGreen, - // @ts-ignore - shards_capacity: healthIndicatorsMock.shardCapacityIndicatorRed, - }, - }); - - const result = await getHealthIndicators(esClient); - expect(result).toMatchInlineSnapshot(` - Array [ - Object { - "correctiveAction": Object { - "action": "Increase the value of [cluster.max_shards_per_node] cluster setting or remove data indices to clear up resources.", - "cause": "Elasticsearch is about to reach the maximum number of shards it can host, based on your current settings.", - "impacts": Array [ - Object { - "description": "The cluster has too many used shards to be able to upgrade.", - "id": "elasticsearch:health:shards_capacity:impact:upgrade_blocked", - "impact_areas": "[Array]", - "severity": 1, - }, - Object { - "description": "The cluster is running low on room to add new shards. Adding data to new indices is at risk", - "id": "elasticsearch:health:shards_capacity:impact:creation_of_new_indices_blocked", - "impact_areas": "[Array]", - "severity": 1, - }, - ], - "type": "healthIndicator", - }, - "details": "Cluster is close to reaching the configured maximum number of shards for data nodes.", - "isCritical": true, - "message": "Elasticsearch is about to reach the maximum number of shards it can host, based on your current settings.", - "resolveDuringUpgrade": false, - "type": "health_indicator", - "url": "https://ela.st/fix-shards-capacity", - }, - ] - `); - }); - - it('returns unhealthy disk indicator', async () => { - esClient.asCurrentUser.healthReport.mockResponse({ - cluster_name: 'mock', - indicators: { - disk: healthIndicatorsMock.diskIndicatorRed, - // @ts-ignore - shards_capacity: healthIndicatorsMock.shardCapacityIndicatorGreen, - }, - }); - - const result = await getHealthIndicators(esClient); - expect(result).toMatchInlineSnapshot(` - Array [ - Object { - "correctiveAction": Object { - "cause": "The number of indices the system enforced a read-only index block (\`index.blocks.read_only_allow_delete\`) on because the cluster is running out of space. - The number of nodes that are running low on disk and it is likely that they will run out of space. Their disk usage has tripped the <>. - The number of nodes that have run out of disk. Their disk usage has tripped the <>.", - "impacts": Object { - "indices_with_readonly_block": 1, - "nodes_over_flood_stage_watermark": 1, - "nodes_over_high_watermark": 1, - "nodes_with_enough_disk_space": 1, - "nodes_with_unknown_disk_status": 1, - }, - "type": "healthIndicator", - }, - "details": "The cluster does not have enough available disk space.", - "isCritical": true, - "message": "The cluster does not have enough available disk space.", - "resolveDuringUpgrade": false, - "type": "health_indicator", - "url": null, - }, - ] - `); - }); -}); - describe('getESUpgradeStatus', () => { const featureSet: FeatureSet = { reindexCorrectiveActions: true, migrateSystemIndices: true, mlSnapshots: true, + migrateDataStreams: true, }; const resolvedIndices = { @@ -200,6 +80,7 @@ describe('getESUpgradeStatus', () => { node_settings: [], ml_settings: [], index_settings: {}, + data_streams: {}, }); await expect(getESUpgradeStatus(esClient, featureSet)).resolves.toHaveProperty( @@ -215,6 +96,7 @@ describe('getESUpgradeStatus', () => { node_settings: [], ml_settings: [], index_settings: {}, + data_streams: {}, }); await expect(getESUpgradeStatus(esClient, featureSet)).resolves.toHaveProperty( @@ -240,6 +122,7 @@ describe('getESUpgradeStatus', () => { }, ], }, + data_streams: {}, }); const upgradeStatus = await getESUpgradeStatus(esClient, featureSet); @@ -249,38 +132,44 @@ describe('getESUpgradeStatus', () => { }); it('filters out ml_settings if featureSet.mlSnapshots is set to false', async () => { - esClient.asCurrentUser.migration.deprecations.mockResponse({ - cluster_settings: [], - node_settings: [], - ml_settings: [ - { - level: 'warning', - message: 'Datafeed [deprecation-datafeed] uses deprecated query options', - url: 'https://www.elastic.co/guide/en/elasticsearch/reference/master/breaking-changes-7.0.html#breaking_70_search_changes', - details: - '[Deprecated field [use_dis_max] used, replaced by [Set [tie_breaker] to 1 instead]]', - // @ts-ignore - resolve_during_rolling_upgrade: false, - }, - { - level: 'critical', - message: - 'model snapshot [1] for job [deprecation_check_job] needs to be deleted or upgraded', - url: '', - details: 'details', - // @ts-ignore - _meta: { snapshot_id: '1', job_id: 'deprecation_check_job' }, - // @ts-ignore - resolve_during_rolling_upgrade: false, - }, - ], - index_settings: {}, + const mockResponse = { + ...esMigrationsMock.getMockEsDeprecations(), + ...esMigrationsMock.getMockMlSettingsDeprecations(), + }; + // @ts-ignore missing property definitions in ES resolve_during_rolling_upgrade and _meta + esClient.asCurrentUser.migration.deprecations.mockResponse(mockResponse); + + const enabledUpgradeStatus = await getESUpgradeStatus(esClient, { ...featureSet }); + expect(enabledUpgradeStatus.deprecations).toHaveLength(2); + expect(enabledUpgradeStatus.totalCriticalDeprecations).toBe(1); + + const disabledUpgradeStatus = await getESUpgradeStatus(esClient, { + ...featureSet, + mlSnapshots: false, }); - const upgradeStatus = await getESUpgradeStatus(esClient, { ...featureSet, mlSnapshots: false }); + expect(disabledUpgradeStatus.deprecations).toHaveLength(0); + expect(disabledUpgradeStatus.totalCriticalDeprecations).toBe(0); + }); - expect(upgradeStatus.deprecations).toHaveLength(0); - expect(upgradeStatus.totalCriticalDeprecations).toBe(0); + it('filters out data_streams if featureSet.migrateDataStreams is set to false', async () => { + const mockResponse = { + ...esMigrationsMock.getMockEsDeprecations(), + ...esMigrationsMock.getMockDataStreamDeprecations(), + }; + esClient.asCurrentUser.migration.deprecations.mockResponse(mockResponse); + + const enabledUpgradeStatus = await getESUpgradeStatus(esClient, { ...featureSet }); + expect(enabledUpgradeStatus.deprecations).toHaveLength(1); + expect(enabledUpgradeStatus.totalCriticalDeprecations).toBe(1); + + const disabledUpgradeStatus = await getESUpgradeStatus(esClient, { + ...featureSet, + migrateDataStreams: false, + }); + + expect(disabledUpgradeStatus.deprecations).toHaveLength(0); + expect(disabledUpgradeStatus.totalCriticalDeprecations).toBe(0); }); it('filters out reindex corrective actions if featureSet.reindexCorrectiveActions is set to false', async () => { @@ -306,6 +195,7 @@ describe('getESUpgradeStatus', () => { ], ml_settings: [], index_settings: {}, + data_streams: {}, }); const upgradeStatus = await getESUpgradeStatus(esClient, { @@ -332,6 +222,7 @@ describe('getESUpgradeStatus', () => { ], ml_settings: [], index_settings: {}, + data_streams: {}, }); esClient.asCurrentUser.healthReport.mockResponse({ @@ -380,6 +271,7 @@ describe('getESUpgradeStatus', () => { "type": "reindex", }, "details": "This index was created using version: 6.8.13", + "index": undefined, "isCritical": true, "message": "Index created before 7.0", "resolveDuringUpgrade": false, diff --git a/x-pack/plugins/upgrade_assistant/server/lib/es_deprecations_status/index.ts b/x-pack/plugins/upgrade_assistant/server/lib/es_deprecations_status/index.ts new file mode 100644 index 0000000000000..062c62660a538 --- /dev/null +++ b/x-pack/plugins/upgrade_assistant/server/lib/es_deprecations_status/index.ts @@ -0,0 +1,69 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { IScopedClusterClient } from '@kbn/core/server'; +import { EnrichedDeprecationInfo, ESUpgradeStatus, FeatureSet } from '../../../common/types'; +import { getEnrichedDeprecations } from './migrations'; +import { getHealthIndicators } from './health_indicators'; + +export async function getESUpgradeStatus( + dataClient: IScopedClusterClient, + featureSet: FeatureSet +): Promise { + const getCombinedDeprecations = async () => { + const healthIndicators = await getHealthIndicators(dataClient); + const enrichedDeprecations = await getEnrichedDeprecations(dataClient); + + const toggledMigrationsDeprecations = enrichedDeprecations.filter( + ({ type, correctiveAction }) => { + /** + * This disables showing the ML deprecations in the UA if `featureSet.mlSnapshots` + * is set to `false`. + * + * This config should be set to true only on the `x.last` versions, or when + * the constant `MachineLearningField.MIN_CHECKED_SUPPORTED_SNAPSHOT_VERSION` + * is incremented to something higher than 7.0.0 in the Elasticsearch code. + */ + if (type === 'ml_settings' || correctiveAction?.type === 'mlSnapshot') { + return featureSet.mlSnapshots; + } + + /** + * This disables showing the Data streams deprecations in the UA if + * `featureSet.migrateDataStreams` is set to `false`. + */ + if (type === 'data_streams') { + return !!featureSet.migrateDataStreams; + } + + /** + * This disables showing the reindexing deprecations in the UA if + * `featureSet.reindexCorrectiveActions` is set to `false`. + */ + if (correctiveAction?.type === 'reindex') { + return !!featureSet.reindexCorrectiveActions; + } + + return true; + } + ); + + const enrichedHealthIndicators = healthIndicators.filter(({ status }) => { + return status !== 'green'; + }) as EnrichedDeprecationInfo[]; + + return [...enrichedHealthIndicators, ...toggledMigrationsDeprecations]; + }; + + const combinedDeprecations = await getCombinedDeprecations(); + const criticalWarnings = combinedDeprecations.filter(({ isCritical }) => isCritical === true); + + return { + totalCriticalDeprecations: criticalWarnings.length, + deprecations: combinedDeprecations, + }; +} diff --git a/x-pack/plugins/upgrade_assistant/server/lib/es_deprecations_status/migrations.ts b/x-pack/plugins/upgrade_assistant/server/lib/es_deprecations_status/migrations.ts new file mode 100644 index 0000000000000..39d9984a64aa1 --- /dev/null +++ b/x-pack/plugins/upgrade_assistant/server/lib/es_deprecations_status/migrations.ts @@ -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 type { + MigrationDeprecationsResponse, + MigrationDeprecationsDeprecation, +} from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; +import { IScopedClusterClient } from '@kbn/core-elasticsearch-server'; +import _ from 'lodash'; +import { EnrichedDeprecationInfo } from '../../../common/types'; +import { + convertFeaturesToIndicesArray, + getESSystemIndicesMigrationStatus, +} from '../es_system_indices_migration'; +import { getCorrectiveAction } from './get_corrective_actions'; +import { esIndicesStateCheck } from '../es_indices_state_check'; + +/** + * Remove once the data_streams type is added to the `MigrationDeprecationsResponse` type + */ +interface EsDeprecations extends MigrationDeprecationsResponse { + data_streams: Record; +} + +const createBaseMigrationDeprecation = ( + migrationDeprecation: MigrationDeprecationsDeprecation, + { deprecationType, indexName }: { deprecationType: keyof EsDeprecations; indexName?: string } +) => { + const { + details, + message, + url, + level, + // @ts-expect-error @elastic/elasticsearch _meta not available yet in MigrationDeprecationInfoResponse + _meta: metadata, + // @ts-expect-error @elastic/elasticsearch resolve_during_rolling_upgrade not available yet in MigrationDeprecationInfoResponse + resolve_during_rolling_upgrade: resolveDuringUpgrade, + } = migrationDeprecation; + + return { + index: indexName, + type: deprecationType, + details, + message, + url, + isCritical: level === 'critical', + metadata, + resolveDuringUpgrade, + }; +}; + +const normalizeEsResponse = (migrationsResponse: EsDeprecations) => { + const indexSettingsMigrations = Object.entries(migrationsResponse.index_settings).flatMap( + ([indexName, migrationDeprecations]) => { + return migrationDeprecations.flatMap((migrationDeprecation) => + createBaseMigrationDeprecation(migrationDeprecation, { + indexName, + deprecationType: 'index_settings', + }) + ); + } + ); + + const dataStreamsMigrations = Object.entries(migrationsResponse.data_streams).flatMap( + ([indexName, dataStreamDeprecations]) => { + return dataStreamDeprecations.flatMap((depractionData) => + createBaseMigrationDeprecation(depractionData, { + indexName, + deprecationType: 'data_streams', + }) + ); + } + ); + + const mlSettingsMigrations = migrationsResponse.ml_settings.map((depractionData) => + createBaseMigrationDeprecation(depractionData, { deprecationType: 'ml_settings' }) + ); + const nodeSettingsMigrations = migrationsResponse.node_settings.map((depractionData) => + createBaseMigrationDeprecation(depractionData, { deprecationType: 'node_settings' }) + ); + + const clusterSettingsMigrations = migrationsResponse.cluster_settings.map((depractionData) => + createBaseMigrationDeprecation(depractionData, { deprecationType: 'cluster_settings' }) + ); + + return [ + ...clusterSettingsMigrations, + ...mlSettingsMigrations, + ...nodeSettingsMigrations, + ...indexSettingsMigrations, + ...dataStreamsMigrations, + ].flat(); +}; + +export const getEnrichedDeprecations = async ( + dataClient: IScopedClusterClient +): Promise => { + const deprecations = (await dataClient.asCurrentUser.migration.deprecations()) as EsDeprecations; + const systemIndices = await getESSystemIndicesMigrationStatus(dataClient.asCurrentUser); + + const systemIndicesList = convertFeaturesToIndicesArray(systemIndices.features); + + const indexSettingsIndexNames = Object.keys(deprecations.index_settings).map( + (indexName) => indexName! + ); + const indexSettingsIndexStates = indexSettingsIndexNames.length + ? await esIndicesStateCheck(dataClient.asCurrentUser, indexSettingsIndexNames) + : {}; + + return normalizeEsResponse(deprecations) + .filter((deprecation) => { + switch (deprecation.type) { + case 'index_settings': { + if (!deprecation.index) { + return false; + } + // filter out system indices + return !systemIndicesList.includes(deprecation.index); + } + case 'cluster_settings': + case 'ml_settings': + case 'node_settings': + case 'data_streams': { + return true; + } + default: { + // Throwing here to avoid allowing upgrades while we have unhandled deprecation types from ES + // That might cause the stack to fail to start after upgrade. + throw new Error(`Unknown ES deprecation type "${deprecation.type}"`); + } + } + }) + .map((deprecation) => { + const correctiveAction = getCorrectiveAction( + deprecation.message, + deprecation.metadata, + deprecation.index! + ); + + // If we have found deprecation information for index/indices + // check whether the index is open or closed. + if (deprecation.type === 'index_settings' && correctiveAction?.type === 'reindex') { + correctiveAction.blockerForReindexing = + indexSettingsIndexStates[deprecation.index!] === 'closed' ? 'index-closed' : undefined; + } + + const enrichedDeprecation = _.omit(deprecation, 'metadata'); + return { + ...enrichedDeprecation, + correctiveAction, + }; + }); +}; diff --git a/x-pack/plugins/upgrade_assistant/tsconfig.json b/x-pack/plugins/upgrade_assistant/tsconfig.json index 85fb886ca2af3..d78cafa21551b 100644 --- a/x-pack/plugins/upgrade_assistant/tsconfig.json +++ b/x-pack/plugins/upgrade_assistant/tsconfig.json @@ -42,7 +42,8 @@ "@kbn/deeplinks-observability", "@kbn/core-logging-server-mocks", "@kbn/core-http-server-mocks", - "@kbn/core-http-server-utils" + "@kbn/core-http-server-utils", + "@kbn/core-elasticsearch-server" ], "exclude": [ "target/**/*", diff --git a/x-pack/test/alerting_api_integration/common/config.ts b/x-pack/test/alerting_api_integration/common/config.ts index b8a576f99b8d0..04d6a1c48b98e 100644 --- a/x-pack/test/alerting_api_integration/common/config.ts +++ b/x-pack/test/alerting_api_integration/common/config.ts @@ -217,7 +217,6 @@ export function createTestConfig(name: string, options: CreateTestConfigOptions) ...emailSettings, ...maxScheduledPerMinuteSettings, '--xpack.eventLog.logEntries=true', - '--xpack.task_manager.ephemeral_tasks.enabled=false', `--xpack.task_manager.unsafe.exclude_task_types=${JSON.stringify([ 'actions:test.excluded', ])}`, diff --git a/x-pack/test/alerting_api_integration/common/plugins/alerts/server/plugin.ts b/x-pack/test/alerting_api_integration/common/plugins/alerts/server/plugin.ts index 9210e9f71ed9c..62b6d6594b06c 100644 --- a/x-pack/test/alerting_api_integration/common/plugins/alerts/server/plugin.ts +++ b/x-pack/test/alerting_api_integration/common/plugins/alerts/server/plugin.ts @@ -8,10 +8,7 @@ import { Plugin, CoreSetup, CoreStart, Logger, PluginInitializerContext } from '@kbn/core/server'; import { firstValueFrom, Subject } from 'rxjs'; import { PluginSetupContract as ActionsPluginSetup } from '@kbn/actions-plugin/server/plugin'; -import { - PluginStartContract as AlertingPluginsStart, - PluginSetupContract as AlertingPluginSetup, -} from '@kbn/alerting-plugin/server/plugin'; +import { AlertingServerSetup, AlertingServerStart } from '@kbn/alerting-plugin/server/plugin'; import { TaskManagerSetupContract, TaskManagerStartContract, @@ -25,6 +22,7 @@ import { RuleRegistryPluginSetupContract } from '@kbn/rule-registry-plugin/serve import { IEventLogClientService } from '@kbn/event-log-plugin/server'; import { NotificationsPluginStart } from '@kbn/notifications-plugin/server'; import { RULE_SAVED_OBJECT_TYPE } from '@kbn/alerting-plugin/server'; +import { ALERTING_FEATURE_ID } from '@kbn/alerting-plugin/common'; import { KibanaFeatureScope } from '@kbn/features-plugin/common'; import { defineRoutes } from './routes'; import { defineActionTypes } from './action_types'; @@ -34,13 +32,13 @@ import { defineConnectorAdapters } from './connector_adapters'; export interface FixtureSetupDeps { features: FeaturesPluginSetup; actions: ActionsPluginSetup; - alerting: AlertingPluginSetup; + alerting: AlertingServerSetup; taskManager: TaskManagerSetupContract; ruleRegistry: RuleRegistryPluginSetupContract; } export interface FixtureStartDeps { - alerting: AlertingPluginsStart; + alerting: AlertingServerStart; encryptedSavedObjects: EncryptedSavedObjectsPluginStart; security?: SecurityPluginStart; spaces?: SpacesPluginStart; @@ -50,6 +48,35 @@ export interface FixtureStartDeps { notifications: NotificationsPluginStart; } +const testRuleTypes = [ + 'test.always-firing', + 'test.cumulative-firing', + 'test.never-firing', + 'test.failing', + 'test.authorization', + 'test.delayed', + 'test.validation', + 'test.onlyContextVariables', + 'test.onlyStateVariables', + 'test.noop', + 'test.unrestricted-noop', + 'test.patternFiring', + 'test.patternSuccessOrFailure', + 'test.throw', + 'test.longRunning', + 'test.exceedsAlertLimit', + 'test.always-firing-alert-as-data', + 'test.patternFiringAad', + 'test.waitingRule', + 'test.patternFiringAutoRecoverFalse', + 'test.severity', +]; + +const testAlertingFeatures = testRuleTypes.map((ruleTypeId) => ({ + ruleTypeId, + consumers: ['alertsFixture', ALERTING_FEATURE_ID], +})); + export class FixturePlugin implements Plugin { private readonly logger: Logger; @@ -72,30 +99,8 @@ export class FixturePlugin implements Plugin { const defaultStart = moment().utc().startOf('day').subtract(7, 'days').toISOString(); const defaultEnd = moment().utc().startOf('day').subtract(1, 'day').toISOString(); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/bulk_untrack_by_query.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/bulk_untrack_by_query.ts index 794cb73677730..66d04b723ca03 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/bulk_untrack_by_query.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/bulk_untrack_by_query.ts @@ -130,7 +130,7 @@ export default function bulkUntrackByQueryTests({ getService }: FtrProviderConte }, }, ], - feature_ids: ['alertsFixture'], + rule_type_ids: ['test.always-firing-alert-as-data'], }); switch (scenario.id) { diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/create.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/create.ts index 95e6f7043c90b..d0716df4e2db9 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/create.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/create.ts @@ -261,18 +261,11 @@ export default function createAlertTests({ getService }: FtrProviderContext) { switch (scenario.id) { case 'no_kibana_privileges at space1': case 'space_1_all at space2': - expect(response.statusCode).to.eql(403); - expect(response.body).to.eql({ - error: 'Forbidden', - message: getUnauthorizedErrorMessage('create', 'test.noop', 'alerts'), - statusCode: 403, - }); - break; case 'global_read at space1': expect(response.statusCode).to.eql(403); expect(response.body).to.eql({ error: 'Forbidden', - message: getUnauthorizedErrorMessage('create', 'test.noop', 'alertsFixture'), + message: getUnauthorizedErrorMessage('create', 'test.noop', 'alerts'), statusCode: 403, }); break; diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/delete.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/delete.ts index d6cb57261a558..6814ed46c42b3 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/delete.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/delete.ts @@ -219,7 +219,7 @@ export default function createDeleteTests({ getService }: FtrProviderContext) { expect(response.statusCode).to.eql(403); expect(response.body).to.eql({ error: 'Forbidden', - message: getUnauthorizedErrorMessage('delete', 'test.noop', 'alertsFixture'), + message: getUnauthorizedErrorMessage('delete', 'test.noop', 'alerts'), statusCode: 403, }); objectRemover.add(space.id, createdAlert.id, 'rule', 'alerting'); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/disable.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/disable.ts index 264df417440f3..aa43d52d60ad4 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/disable.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/disable.ts @@ -255,18 +255,11 @@ export default function createDisableAlertTests({ getService }: FtrProviderConte switch (scenario.id) { case 'no_kibana_privileges at space1': case 'space_1_all at space2': - expect(response.statusCode).to.eql(403); - expect(response.body).to.eql({ - error: 'Forbidden', - message: getUnauthorizedErrorMessage('disable', 'test.noop', 'alerts'), - statusCode: 403, - }); - break; case 'global_read at space1': expect(response.statusCode).to.eql(403); expect(response.body).to.eql({ error: 'Forbidden', - message: getUnauthorizedErrorMessage('disable', 'test.noop', 'alertsFixture'), + message: getUnauthorizedErrorMessage('disable', 'test.noop', 'alerts'), statusCode: 403, }); break; diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/enable.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/enable.ts index 581f6f13a63b7..eef6ff320a828 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/enable.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/enable.ts @@ -246,18 +246,11 @@ export default function createEnableAlertTests({ getService }: FtrProviderContex switch (scenario.id) { case 'no_kibana_privileges at space1': case 'space_1_all at space2': - expect(response.statusCode).to.eql(403); - expect(response.body).to.eql({ - error: 'Forbidden', - message: getUnauthorizedErrorMessage('enable', 'test.noop', 'alerts'), - statusCode: 403, - }); - break; case 'global_read at space1': expect(response.statusCode).to.eql(403); expect(response.body).to.eql({ error: 'Forbidden', - message: getUnauthorizedErrorMessage('enable', 'test.noop', 'alertsFixture'), + message: getUnauthorizedErrorMessage('enable', 'test.noop', 'alerts'), statusCode: 403, }); break; diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/find.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/find.ts index bf5595e5756c1..da74893f81713 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/find.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/find.ts @@ -8,12 +8,7 @@ import expect from '@kbn/expect'; import { chunk, omit } from 'lodash'; import { v4 as uuidv4 } from 'uuid'; -import { - ES_QUERY_ID, - ML_ANOMALY_DETECTION_RULE_TYPE_ID, - OBSERVABILITY_THRESHOLD_RULE_TYPE_ID, -} from '@kbn/rule-data-utils'; -import { SuperuserAtSpace1, UserAtSpaceScenarios, StackAlertsOnly } from '../../../scenarios'; +import { SuperuserAtSpace1, UserAtSpaceScenarios } from '../../../scenarios'; import { getUrlPrefix, getTestRuleData, ObjectRemover } from '../../../../common/lib'; import { FtrProviderContext } from '../../../../common/ftr_provider_context'; @@ -614,120 +609,5 @@ export default function createFindTests({ getService }: FtrProviderContext) { ]); }); }); - - describe('stack alerts', () => { - const ruleTypes = [ - [ - ES_QUERY_ID, - { - searchType: 'esQuery', - timeWindowSize: 5, - timeWindowUnit: 'm', - threshold: [1000], - thresholdComparator: '>', - size: 100, - esQuery: '{\n "query":{\n "match_all" : {}\n }\n }', - aggType: 'count', - groupBy: 'all', - termSize: 5, - excludeHitsFromPreviousRun: false, - sourceFields: [], - index: ['.kibana'], - timeField: 'created_at', - }, - ], - [ - OBSERVABILITY_THRESHOLD_RULE_TYPE_ID, - { - criteria: [ - { - comparator: '>', - metrics: [ - { - name: 'A', - aggType: 'count', - }, - ], - threshold: [100], - timeSize: 1, - timeUnit: 'm', - }, - ], - alertOnNoData: false, - alertOnGroupDisappear: false, - searchConfiguration: { - query: { - query: '', - language: 'kuery', - }, - index: 'kibana-event-log-data-view', - }, - }, - ], - [ - ML_ANOMALY_DETECTION_RULE_TYPE_ID, - { - severity: 75, - resultType: 'bucket', - includeInterim: false, - jobSelection: { - jobIds: ['low_request_rate'], - }, - }, - ], - ]; - - const createRule = async (rule = {}) => { - const { body: createdAlert } = await supertest - .post(`${getUrlPrefix('space1')}/api/alerting/rule`) - .set('kbn-xsrf', 'foo') - .send(getTestRuleData({ ...rule })) - .expect(200); - - objectRemover.add('space1', createdAlert.id, 'rule', 'alerting'); - }; - - for (const [ruleTypeId, params] of ruleTypes) { - it(`should get rules of ${ruleTypeId} rule type ID and stackAlerts consumer`, async () => { - /** - * We create two rules. The first one is a test.noop - * rule with stackAlerts as consumer. The second rule - * is has different rule type ID but with the same consumer as the first rule (stackAlerts). - * This way we can verify that the find API call returns only the rules the user is authorized to. - * Specifically only the second rule because the StackAlertsOnly user does not have - * access to the test.noop rule type. - */ - await createRule({ consumer: 'stackAlerts' }); - await createRule({ rule_type_id: ruleTypeId, params, consumer: 'stackAlerts' }); - - const response = await supertestWithoutAuth - .get(`${getUrlPrefix('space1')}/api/alerting/rules/_find`) - .auth(StackAlertsOnly.username, StackAlertsOnly.password); - - expect(response.statusCode).to.eql(200); - expect(response.body.total).to.equal(1); - expect(response.body.data[0].rule_type_id).to.equal(ruleTypeId); - expect(response.body.data[0].consumer).to.equal('stackAlerts'); - }); - } - - for (const [ruleTypeId, params] of ruleTypes) { - it(`should NOT get rules of ${ruleTypeId} rule type ID and NOT stackAlerts consumer`, async () => { - /** - * We create two rules with logs as consumer. The user is authorized to - * access rules only with the stackAlerts consumers. - */ - await createRule({ consumer: 'logs' }); - await createRule({ rule_type_id: ruleTypeId, params, consumer: 'logs' }); - - const response = await supertestWithoutAuth - .get(`${getUrlPrefix('space1')}/api/alerting/rules/_find`) - .auth(StackAlertsOnly.username, StackAlertsOnly.password); - - expect(response.statusCode).to.eql(200); - expect(response.body.total).to.equal(0); - }); - } - }); }); } diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/find_internal.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/find_internal.ts index ee8d49c662ada..751d5cf169836 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/find_internal.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/find_internal.ts @@ -13,7 +13,13 @@ import { ML_ANOMALY_DETECTION_RULE_TYPE_ID, OBSERVABILITY_THRESHOLD_RULE_TYPE_ID, } from '@kbn/rule-data-utils'; -import { SuperuserAtSpace1, UserAtSpaceScenarios, StackAlertsOnly } from '../../../scenarios'; +import { Space } from '../../../../common/types'; +import { + Space1AllAtSpace1, + StackAlertsOnly, + SuperuserAtSpace1, + UserAtSpaceScenarios, +} from '../../../scenarios'; import { getUrlPrefix, getTestRuleData, ObjectRemover } from '../../../../common/lib'; import { FtrProviderContext } from '../../../../common/ftr_provider_context'; @@ -31,40 +37,13 @@ export default function createFindTests({ getService }: FtrProviderContext) { for (const scenario of UserAtSpaceScenarios) { const { user, space } = scenario; + describe(scenario.id, () => { it('should handle find alert request appropriately', async () => { - const { body: createdAction } = await supertest - .post(`${getUrlPrefix(space.id)}/api/actions/connector`) - .set('kbn-xsrf', 'foo') - .send({ - name: 'MY action', - connector_type_id: 'test.noop', - config: {}, - secrets: {}, - }) - .expect(200); - const { body: createdAlert } = await supertest .post(`${getUrlPrefix(space.id)}/api/alerting/rule`) .set('kbn-xsrf', 'foo') - .send( - getTestRuleData({ - actions: [ - { - group: 'default', - id: createdAction.id, - params: {}, - frequency: { - summary: false, - notify_when: 'onThrottleInterval', - throttle: '1m', - }, - }, - ], - notify_when: undefined, - throttle: undefined, - }) - ) + .send(getTestRuleData()) .expect(200); objectRemover.add(space.id, createdAlert.id, 'rule', 'alerting'); @@ -108,37 +87,23 @@ export default function createFindTests({ getService }: FtrProviderContext) { consumer: 'alertsFixture', schedule: { interval: '1m' }, enabled: true, - actions: [ - { - group: 'default', - id: createdAction.id, - connector_type_id: 'test.noop', - params: {}, - uuid: match.actions[0].uuid, - frequency: { - summary: false, - notify_when: 'onThrottleInterval', - throttle: '1m', - }, - }, - ], + actions: [], params: {}, created_by: 'elastic', + api_key_created_by_user: false, + revision: 0, scheduled_task_id: match.scheduled_task_id, created_at: match.created_at, updated_at: match.updated_at, - throttle: null, - notify_when: null, + throttle: '1m', + notify_when: 'onThrottleInterval', updated_by: 'elastic', api_key_owner: 'elastic', - api_key_created_by_user: false, mute_all: false, muted_alert_ids: [], - revision: 0, execution_status: match.execution_status, ...(match.next_run ? { next_run: match.next_run } : {}), ...(match.last_run ? { last_run: match.last_run } : {}), - monitoring: match.monitoring, snooze_schedule: match.snooze_schedule, ...(hasActiveSnoozes && { active_snoozes: activeSnoozes }), @@ -153,40 +118,15 @@ export default function createFindTests({ getService }: FtrProviderContext) { }); it('should filter out types that the user is not authorized to `get` retaining pagination', async () => { - async function createNoOpAlert(overrides = {}) { - const alert = getTestRuleData(overrides); - const { body: createdAlert } = await supertest - .post(`${getUrlPrefix(space.id)}/api/alerting/rule`) - .set('kbn-xsrf', 'foo') - .send(alert) - .expect(200); - objectRemover.add(space.id, createdAlert.id, 'rule', 'alerting'); - return { - id: createdAlert.id, - rule_type_id: alert.rule_type_id, - }; - } - function createRestrictedNoOpAlert() { - return createNoOpAlert({ - rule_type_id: 'test.restricted-noop', - consumer: 'alertsRestrictedFixture', - }); - } - function createUnrestrictedNoOpAlert() { - return createNoOpAlert({ - rule_type_id: 'test.unrestricted-noop', - consumer: 'alertsFixture', - }); - } const allAlerts = []; - allAlerts.push(await createNoOpAlert()); - allAlerts.push(await createNoOpAlert()); - allAlerts.push(await createRestrictedNoOpAlert()); - allAlerts.push(await createUnrestrictedNoOpAlert()); - allAlerts.push(await createUnrestrictedNoOpAlert()); - allAlerts.push(await createRestrictedNoOpAlert()); - allAlerts.push(await createNoOpAlert()); - allAlerts.push(await createNoOpAlert()); + allAlerts.push(await createNoOpAlert(space)); + allAlerts.push(await createNoOpAlert(space)); + allAlerts.push(await createRestrictedNoOpAlert(space)); + allAlerts.push(await createUnrestrictedNoOpAlert(space)); + allAlerts.push(await createUnrestrictedNoOpAlert(space)); + allAlerts.push(await createRestrictedNoOpAlert(space)); + allAlerts.push(await createNoOpAlert(space)); + allAlerts.push(await createNoOpAlert(space)); const perPage = 4; @@ -233,25 +173,24 @@ export default function createFindTests({ getService }: FtrProviderContext) { expect(response.body.per_page).to.be.equal(perPage); expect(response.body.total).to.be.equal(8); - { - const [firstPage, secondPage] = chunk( - allAlerts.map((alert) => alert.id), - perPage - ); - expect(response.body.data.map((alert: any) => alert.id)).to.eql(firstPage); - - const secondResponse = await supertestWithoutAuth - .post(`${getUrlPrefix(space.id)}/internal/alerting/rules/_find`) - .set('kbn-xsrf', 'foo') - .auth(user.username, user.password) - .send({ - per_page: perPage, - sort_field: 'createdAt', - page: 2, - }); - - expect(secondResponse.body.data.map((alert: any) => alert.id)).to.eql(secondPage); - } + const [firstPage, secondPage] = chunk( + allAlerts.map((alert) => alert.id), + perPage + ); + expect(response.body.data.map((alert: any) => alert.id)).to.eql(firstPage); + + const secondResponse = await supertestWithoutAuth + .post(`${getUrlPrefix(space.id)}/internal/alerting/rules/_find`) + .set('kbn-xsrf', 'foo') + .auth(user.username, user.password) + .send({ + per_page: perPage, + sort_field: 'createdAt', + page: '2', + }); + + expect(secondResponse.statusCode).to.eql(200); + expect(secondResponse.body.data.map((alert: any) => alert.id)).to.eql(secondPage); break; default: @@ -294,7 +233,7 @@ export default function createFindTests({ getService }: FtrProviderContext) { .set('kbn-xsrf', 'foo') .auth(user.username, user.password) .send({ - filter: 'alert.attributes.actions:{ actionTypeId: test.noop }', + filter: 'alert.attributes.actions:{ actionTypeId: "test.noop" }', }); switch (scenario.id) { @@ -334,13 +273,14 @@ export default function createFindTests({ getService }: FtrProviderContext) { group: 'default', connector_type_id: 'test.noop', params: {}, - uuid: createdAlert.actions[0].uuid, + uuid: match.actions[0].uuid, }, ], params: {}, created_by: 'elastic', - throttle: '1m', api_key_created_by_user: null, + revision: 0, + throttle: '1m', updated_by: 'elastic', api_key_owner: null, mute_all: false, @@ -349,7 +289,6 @@ export default function createFindTests({ getService }: FtrProviderContext) { created_at: match.created_at, updated_at: match.updated_at, execution_status: match.execution_status, - revision: 0, ...(match.next_run ? { next_run: match.next_run } : {}), ...(match.last_run ? { last_run: match.last_run } : {}), monitoring: match.monitoring, @@ -577,73 +516,153 @@ export default function createFindTests({ getService }: FtrProviderContext) { throw new Error(`Scenario untested: ${JSON.stringify(scenario)}`); } }); + + it('should filter by rule type IDs correctly', async () => { + await createNoOpAlert(space); + await createRestrictedNoOpAlert(space); + await createUnrestrictedNoOpAlert(space); + + const perPage = 10; + const ruleTypeIds = ['test.restricted-noop', 'test.noop']; + + const response = await supertestWithoutAuth + .post(`${getUrlPrefix(space.id)}/internal/alerting/rules/_find`) + .set('kbn-xsrf', 'foo') + .auth(user.username, user.password) + .send({ + per_page: perPage, + sort_field: 'createdAt', + rule_type_ids: ruleTypeIds, + }); + + switch (scenario.id) { + case 'no_kibana_privileges at space1': + case 'space_1_all at space2': + expect(response.statusCode).to.eql(403); + expect(response.body).to.eql({ + error: 'Forbidden', + message: `Unauthorized to find rules for any rule types`, + statusCode: 403, + }); + break; + case 'space_1_all at space1': + case 'space_1_all_alerts_none_actions at space1': + expect(response.statusCode).to.eql(200); + expect(response.body.total).to.be.equal(1); + + expect( + response.body.data.every( + (rule: { rule_type_id: string }) => rule.rule_type_id === 'test.noop' + ) + ).to.be.eql(true); + break; + case 'global_read at space1': + case 'superuser at space1': + case 'space_1_all_with_restricted_fixture at space1': + expect(response.statusCode).to.eql(200); + expect(response.body.total).to.be.equal(2); + + expect( + response.body.data.every((rule: { rule_type_id: string }) => + ruleTypeIds.includes(rule.rule_type_id) + ) + ).to.be.eql(true); + break; + default: + throw new Error(`Scenario untested: ${JSON.stringify(scenario)}`); + } + }); }); } - describe('Actions', () => { - const { user, space } = SuperuserAtSpace1; + describe('filtering', () => { + it('should return the correct rules when trying to exploit RBAC through the ruleTypeIds parameter', async () => { + const { user, space } = Space1AllAtSpace1; - it('should return the actions correctly', async () => { - const { body: createdAction } = await supertest - .post(`${getUrlPrefix(space.id)}/api/actions/connector`) + const { body: createdAlert1 } = await supertest + .post(`${getUrlPrefix(SuperuserAtSpace1.space.id)}/api/alerting/rule`) .set('kbn-xsrf', 'foo') - .send({ - name: 'MY action', - connector_type_id: 'test.noop', - config: {}, - secrets: {}, - }) + .send( + getTestRuleData({ + rule_type_id: 'test.restricted-noop', + consumer: 'alertsRestrictedFixture', + }) + ) + .auth(SuperuserAtSpace1.user.username, SuperuserAtSpace1.user.password) .expect(200); - const { body: createdRule1 } = await supertest - .post(`${getUrlPrefix(space.id)}/api/alerting/rule`) + const { body: createdAlert2 } = await supertest + .post(`${getUrlPrefix(SuperuserAtSpace1.space.id)}/api/alerting/rule`) .set('kbn-xsrf', 'foo') .send( getTestRuleData({ - enabled: true, - actions: [ - { - id: createdAction.id, - group: 'default', - params: {}, - }, - { - id: 'system-connector-test.system-action', - params: {}, - }, - ], + rule_type_id: 'test.noop', + consumer: 'alertsFixture', }) ) + .auth(SuperuserAtSpace1.user.username, SuperuserAtSpace1.user.password) .expect(200); - objectRemover.add(space.id, createdRule1.id, 'rule', 'alerting'); + objectRemover.add(SuperuserAtSpace1.space.id, createdAlert1.id, 'rule', 'alerting'); + objectRemover.add(SuperuserAtSpace1.space.id, createdAlert2.id, 'rule', 'alerting'); const response = await supertestWithoutAuth - .get(`${getUrlPrefix(space.id)}/api/alerting/rules/_find`) + .post(`${getUrlPrefix(space.id)}/internal/alerting/rules/_find`) .set('kbn-xsrf', 'foo') - .auth(user.username, user.password); + .auth(user.username, user.password) + .send({ + rule_type_ids: ['test.noop', 'test.restricted-noop'], + }); - const action = response.body.data[0].actions[0]; - const systemAction = response.body.data[0].actions[1]; - const { uuid, ...restAction } = action; - const { uuid: systemActionUuid, ...restSystemAction } = systemAction; + expect(response.status).to.eql(200); + expect(response.body.total).to.equal(1); + expect(response.body.data[0].rule_type_id).to.eql('test.noop'); + }); - expect([restAction, restSystemAction]).to.eql([ - { - id: createdAction.id, - connector_type_id: 'test.noop', - group: 'default', - params: {}, - }, - { - id: 'system-connector-test.system-action', - connector_type_id: 'test.system-action', - params: {}, - }, - , - ]); + it('should return the correct rules when trying to exploit RBAC through the consumers parameter', async () => { + const { user, space } = Space1AllAtSpace1; + + const { body: createdAlert1 } = await supertest + .post(`${getUrlPrefix(SuperuserAtSpace1.space.id)}/api/alerting/rule`) + .set('kbn-xsrf', 'foo') + .send( + getTestRuleData({ + rule_type_id: 'test.restricted-noop', + consumer: 'alertsRestrictedFixture', + }) + ) + .auth(SuperuserAtSpace1.user.username, SuperuserAtSpace1.user.password) + .expect(200); + + const { body: createdAlert2 } = await supertest + .post(`${getUrlPrefix(SuperuserAtSpace1.space.id)}/api/alerting/rule`) + .set('kbn-xsrf', 'foo') + .send( + getTestRuleData({ + rule_type_id: 'test.noop', + consumer: 'alertsFixture', + }) + ) + .auth(SuperuserAtSpace1.user.username, SuperuserAtSpace1.user.password) + .expect(200); + + objectRemover.add(SuperuserAtSpace1.space.id, createdAlert1.id, 'rule', 'alerting'); + objectRemover.add(SuperuserAtSpace1.space.id, createdAlert2.id, 'rule', 'alerting'); + + const response = await supertestWithoutAuth + .post(`${getUrlPrefix(space.id)}/internal/alerting/rules/_find`) + .set('kbn-xsrf', 'foo') + .auth(user.username, user.password) + .send({ + consumers: ['alertsFixture', 'alertsRestrictedFixture'], + }); + + expect(response.status).to.eql(200); + expect(response.body.total).to.equal(1); + expect(response.body.data[0].consumer).to.eql('alertsFixture'); }); }); + describe('stack alerts', () => { const ruleTypes = [ [ @@ -758,5 +777,35 @@ export default function createFindTests({ getService }: FtrProviderContext) { }); } }); + + async function createNoOpAlert(space: Space, overrides = {}) { + const alert = getTestRuleData(overrides); + const { body: createdAlert } = await supertest + .post(`${getUrlPrefix(space.id)}/api/alerting/rule`) + .set('kbn-xsrf', 'foo') + .send(alert) + .expect(200); + + objectRemover.add(space.id, createdAlert.id, 'rule', 'alerting'); + + return { + id: createdAlert.id, + rule_type_id: alert.rule_type_id, + }; + } + + function createRestrictedNoOpAlert(space: Space) { + return createNoOpAlert(space, { + rule_type_id: 'test.restricted-noop', + consumer: 'alertsRestrictedFixture', + }); + } + + function createUnrestrictedNoOpAlert(space: Space) { + return createNoOpAlert(space, { + rule_type_id: 'test.unrestricted-noop', + consumer: 'alertsFixture', + }); + } }); } diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/find_with_post.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/find_with_post.ts deleted file mode 100644 index c8afff8fcc476..0000000000000 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/find_with_post.ts +++ /dev/null @@ -1,593 +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 { Agent as SuperTestAgent } from 'supertest'; -import { chunk, omit } from 'lodash'; -import { v4 as uuidv4 } from 'uuid'; -import { SupertestWithoutAuthProviderType } from '@kbn/ftr-common-functional-services'; -import { UserAtSpaceScenarios } from '../../../scenarios'; -import { getUrlPrefix, getTestRuleData, ObjectRemover } from '../../../../common/lib'; -import { FtrProviderContext } from '../../../../common/ftr_provider_context'; - -const findTestUtils = ( - describeType: 'internal' | 'public', - objectRemover: ObjectRemover, - supertest: SuperTestAgent, - supertestWithoutAuth: SupertestWithoutAuthProviderType -) => { - describe(describeType, () => { - afterEach(async () => { - await objectRemover.removeAll(); - }); - - for (const scenario of UserAtSpaceScenarios) { - const { user, space } = scenario; - describe(scenario.id, () => { - it('should handle find alert request appropriately', async () => { - const { body: createdAlert } = await supertest - .post(`${getUrlPrefix(space.id)}/api/alerting/rule`) - .set('kbn-xsrf', 'foo') - .send(getTestRuleData()) - .expect(200); - objectRemover.add(space.id, createdAlert.id, 'rule', 'alerting'); - - const response = await supertestWithoutAuth - .post( - `${getUrlPrefix(space.id)}/${ - describeType === 'public' ? 'api' : 'internal' - }/alerting/rules/_find` - ) - .set('kbn-xsrf', 'foo') - .auth(user.username, user.password) - .send({ - search: 'test.noop', - search_fields: 'alertTypeId', - }); - - switch (scenario.id) { - case 'no_kibana_privileges at space1': - case 'space_1_all at space2': - expect(response.statusCode).to.eql(403); - expect(response.body).to.eql({ - error: 'Forbidden', - message: `Unauthorized to find rules for any rule types`, - statusCode: 403, - }); - break; - case 'global_read at space1': - case 'superuser at space1': - case 'space_1_all at space1': - case 'space_1_all_alerts_none_actions at space1': - case 'space_1_all_with_restricted_fixture at space1': - expect(response.statusCode).to.eql(200); - expect(response.body.page).to.equal(1); - expect(response.body.per_page).to.be.greaterThan(0); - expect(response.body.total).to.be.greaterThan(0); - const match = response.body.data.find((obj: any) => obj.id === createdAlert.id); - const activeSnoozes = match.active_snoozes; - const hasActiveSnoozes = !!(activeSnoozes || []).filter((obj: any) => obj).length; - expect(match).to.eql({ - id: createdAlert.id, - name: 'abc', - tags: ['foo'], - rule_type_id: 'test.noop', - running: match.running ?? false, - consumer: 'alertsFixture', - schedule: { interval: '1m' }, - enabled: true, - actions: [], - params: {}, - created_by: 'elastic', - api_key_created_by_user: false, - revision: 0, - scheduled_task_id: match.scheduled_task_id, - created_at: match.created_at, - updated_at: match.updated_at, - throttle: '1m', - notify_when: 'onThrottleInterval', - updated_by: 'elastic', - api_key_owner: 'elastic', - mute_all: false, - muted_alert_ids: [], - execution_status: match.execution_status, - ...(match.next_run ? { next_run: match.next_run } : {}), - ...(match.last_run ? { last_run: match.last_run } : {}), - ...(describeType === 'internal' - ? { - monitoring: match.monitoring, - snooze_schedule: match.snooze_schedule, - ...(hasActiveSnoozes && { active_snoozes: activeSnoozes }), - is_snoozed_until: null, - } - : {}), - }); - expect(Date.parse(match.created_at)).to.be.greaterThan(0); - expect(Date.parse(match.updated_at)).to.be.greaterThan(0); - break; - default: - throw new Error(`Scenario untested: ${JSON.stringify(scenario)}`); - } - }); - - it('should filter out types that the user is not authorized to `get` retaining pagination', async () => { - async function createNoOpAlert(overrides = {}) { - const alert = getTestRuleData(overrides); - const { body: createdAlert } = await supertest - .post(`${getUrlPrefix(space.id)}/api/alerting/rule`) - .set('kbn-xsrf', 'foo') - .send(alert) - .expect(200); - objectRemover.add(space.id, createdAlert.id, 'rule', 'alerting'); - return { - id: createdAlert.id, - rule_type_id: alert.rule_type_id, - }; - } - function createRestrictedNoOpAlert() { - return createNoOpAlert({ - rule_type_id: 'test.restricted-noop', - consumer: 'alertsRestrictedFixture', - }); - } - function createUnrestrictedNoOpAlert() { - return createNoOpAlert({ - rule_type_id: 'test.unrestricted-noop', - consumer: 'alertsFixture', - }); - } - const allAlerts = []; - allAlerts.push(await createNoOpAlert()); - allAlerts.push(await createNoOpAlert()); - allAlerts.push(await createRestrictedNoOpAlert()); - allAlerts.push(await createUnrestrictedNoOpAlert()); - allAlerts.push(await createUnrestrictedNoOpAlert()); - allAlerts.push(await createRestrictedNoOpAlert()); - allAlerts.push(await createNoOpAlert()); - allAlerts.push(await createNoOpAlert()); - - const perPage = 4; - - const response = await supertestWithoutAuth - .post( - `${getUrlPrefix(space.id)}/${ - describeType === 'public' ? 'api' : 'internal' - }/alerting/rules/_find` - ) - .set('kbn-xsrf', 'foo') - .auth(user.username, user.password) - .send({ - per_page: perPage, - sort_field: 'createdAt', - }); - - switch (scenario.id) { - case 'no_kibana_privileges at space1': - case 'space_1_all at space2': - expect(response.statusCode).to.eql(403); - expect(response.body).to.eql({ - error: 'Forbidden', - message: `Unauthorized to find rules for any rule types`, - statusCode: 403, - }); - break; - case 'space_1_all at space1': - case 'space_1_all_alerts_none_actions at space1': - expect(response.statusCode).to.eql(200); - expect(response.body.page).to.equal(1); - expect(response.body.per_page).to.be.equal(perPage); - expect(response.body.total).to.be.equal(6); - { - const [firstPage] = chunk( - allAlerts - .filter((alert) => alert.rule_type_id !== 'test.restricted-noop') - .map((alert) => alert.id), - perPage - ); - expect(response.body.data.map((alert: any) => alert.id)).to.eql(firstPage); - } - break; - case 'global_read at space1': - case 'superuser at space1': - case 'space_1_all_with_restricted_fixture at space1': - expect(response.statusCode).to.eql(200); - expect(response.body.page).to.equal(1); - expect(response.body.per_page).to.be.equal(perPage); - expect(response.body.total).to.be.equal(8); - - { - const [firstPage, secondPage] = chunk( - allAlerts.map((alert) => alert.id), - perPage - ); - expect(response.body.data.map((alert: any) => alert.id)).to.eql(firstPage); - - const secondResponse = await supertestWithoutAuth - .post(`${getUrlPrefix(space.id)}/internal/alerting/rules/_find`) - .set('kbn-xsrf', 'kibana') - .auth(user.username, user.password) - .send({ - per_page: perPage, - sort_field: 'createdAt', - page: 2, - }); - - expect(secondResponse.body.data.map((alert: any) => alert.id)).to.eql(secondPage); - } - - break; - default: - throw new Error(`Scenario untested: ${JSON.stringify(scenario)}`); - } - }); - - it('should handle find alert request with filter appropriately', async () => { - const { body: createdAction } = await supertest - .post(`${getUrlPrefix(space.id)}/api/actions/connector`) - .set('kbn-xsrf', 'foo') - .send({ - name: 'My action', - connector_type_id: 'test.noop', - config: {}, - secrets: {}, - }) - .expect(200); - - const { body: createdAlert } = await supertest - .post(`${getUrlPrefix(space.id)}/api/alerting/rule`) - .set('kbn-xsrf', 'foo') - .send( - getTestRuleData({ - enabled: false, - actions: [ - { - id: createdAction.id, - group: 'default', - params: {}, - }, - ], - }) - ) - .expect(200); - objectRemover.add(space.id, createdAlert.id, 'rule', 'alerting'); - - const response = await supertestWithoutAuth - .post( - `${getUrlPrefix(space.id)}/${ - describeType === 'public' ? 'api' : 'internal' - }/alerting/rules/_find` - ) - .set('kbn-xsrf', 'foo') - .auth(user.username, user.password) - .send({ - filter: 'alert.attributes.actions:{ actionTypeId: "test.noop" }', - }); - - switch (scenario.id) { - case 'no_kibana_privileges at space1': - case 'space_1_all at space2': - expect(response.statusCode).to.eql(403); - expect(response.body).to.eql({ - error: 'Forbidden', - message: `Unauthorized to find rules for any rule types`, - statusCode: 403, - }); - break; - case 'global_read at space1': - case 'superuser at space1': - case 'space_1_all at space1': - case 'space_1_all_alerts_none_actions at space1': - case 'space_1_all_with_restricted_fixture at space1': - expect(response.statusCode).to.eql(200); - expect(response.body.page).to.equal(1); - expect(response.body.per_page).to.be.greaterThan(0); - expect(response.body.total).to.be.greaterThan(0); - const match = response.body.data.find((obj: any) => obj.id === createdAlert.id); - const activeSnoozes = match.active_snoozes; - const hasActiveSnoozes = !!(activeSnoozes || []).filter((obj: any) => obj).length; - expect(match).to.eql({ - id: createdAlert.id, - name: 'abc', - tags: ['foo'], - rule_type_id: 'test.noop', - running: match.running ?? false, - consumer: 'alertsFixture', - schedule: { interval: '1m' }, - enabled: false, - actions: [ - { - id: createdAction.id, - group: 'default', - connector_type_id: 'test.noop', - params: {}, - uuid: match.actions[0].uuid, - }, - ], - params: {}, - created_by: 'elastic', - api_key_created_by_user: null, - revision: 0, - throttle: '1m', - updated_by: 'elastic', - api_key_owner: null, - mute_all: false, - muted_alert_ids: [], - notify_when: 'onThrottleInterval', - created_at: match.created_at, - updated_at: match.updated_at, - execution_status: match.execution_status, - ...(match.next_run ? { next_run: match.next_run } : {}), - ...(match.last_run ? { last_run: match.last_run } : {}), - ...(describeType === 'internal' - ? { - monitoring: match.monitoring, - snooze_schedule: match.snooze_schedule, - ...(hasActiveSnoozes && { active_snoozes: activeSnoozes }), - is_snoozed_until: null, - } - : {}), - }); - expect(Date.parse(match.created_at)).to.be.greaterThan(0); - expect(Date.parse(match.updated_at)).to.be.greaterThan(0); - break; - default: - throw new Error(`Scenario untested: ${JSON.stringify(scenario)}`); - } - }); - - it('should handle find alert request with fields appropriately', async () => { - const myTag = uuidv4(); - const { body: createdAlert } = await supertest - .post(`${getUrlPrefix(space.id)}/api/alerting/rule`) - .set('kbn-xsrf', 'foo') - .send( - getTestRuleData({ - enabled: false, - tags: [myTag], - rule_type_id: 'test.restricted-noop', - consumer: 'alertsRestrictedFixture', - }) - ) - .expect(200); - objectRemover.add(space.id, createdAlert.id, 'rule', 'alerting'); - - // create another type with same tag - const { body: createdSecondAlert } = await supertest - .post(`${getUrlPrefix(space.id)}/api/alerting/rule`) - .set('kbn-xsrf', 'foo') - .send( - getTestRuleData({ - tags: [myTag], - rule_type_id: 'test.restricted-noop', - consumer: 'alertsRestrictedFixture', - }) - ) - .expect(200); - objectRemover.add(space.id, createdSecondAlert.id, 'rule', 'alerting'); - - const response = await supertestWithoutAuth - .post( - `${getUrlPrefix(space.id)}/${ - describeType === 'public' ? 'api' : 'internal' - }/alerting/rules/_find` - ) - .set('kbn-xsrf', 'foo') - .auth(user.username, user.password) - .send({ - filter: 'alert.attributes.alertTypeId:test.restricted-noop', - fields: ['tags'], - sort_field: 'createdAt', - }); - - switch (scenario.id) { - case 'no_kibana_privileges at space1': - case 'space_1_all at space2': - expect(response.statusCode).to.eql(403); - expect(response.body).to.eql({ - error: 'Forbidden', - message: `Unauthorized to find rules for any rule types`, - statusCode: 403, - }); - break; - case 'space_1_all at space1': - case 'space_1_all_alerts_none_actions at space1': - expect(response.statusCode).to.eql(200); - expect(response.body.data).to.eql([]); - break; - case 'global_read at space1': - case 'superuser at space1': - case 'space_1_all_with_restricted_fixture at space1': - expect(response.statusCode).to.eql(200); - expect(response.body.page).to.equal(1); - expect(response.body.per_page).to.be.greaterThan(0); - expect(response.body.total).to.be.greaterThan(0); - const [matchFirst, matchSecond] = response.body.data; - expect(omit(matchFirst, 'updatedAt')).to.eql({ - id: createdAlert.id, - actions: [], - tags: [myTag], - ...(describeType === 'internal' && { - snooze_schedule: [], - is_snoozed_until: null, - }), - }); - expect(omit(matchSecond, 'updatedAt')).to.eql({ - id: createdSecondAlert.id, - actions: [], - tags: [myTag], - ...(describeType === 'internal' && { - snooze_schedule: [], - is_snoozed_until: null, - }), - }); - break; - default: - throw new Error(`Scenario untested: ${JSON.stringify(scenario)}`); - } - }); - - it('should handle find alert request with executionStatus field appropriately', async () => { - const myTag = uuidv4(); - const { body: createdAlert } = await supertest - .post(`${getUrlPrefix(space.id)}/api/alerting/rule`) - .set('kbn-xsrf', 'foo') - .send( - getTestRuleData({ - enabled: false, - tags: [myTag], - rule_type_id: 'test.restricted-noop', - consumer: 'alertsRestrictedFixture', - }) - ) - .expect(200); - objectRemover.add(space.id, createdAlert.id, 'rule', 'alerting'); - - // create another type with same tag - const { body: createdSecondAlert } = await supertest - .post(`${getUrlPrefix(space.id)}/api/alerting/rule`) - .set('kbn-xsrf', 'foo') - .send( - getTestRuleData({ - tags: [myTag], - rule_type_id: 'test.restricted-noop', - consumer: 'alertsRestrictedFixture', - }) - ) - .expect(200); - objectRemover.add(space.id, createdSecondAlert.id, 'rule', 'alerting'); - - const response = await supertestWithoutAuth - .post( - `${getUrlPrefix(space.id)}/${ - describeType === 'public' ? 'api' : 'internal' - }/alerting/rules/_find` - ) - .set('kbn-xsrf', 'foo') - .auth(user.username, user.password) - .send({ - filter: 'alert.attributes.alertTypeId:test.restricted-noop', - fields: ['tags', 'executionStatus'], - sort_field: 'createdAt', - }); - - switch (scenario.id) { - case 'no_kibana_privileges at space1': - case 'space_1_all at space2': - expect(response.statusCode).to.eql(403); - expect(response.body).to.eql({ - error: 'Forbidden', - message: `Unauthorized to find rules for any rule types`, - statusCode: 403, - }); - break; - case 'space_1_all at space1': - case 'space_1_all_alerts_none_actions at space1': - expect(response.statusCode).to.eql(200); - expect(response.body.data).to.eql([]); - break; - case 'global_read at space1': - case 'superuser at space1': - case 'space_1_all_with_restricted_fixture at space1': - expect(response.statusCode).to.eql(200); - expect(response.body.page).to.equal(1); - expect(response.body.per_page).to.be.greaterThan(0); - expect(response.body.total).to.be.greaterThan(0); - const [matchFirst, matchSecond] = response.body.data; - expect(omit(matchFirst, 'updatedAt')).to.eql({ - id: createdAlert.id, - actions: [], - tags: [myTag], - execution_status: matchFirst.execution_status, - ...(describeType === 'internal' && { - snooze_schedule: [], - is_snoozed_until: null, - }), - }); - expect(omit(matchSecond, 'updatedAt')).to.eql({ - id: createdSecondAlert.id, - actions: [], - tags: [myTag], - execution_status: matchSecond.execution_status, - ...(describeType === 'internal' && { - snooze_schedule: [], - is_snoozed_until: null, - }), - }); - break; - default: - throw new Error(`Scenario untested: ${JSON.stringify(scenario)}`); - } - }); - - it(`shouldn't find alert from another space`, async () => { - const { body: createdAlert } = await supertest - .post(`${getUrlPrefix(space.id)}/api/alerting/rule`) - .set('kbn-xsrf', 'foo') - .send(getTestRuleData()) - .expect(200); - objectRemover.add(space.id, createdAlert.id, 'rule', 'alerting'); - - const response = await supertestWithoutAuth - .post( - `${getUrlPrefix('other')}/${ - describeType === 'public' ? 'api' : 'internal' - }/alerting/rules/_find` - ) - .set('kbn-xsrf', 'foo') - .auth(user.username, user.password) - .send({ - search: 'test.noop', - search_fields: 'alertTypeId', - }); - - switch (scenario.id) { - case 'no_kibana_privileges at space1': - case 'space_1_all at space2': - case 'space_1_all at space1': - case 'space_1_all_alerts_none_actions at space1': - case 'space_1_all_with_restricted_fixture at space1': - expect(response.statusCode).to.eql(403); - expect(response.body).to.eql({ - error: 'Forbidden', - message: `Unauthorized to find rules for any rule types`, - statusCode: 403, - }); - break; - case 'global_read at space1': - case 'superuser at space1': - expect(response.statusCode).to.eql(200); - expect(response.body).to.eql({ - page: 1, - per_page: 10, - total: 0, - data: [], - }); - break; - default: - throw new Error(`Scenario untested: ${JSON.stringify(scenario)}`); - } - }); - }); - } - }); -}; - -// eslint-disable-next-line import/no-default-export -export default function createFindTests({ getService }: FtrProviderContext) { - const supertest = getService('supertest'); - const supertestWithoutAuth = getService('supertestWithoutAuth'); - - describe('find with post', () => { - const objectRemover = new ObjectRemover(supertest); - - afterEach(async () => { - await objectRemover.removeAll(); - }); - - findTestUtils('internal', objectRemover, supertest, supertestWithoutAuth); - }); -} diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/get.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/get.ts index 78c662d98a541..c1872d1e40213 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/get.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/get.ts @@ -223,23 +223,12 @@ const getTestUtils = ( switch (scenario.id) { case 'no_kibana_privileges at space1': case 'space_1_all at space2': - expect(response.statusCode).to.eql(403); - expect(response.body).to.eql({ - error: 'Forbidden', - message: getUnauthorizedErrorMessage('get', 'test.restricted-noop', 'alerts'), - statusCode: 403, - }); - break; case 'space_1_all at space1': case 'space_1_all_alerts_none_actions at space1': expect(response.statusCode).to.eql(403); expect(response.body).to.eql({ error: 'Forbidden', - message: getUnauthorizedErrorMessage( - 'get', - 'test.restricted-noop', - 'alertsRestrictedFixture' - ), + message: getUnauthorizedErrorMessage('get', 'test.restricted-noop', 'alerts'), statusCode: 403, }); break; diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/index.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/index.ts index 262fe8af301c8..dc85feb741eb8 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/index.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/index.ts @@ -23,7 +23,6 @@ export default function alertingTests({ loadTestFile, getService }: FtrProviderC loadTestFile(require.resolve('./backfill')); loadTestFile(require.resolve('./find')); loadTestFile(require.resolve('./find_internal')); - loadTestFile(require.resolve('./find_with_post')); loadTestFile(require.resolve('./create')); loadTestFile(require.resolve('./delete')); loadTestFile(require.resolve('./disable')); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/alerting/aggregate.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/alerting/aggregate.ts new file mode 100644 index 0000000000000..dde153aca402e --- /dev/null +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/alerting/aggregate.ts @@ -0,0 +1,377 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor 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 { Space, User } from '../../../../common/types'; +import { Space1AllAtSpace1, SuperuserAtSpace1, UserAtSpaceScenarios } from '../../../scenarios'; +import { getUrlPrefix, getTestRuleData, ObjectRemover, getEventLog } from '../../../../common/lib'; +import { FtrProviderContext } from '../../../../common/ftr_provider_context'; + +// eslint-disable-next-line import/no-default-export +export default function createAggregateTests({ getService }: FtrProviderContext) { + const supertest = getService('supertest'); + const supertestWithoutAuth = getService('supertestWithoutAuth'); + const retry = getService('retry'); + + const getEventLogWithRetry = async (id: string, space: Space) => { + await retry.try(async () => { + return await getEventLog({ + getService, + spaceId: space.id, + type: 'alert', + id, + provider: 'alerting', + actions: new Map([['execute', { equal: 1 }]]), + }); + }); + }; + + describe('aggregate', () => { + const objectRemover = new ObjectRemover(supertest); + + afterEach(async () => { + await objectRemover.removeAll(); + }); + + for (const scenario of UserAtSpaceScenarios) { + const { user, space } = scenario; + + describe(scenario.id, () => { + it('should aggregate alert status totals', async () => { + const NumOkAlerts = 4; + const NumActiveAlerts = 1; + const NumErrorAlerts = 2; + + const okAlertIds: string[] = []; + const activeAlertIds: string[] = []; + const errorAlertIds: string[] = []; + + await Promise.all( + [...Array(NumOkAlerts)].map(async () => { + const okAlertId = await createTestAlert( + { + /** + * The _aggregate calls is made + * to get all stats across all rule types + * that the user has access to. Only a subset + * of users have access to the test.restricted-noop/alertsRestrictedFixture + * pair. The differences in the stats ensure that even though we request + * the stats for all rule types only for the ones that the user has access to + * are returned. + * */ + rule_type_id: 'test.restricted-noop', + schedule: { interval: '24h' }, + consumer: 'alertsRestrictedFixture', + }, + space, + user + ); + + okAlertIds.push(okAlertId); + + objectRemover.add(space.id, okAlertId, 'rule', 'alerting'); + }) + ); + + await Promise.all(okAlertIds.map((id) => getEventLogWithRetry(id, space))); + + await Promise.all( + [...Array(NumActiveAlerts)].map(async () => { + const activeAlertId = await createTestAlert( + { + rule_type_id: 'test.patternFiring', + schedule: { interval: '24h' }, + params: { + pattern: { instance: new Array(100).fill(true) }, + }, + }, + space, + user + ); + + activeAlertIds.push(activeAlertId); + objectRemover.add(space.id, activeAlertId, 'rule', 'alerting'); + }) + ); + + await Promise.all(activeAlertIds.map((id) => getEventLogWithRetry(id, space))); + + await Promise.all( + [...Array(NumErrorAlerts)].map(async () => { + const errorAlertId = await createTestAlert( + { + rule_type_id: 'test.throw', + schedule: { interval: '24h' }, + }, + space, + user + ); + + errorAlertIds.push(errorAlertId); + objectRemover.add(space.id, errorAlertId, 'rule', 'alerting'); + }) + ); + + await Promise.all(errorAlertIds.map((id) => getEventLogWithRetry(id, space))); + + switch (scenario.id) { + case 'no_kibana_privileges at space1': + case 'space_1_all at space2': + await aggregate({ + space, + user, + expectedStatusCode: 403, + expectedResponse: { + error: 'Forbidden', + message: 'Unauthorized to find rules for any rule types', + statusCode: 403, + }, + }); + break; + case 'space_1_all at space1': + case 'space_1_all_alerts_none_actions at space1': + await aggregate({ + space, + user, + expectedStatusCode: 200, + expectedResponse: { + rule_enabled_status: { + disabled: 0, + enabled: 3, + }, + rule_execution_status: { + ok: 0, + active: NumActiveAlerts, + error: NumErrorAlerts, + pending: 0, + unknown: 0, + warning: 0, + }, + rule_last_run_outcome: { + succeeded: 1, + warning: 0, + failed: 2, + }, + rule_muted_status: { + muted: 0, + unmuted: 3, + }, + rule_snoozed_status: { + snoozed: 0, + }, + rule_tags: ['foo'], + }, + }); + break; + case 'global_read at space1': + case 'superuser at space1': + case 'space_1_all_with_restricted_fixture at space1': + await aggregate({ + space, + user, + expectedStatusCode: 200, + expectedResponse: { + rule_enabled_status: { + disabled: 0, + enabled: 7, + }, + rule_execution_status: { + ok: NumOkAlerts, + active: NumActiveAlerts, + error: NumErrorAlerts, + pending: 0, + unknown: 0, + warning: 0, + }, + rule_last_run_outcome: { + succeeded: 5, + warning: 0, + failed: 2, + }, + rule_muted_status: { + muted: 0, + unmuted: 7, + }, + rule_snoozed_status: { + snoozed: 0, + }, + rule_tags: ['foo'], + }, + }); + break; + default: + throw new Error(`Scenario untested: ${JSON.stringify(scenario)}`); + } + }); + }); + } + + describe('filtering', () => { + it('should return the correct rule stats when trying to exploit RBAC through the ruleTypeIds parameter', async () => { + const { user, space } = Space1AllAtSpace1; + + const okAlertId = await createTestAlert( + { + rule_type_id: 'test.restricted-noop', + schedule: { interval: '24h' }, + consumer: 'alertsRestrictedFixture', + }, + SuperuserAtSpace1.space, + SuperuserAtSpace1.user + ); + + const activeAlertId = await createTestAlert( + { + rule_type_id: 'test.patternFiring', + schedule: { interval: '24h' }, + params: { + pattern: { instance: new Array(100).fill(true) }, + }, + }, + SuperuserAtSpace1.space, + SuperuserAtSpace1.user + ); + + objectRemover.add(SuperuserAtSpace1.space.id, okAlertId, 'rule', 'alerting'); + objectRemover.add(SuperuserAtSpace1.space.id, activeAlertId, 'rule', 'alerting'); + + await aggregate({ + space, + user, + params: { rule_type_ids: ['test.restricted-noop', 'test.patternFiring'] }, + expectedStatusCode: 200, + expectedResponse: { + rule_enabled_status: { + disabled: 0, + enabled: 1, + }, + rule_execution_status: { + ok: 0, + active: 1, + error: 0, + pending: 0, + unknown: 0, + warning: 0, + }, + rule_last_run_outcome: { + succeeded: 1, + warning: 0, + failed: 0, + }, + rule_muted_status: { + muted: 0, + unmuted: 1, + }, + rule_snoozed_status: { + snoozed: 0, + }, + rule_tags: ['foo'], + }, + }); + }); + + it('should return the correct rule stats when trying to exploit RBAC through the consumer parameter', async () => { + const { user, space } = Space1AllAtSpace1; + + const okAlertId = await createTestAlert( + { + rule_type_id: 'test.restricted-noop', + schedule: { interval: '24h' }, + consumer: 'alertsRestrictedFixture', + }, + SuperuserAtSpace1.space, + SuperuserAtSpace1.user + ); + + const activeAlertId = await createTestAlert( + { + rule_type_id: 'test.patternFiring', + schedule: { interval: '24h' }, + params: { + pattern: { instance: new Array(100).fill(true) }, + }, + }, + SuperuserAtSpace1.space, + SuperuserAtSpace1.user + ); + + objectRemover.add(SuperuserAtSpace1.space.id, okAlertId, 'rule', 'alerting'); + objectRemover.add(SuperuserAtSpace1.space.id, activeAlertId, 'rule', 'alerting'); + + await aggregate({ + space, + user, + params: { consumers: ['alertsRestrictedFixture', 'alertsFixture'] }, + expectedStatusCode: 200, + expectedResponse: { + rule_enabled_status: { + disabled: 0, + enabled: 1, + }, + rule_execution_status: { + ok: 0, + active: 1, + error: 0, + pending: 0, + unknown: 0, + warning: 0, + }, + rule_last_run_outcome: { + succeeded: 1, + warning: 0, + failed: 0, + }, + rule_muted_status: { + muted: 0, + unmuted: 1, + }, + rule_snoozed_status: { + snoozed: 0, + }, + rule_tags: ['foo'], + }, + }); + }); + }); + }); + + async function createTestAlert(testAlertOverrides = {}, space: Space, user: User) { + const { body: createdAlert } = await supertest + .post(`${getUrlPrefix(space.id)}/api/alerting/rule`) + .set('kbn-xsrf', 'foo') + .send(getTestRuleData(testAlertOverrides)) + .auth(user.username, user.password) + .expect(200); + + return createdAlert.id; + } + + const aggregate = async ({ + space, + user, + expectedStatusCode, + expectedResponse, + params = {}, + }: { + space: Space; + user: User; + expectedStatusCode: number; + expectedResponse: Record; + params?: Record; + }) => { + await retry.try(async () => { + const response = await supertestWithoutAuth + .post(`${getUrlPrefix(space.id)}/internal/alerting/rules/_aggregate`) + .set('kbn-xsrf', 'foo') + .auth(user.username, user.password) + .send(params); + + expect(response.status).to.eql(expectedStatusCode); + expect(response.body).to.eql(expectedResponse); + }); + }; +} diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/alerting/index.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/alerting/index.ts index a6f090030a6d4..ea834cbdb5027 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/alerting/index.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/alerting/index.ts @@ -19,6 +19,7 @@ export default function alertingTests({ loadTestFile, getService }: FtrProviderC await tearDown(getService); }); + loadTestFile(require.resolve('./aggregate')); loadTestFile(require.resolve('./mute_all')); loadTestFile(require.resolve('./mute_instance')); loadTestFile(require.resolve('./unmute_all')); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/alerting/mute_all.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/alerting/mute_all.ts index c5be0877c89ff..a9b6bf42e55a3 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/alerting/mute_all.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/alerting/mute_all.ts @@ -252,11 +252,7 @@ export default function createMuteAlertTests({ getService }: FtrProviderContext) expect(response.statusCode).to.eql(403); expect(response.body).to.eql({ error: 'Forbidden', - message: getUnauthorizedErrorMessage( - 'muteAll', - 'test.restricted-noop', - 'alertsRestrictedFixture' - ), + message: getUnauthorizedErrorMessage('muteAll', 'test.restricted-noop', 'alerts'), statusCode: 403, }); break; diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/alerting/mute_instance.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/alerting/mute_instance.ts index b7cdf762836fe..1e3d99f5dd6a8 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/alerting/mute_instance.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/alerting/mute_instance.ts @@ -239,24 +239,13 @@ export default function createMuteAlertInstanceTests({ getService }: FtrProvider switch (scenario.id) { case 'no_kibana_privileges at space1': case 'space_1_all at space2': - expect(response.statusCode).to.eql(403); - expect(response.body).to.eql({ - error: 'Forbidden', - message: getUnauthorizedErrorMessage('muteAlert', 'test.restricted-noop', 'alerts'), - statusCode: 403, - }); - break; case 'global_read at space1': case 'space_1_all at space1': case 'space_1_all_alerts_none_actions at space1': expect(response.statusCode).to.eql(403); expect(response.body).to.eql({ error: 'Forbidden', - message: getUnauthorizedErrorMessage( - 'muteAlert', - 'test.restricted-noop', - 'alertsRestrictedFixture' - ), + message: getUnauthorizedErrorMessage('muteAlert', 'test.restricted-noop', 'alerts'), statusCode: 403, }); break; diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/alerting/unmute_all.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/alerting/unmute_all.ts index d038108d29f67..6c7f56b75eec6 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/alerting/unmute_all.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/alerting/unmute_all.ts @@ -259,6 +259,9 @@ export default function createUnmuteAlertTests({ getService }: FtrProviderContex switch (scenario.id) { case 'no_kibana_privileges at space1': case 'space_1_all at space2': + case 'global_read at space1': + case 'space_1_all at space1': + case 'space_1_all_alerts_none_actions at space1': expect(response.statusCode).to.eql(403); expect(response.body).to.eql({ error: 'Forbidden', @@ -266,9 +269,6 @@ export default function createUnmuteAlertTests({ getService }: FtrProviderContex statusCode: 403, }); break; - case 'global_read at space1': - case 'space_1_all at space1': - case 'space_1_all_alerts_none_actions at space1': expect(response.statusCode).to.eql(403); expect(response.body).to.eql({ error: 'Forbidden', diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/alerting/unmute_instance.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/alerting/unmute_instance.ts index 97add81c6d5b8..a569b834fb82a 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/alerting/unmute_instance.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/alerting/unmute_instance.ts @@ -259,17 +259,6 @@ export default function createMuteAlertInstanceTests({ getService }: FtrProvider switch (scenario.id) { case 'no_kibana_privileges at space1': case 'space_1_all at space2': - expect(response.statusCode).to.eql(403); - expect(response.body).to.eql({ - error: 'Forbidden', - message: getUnauthorizedErrorMessage( - 'unmuteAlert', - 'test.restricted-noop', - 'alerts' - ), - statusCode: 403, - }); - break; case 'global_read at space1': case 'space_1_all at space1': case 'space_1_all_alerts_none_actions at space1': @@ -279,7 +268,7 @@ export default function createMuteAlertInstanceTests({ getService }: FtrProvider message: getUnauthorizedErrorMessage( 'unmuteAlert', 'test.restricted-noop', - 'alertsRestrictedFixture' + 'alerts' ), statusCode: 403, }); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/alerting/update.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/alerting/update.ts index 198baf12e751f..14f089b40759f 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/alerting/update.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/alerting/update.ts @@ -409,24 +409,13 @@ export default function createUpdateTests({ getService }: FtrProviderContext) { switch (scenario.id) { case 'no_kibana_privileges at space1': case 'space_1_all at space2': - expect(response.statusCode).to.eql(403); - expect(response.body).to.eql({ - error: 'Forbidden', - message: getUnauthorizedErrorMessage('update', 'test.restricted-noop', 'alerts'), - statusCode: 403, - }); - break; case 'global_read at space1': case 'space_1_all at space1': case 'space_1_all_alerts_none_actions at space1': expect(response.statusCode).to.eql(403); expect(response.body).to.eql({ error: 'Forbidden', - message: getUnauthorizedErrorMessage( - 'update', - 'test.restricted-noop', - 'alertsRestrictedFixture' - ), + message: getUnauthorizedErrorMessage('update', 'test.restricted-noop', 'alerts'), statusCode: 403, }); break; diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/alerting/update_api_key.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/alerting/update_api_key.ts index 3df0570650146..b92e423cd6829 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/alerting/update_api_key.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/alerting/update_api_key.ts @@ -238,17 +238,6 @@ export default function createUpdateApiKeyTests({ getService }: FtrProviderConte switch (scenario.id) { case 'no_kibana_privileges at space1': case 'space_1_all at space2': - expect(response.statusCode).to.eql(403); - expect(response.body).to.eql({ - error: 'Forbidden', - message: getUnauthorizedErrorMessage( - 'updateApiKey', - 'test.restricted-noop', - 'alerts' - ), - statusCode: 403, - }); - break; case 'global_read at space1': case 'space_1_all at space1': case 'space_1_all_alerts_none_actions at space1': @@ -258,7 +247,7 @@ export default function createUpdateApiKeyTests({ getService }: FtrProviderConte message: getUnauthorizedErrorMessage( 'updateApiKey', 'test.restricted-noop', - 'alertsRestrictedFixture' + 'alerts' ), statusCode: 403, }); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group3/tests/alerting/bulk_delete.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group3/tests/alerting/bulk_delete.ts index fc3526eebc6a4..acc0321adfa5b 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group3/tests/alerting/bulk_delete.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group3/tests/alerting/bulk_delete.ts @@ -249,71 +249,6 @@ export default ({ getService }: FtrProviderContext) => { } }); - it('should handle delete alert request appropriately when consumer is not the producer', async () => { - const { body: createdRule1 } = await supertest - .post(`${getUrlPrefix(space.id)}/api/alerting/rule`) - .set('kbn-xsrf', 'foo') - .send( - getTestRuleData({ - rule_type_id: 'test.restricted-noop', - consumer: 'alertsFixture', - }) - ) - .expect(200); - - const response = await supertestWithoutAuth - .patch(`${getUrlPrefix(space.id)}/internal/alerting/rules/_bulk_delete`) - .set('kbn-xsrf', 'foo') - .send({ ids: [createdRule1.id] }) - .auth(user.username, user.password); - - switch (scenario.id) { - case 'no_kibana_privileges at space1': - case 'space_1_all at space2': - expect(response.body).to.eql({ - error: 'Forbidden', - message: 'Unauthorized to find rules for any rule types', - statusCode: 403, - }); - expect(response.statusCode).to.eql(403); - objectRemover.add(space.id, createdRule1.id, 'rule', 'alerting'); - // Ensure task still exists - await getScheduledTask(createdRule1.scheduled_task_id); - break; - case 'space_1_all at space1': - case 'space_1_all_alerts_none_actions at space1': - case 'space_1_all_with_restricted_fixture at space1': - case 'global_read at space1': - expect(response.body).to.eql({ - statusCode: 400, - error: 'Bad Request', - message: 'No rules found for bulk delete', - }); - expect(response.statusCode).to.eql(400); - objectRemover.add(space.id, createdRule1.id, 'rule', 'alerting'); - // Ensure task still exists - await getScheduledTask(createdRule1.scheduled_task_id); - break; - case 'superuser at space1': - expect(response.body).to.eql({ - rules: [{ ...getDefaultRules(response), rule_type_id: 'test.restricted-noop' }], - errors: [], - total: 1, - taskIdsFailedToBeDeleted: [], - }); - expect(response.statusCode).to.eql(200); - try { - await getScheduledTask(createdRule1.scheduled_task_id); - throw new Error('Should have removed scheduled task'); - } catch (e) { - expect(e.meta.statusCode).to.eql(404); - } - break; - default: - throw new Error(`Scenario untested: ${JSON.stringify(scenario)}`); - } - }); - it('should handle delete alert request appropriately when consumer is "alerts"', async () => { const { body: createdRule1 } = await supertest .post(`${getUrlPrefix(space.id)}/api/alerting/rule`) @@ -348,7 +283,7 @@ export default ({ getService }: FtrProviderContext) => { case 'global_read at space1': expect(response.body).to.eql({ error: 'Forbidden', - message: getUnauthorizedErrorMessage('bulkDelete', 'test.noop', 'alertsFixture'), + message: getUnauthorizedErrorMessage('bulkDelete', 'test.noop', 'alerts'), statusCode: 403, }); expect(response.statusCode).to.eql(403); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group3/tests/alerting/bulk_disable.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group3/tests/alerting/bulk_disable.ts index b8c2041cb27af..7bd3e42edeb70 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group3/tests/alerting/bulk_disable.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group3/tests/alerting/bulk_disable.ts @@ -278,7 +278,7 @@ export default ({ getService }: FtrProviderContext) => { case 'global_read at space1': expect(response.body).to.eql({ error: 'Forbidden', - message: getUnauthorizedErrorMessage('bulkDisable', 'test.noop', 'alertsFixture'), + message: getUnauthorizedErrorMessage('bulkDisable', 'test.noop', 'alerts'), statusCode: 403, }); expect(response.statusCode).to.eql(403); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group3/tests/alerting/bulk_edit.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group3/tests/alerting/bulk_edit.ts index 1082a6741ec0d..c0835b91e209e 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group3/tests/alerting/bulk_edit.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group3/tests/alerting/bulk_edit.ts @@ -388,11 +388,7 @@ export default function createUpdateTests({ getService }: FtrProviderContext) { case 'global_read at space1': expect(response.body).to.eql({ error: 'Forbidden', - message: getUnauthorizedErrorMessage( - 'bulkEdit', - 'test.restricted-noop', - 'alertsRestrictedFixture' - ), + message: getUnauthorizedErrorMessage('bulkEdit', 'test.restricted-noop', 'alerts'), statusCode: 403, }); expect(response.statusCode).to.eql(403); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group3/tests/alerting/bulk_enable.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group3/tests/alerting/bulk_enable.ts index e7cd7044717c4..c829e130f246d 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group3/tests/alerting/bulk_enable.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group3/tests/alerting/bulk_enable.ts @@ -228,54 +228,6 @@ export default ({ getService }: FtrProviderContext) => { } }); - it('should handle enable alert request appropriately when consumer is not the producer', async () => { - const { body: createdRule } = await supertest - .post(`${getUrlPrefix(space.id)}/api/alerting/rule`) - .set('kbn-xsrf', 'foo') - .send( - getTestRuleData({ - rule_type_id: 'test.restricted-noop', - consumer: 'alertsFixture', - }) - ) - .expect(200); - objectRemover.add(space.id, createdRule.id, 'rule', 'alerting'); - - const response = await supertestWithoutAuth - .patch(`${getUrlPrefix(space.id)}/internal/alerting/rules/_bulk_enable`) - .set('kbn-xsrf', 'foo') - .send({ ids: [createdRule.id] }) - .auth(user.username, user.password); - - switch (scenario.id) { - case 'no_kibana_privileges at space1': - case 'space_1_all at space2': - expect(response.body).to.eql({ - error: 'Forbidden', - message: 'Unauthorized to find rules for any rule types', - statusCode: 403, - }); - expect(response.statusCode).to.eql(403); - break; - case 'space_1_all at space1': - case 'space_1_all_alerts_none_actions at space1': - case 'space_1_all_with_restricted_fixture at space1': - case 'global_read at space1': - expect(response.body).to.eql({ - statusCode: 400, - error: 'Bad Request', - message: 'No rules found for bulk enable', - }); - expect(response.statusCode).to.eql(400); - break; - case 'superuser at space1': - expect(response.statusCode).to.eql(200); - break; - default: - throw new Error(`Scenario untested: ${JSON.stringify(scenario)}`); - } - }); - it('should handle enable alert request appropriately when consumer is "alerts"', async () => { const { body: createdRule } = await supertest .post(`${getUrlPrefix(space.id)}/api/alerting/rule`) @@ -308,7 +260,7 @@ export default ({ getService }: FtrProviderContext) => { case 'global_read at space1': expect(response.body).to.eql({ error: 'Forbidden', - message: getUnauthorizedErrorMessage('bulkEnable', 'test.noop', 'alertsFixture'), + message: getUnauthorizedErrorMessage('bulkEnable', 'test.noop', 'alerts'), statusCode: 403, }); expect(response.statusCode).to.eql(403); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group4/tests/alerting/snooze.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group4/tests/alerting/snooze.ts index 8c1fed7978b55..c880b18dd4b46 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group4/tests/alerting/snooze.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group4/tests/alerting/snooze.ts @@ -269,24 +269,13 @@ export default function createSnoozeRuleTests({ getService }: FtrProviderContext switch (scenario.id) { case 'no_kibana_privileges at space1': case 'space_1_all at space2': - expect(response.statusCode).to.eql(403); - expect(response.body).to.eql({ - error: 'Forbidden', - message: getUnauthorizedErrorMessage('snooze', 'test.restricted-noop', 'alerts'), - statusCode: 403, - }); - break; case 'global_read at space1': case 'space_1_all at space1': case 'space_1_all_alerts_none_actions at space1': expect(response.statusCode).to.eql(403); expect(response.body).to.eql({ error: 'Forbidden', - message: getUnauthorizedErrorMessage( - 'snooze', - 'test.restricted-noop', - 'alertsRestrictedFixture' - ), + message: getUnauthorizedErrorMessage('snooze', 'test.restricted-noop', 'alerts'), statusCode: 403, }); break; diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group4/tests/alerting/unsnooze.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group4/tests/alerting/unsnooze.ts index eae8814a514fb..8f509e6104c3d 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group4/tests/alerting/unsnooze.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group4/tests/alerting/unsnooze.ts @@ -254,11 +254,7 @@ export default function createUnsnoozeRuleTests({ getService }: FtrProviderConte expect(response.statusCode).to.eql(403); expect(response.body).to.eql({ error: 'Forbidden', - message: getUnauthorizedErrorMessage( - 'unsnooze', - 'test.restricted-noop', - 'alertsRestrictedFixture' - ), + message: getUnauthorizedErrorMessage('unsnooze', 'test.restricted-noop', 'alerts'), statusCode: 403, }); break; diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/scenarios.ts b/x-pack/test/alerting_api_integration/security_and_spaces/scenarios.ts index fdb56a4fb501e..bf6b38b6befbe 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/scenarios.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/scenarios.ts @@ -282,6 +282,10 @@ const GlobalReadAtSpace1: GlobalReadAtSpace1 = { space: Space1, }; +interface Space1AllAtSpace1 extends Scenario { + id: 'space_1_all at space1'; +} + interface Space1AllWithRestrictedFixtureAtSpace1 extends Scenario { id: 'space_1_all_with_restricted_fixture at space1'; } @@ -322,7 +326,8 @@ export const systemActionScenario: SystemActionSpace1 = { interface Space1AllAtSpace1 extends Scenario { id: 'space_1_all at space1'; } -const Space1AllAtSpace1: Space1AllAtSpace1 = { + +export const Space1AllAtSpace1: Space1AllAtSpace1 = { id: 'space_1_all at space1', user: Space1All, space: Space1, diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group1/aggregate_post.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group1/aggregate.ts similarity index 51% rename from x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group1/aggregate_post.ts rename to x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group1/aggregate.ts index 6269e9bff6e2b..c1553d1ef8d9e 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group1/aggregate_post.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group1/aggregate.ts @@ -28,10 +28,12 @@ export default function createAggregateTests({ getService }: FtrProviderContext) }); }; - describe('aggregate post', () => { + describe('aggregate', () => { const objectRemover = new ObjectRemover(supertest); - afterEach(() => objectRemover.removeAll()); + afterEach(async () => { + await objectRemover.removeAll(); + }); it('should aggregate when there are no alerts', async () => { const response = await supertest @@ -157,6 +159,171 @@ export default function createAggregateTests({ getService }: FtrProviderContext) }); }); + it('should aggregate only filtered rules by rule type IDs', async () => { + const NumOkAlerts = 4; + const NumActiveAlerts = 1; + const NumErrorAlerts = 2; + + const okAlertIds: string[] = []; + const activeAlertIds: string[] = []; + const errorAlertIds: string[] = []; + + await Promise.all( + [...Array(NumOkAlerts)].map(async () => { + const okAlertId = await createTestAlert({ + rule_type_id: 'test.noop', + schedule: { interval: '24h' }, + }); + okAlertIds.push(okAlertId); + objectRemover.add(Spaces.space1.id, okAlertId, 'rule', 'alerting'); + }) + ); + + await Promise.all(okAlertIds.map((id) => getEventLogWithRetry(id))); + + await Promise.all( + [...Array(NumActiveAlerts)].map(async () => { + const activeAlertId = await createTestAlert({ + rule_type_id: 'test.patternFiring', + schedule: { interval: '24h' }, + params: { + pattern: { instance: new Array(100).fill(true) }, + }, + }); + activeAlertIds.push(activeAlertId); + objectRemover.add(Spaces.space1.id, activeAlertId, 'rule', 'alerting'); + }) + ); + + await Promise.all(activeAlertIds.map((id) => getEventLogWithRetry(id))); + + await Promise.all( + [...Array(NumErrorAlerts)].map(async () => { + const errorAlertId = await createTestAlert({ + rule_type_id: 'test.throw', + schedule: { interval: '24h' }, + }); + errorAlertIds.push(errorAlertId); + objectRemover.add(Spaces.space1.id, errorAlertId, 'rule', 'alerting'); + }) + ); + + await Promise.all(errorAlertIds.map((id) => getEventLogWithRetry(id))); + + await retry.try(async () => { + const response = await supertest + .post(`${getUrlPrefix(Spaces.space1.id)}/internal/alerting/rules/_aggregate`) + .set('kbn-xsrf', 'foo') + .send({ rule_type_ids: ['test.noop'] }); + + expect(response.status).to.eql(200); + expect(response.body).to.eql({ + rule_enabled_status: { + disabled: 0, + enabled: 4, + }, + rule_execution_status: { + ok: NumOkAlerts, + active: 0, + error: 0, + pending: 0, + unknown: 0, + warning: 0, + }, + rule_last_run_outcome: { + succeeded: 4, + warning: 0, + failed: 0, + }, + rule_muted_status: { + muted: 0, + unmuted: 4, + }, + rule_snoozed_status: { + snoozed: 0, + }, + rule_tags: ['foo'], + }); + }); + }); + + it('should aggregate only filtered rules by consumer', async () => { + const NumOkAlerts = 4; + const NumActiveAlerts = 1; + const NumErrorAlerts = 2; + + const okAlertIds: string[] = []; + const activeAlertIds: string[] = []; + const errorAlertIds: string[] = []; + + await Promise.all( + [...Array(NumOkAlerts)].map(async () => { + const okAlertId = await createTestAlert({ + rule_type_id: 'test.restricted-noop', + schedule: { interval: '24h' }, + consumer: 'alertsRestrictedFixture', + }); + okAlertIds.push(okAlertId); + objectRemover.add(Spaces.space1.id, okAlertId, 'rule', 'alerting'); + }) + ); + + await Promise.all(okAlertIds.map((id) => getEventLogWithRetry(id))); + + await Promise.all( + [...Array(NumActiveAlerts)].map(async () => { + const activeAlertId = await createTestAlert({ + rule_type_id: 'test.patternFiring', + schedule: { interval: '24h' }, + params: { + pattern: { instance: new Array(100).fill(true) }, + }, + }); + activeAlertIds.push(activeAlertId); + objectRemover.add(Spaces.space1.id, activeAlertId, 'rule', 'alerting'); + }) + ); + + await Promise.all(activeAlertIds.map((id) => getEventLogWithRetry(id))); + + await Promise.all( + [...Array(NumErrorAlerts)].map(async () => { + const errorAlertId = await createTestAlert({ + rule_type_id: 'test.throw', + schedule: { interval: '24h' }, + }); + errorAlertIds.push(errorAlertId); + objectRemover.add(Spaces.space1.id, errorAlertId, 'rule', 'alerting'); + }) + ); + + await Promise.all(errorAlertIds.map((id) => getEventLogWithRetry(id))); + + await retry.try(async () => { + const response = await supertest + .post(`${getUrlPrefix(Spaces.space1.id)}/internal/alerting/rules/_aggregate`) + .set('kbn-xsrf', 'foo') + .send({ consumers: ['alertsFixture'] }); + + expect(response.status).to.eql(200); + expect(response.body).to.eql({ + rule_execution_status: { + error: NumErrorAlerts, + active: NumActiveAlerts, + ok: 0, + pending: 0, + unknown: 0, + warning: 0, + }, + rule_last_run_outcome: { failed: 2, succeeded: 1, warning: 0 }, + rule_enabled_status: { enabled: 3, disabled: 0 }, + rule_muted_status: { muted: 0, unmuted: 3 }, + rule_snoozed_status: { snoozed: 0 }, + rule_tags: ['foo'], + }); + }); + }); + describe('tags limit', () => { it('should be 50 be default', async () => { const numOfAlerts = 3; diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group1/find.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group1/find.ts index e730dd657d2f1..f6b48df9b9f17 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group1/find.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group1/find.ts @@ -33,10 +33,13 @@ export default function createFindTests({ getService }: FtrProviderContext) { describe('find public API', () => { const objectRemover = new ObjectRemover(supertest); - afterEach(() => objectRemover.removeAll()); + afterEach(async () => { + await objectRemover.removeAll(); + }); describe('handle find alert request', function () { this.tags('skipFIPS'); + it('should handle find alert request appropriately', async () => { const { body: createdAction } = await supertest .post(`${getUrlPrefix(Spaces.space1.id)}/api/actions/connector`) @@ -290,6 +293,48 @@ export default function createFindTests({ getService }: FtrProviderContext) { 'Error find rules: Filter is not supported on this field alert.attributes.mapped_params.risk_score' ); }); + + it('should throw when using rule_type_ids', async () => { + const { body: createdAlert } = await supertest + .post(`${getUrlPrefix(Spaces.space1.id)}/api/alerting/rule`) + .set('kbn-xsrf', 'foo') + .send(getTestRuleData()) + .expect(200); + + objectRemover.add(Spaces.space1.id, createdAlert.id, 'rule', 'alerting'); + + const response = await supertest.get( + `${getUrlPrefix(Spaces.space1.id)}/api/alerting/rules/_find?rule_type_ids=foo` + ); + + expect(response.statusCode).to.eql(400); + expect(response.body).to.eql({ + statusCode: 400, + error: 'Bad Request', + message: '[request query.rule_type_ids]: definition for this key is missing', + }); + }); + + it('should throw when using consumers', async () => { + const { body: createdAlert } = await supertest + .post(`${getUrlPrefix(Spaces.space1.id)}/api/alerting/rule`) + .set('kbn-xsrf', 'foo') + .send(getTestRuleData()) + .expect(200); + + objectRemover.add(Spaces.space1.id, createdAlert.id, 'rule', 'alerting'); + + const response = await supertest.get( + `${getUrlPrefix(Spaces.space1.id)}/api/alerting/rules/_find?consumers=foo` + ); + + expect(response.statusCode).to.eql(400); + expect(response.body).to.eql({ + statusCode: 400, + error: 'Bad Request', + message: '[request query.consumers]: definition for this key is missing', + }); + }); }); describe('legacy', function () { diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group1/find_internal.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group1/find_internal.ts index 25fc54a5229d3..7c10b9be598bb 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group1/find_internal.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group1/find_internal.ts @@ -22,6 +22,7 @@ async function createAlert( .set('kbn-xsrf', 'foo') .send(getTestRuleData(overwrites)) .expect(200); + objectRemover.add(Spaces.space1.id, createdAlert.id, 'rule', 'alerting'); return createdAlert; } @@ -33,10 +34,13 @@ export default function createFindTests({ getService }: FtrProviderContext) { describe('find internal API', () => { const objectRemover = new ObjectRemover(supertest); - afterEach(() => objectRemover.removeAll()); + afterEach(async () => { + await objectRemover.removeAll(); + }); describe('handle find alert request', function () { this.tags('skipFIPS'); + it('should handle find alert request appropriately', async () => { const { body: createdAction } = await supertest .post(`${getUrlPrefix(Spaces.space1.id)}/api/actions/connector`) @@ -276,7 +280,7 @@ export default function createFindTests({ getService }: FtrProviderContext) { it('should filter on parameters', async () => { const response = await supertest - .get(`${getUrlPrefix(Spaces.space1.id)}/internal/alerting/rules/_find`) + .post(`${getUrlPrefix(Spaces.space1.id)}/internal/alerting/rules/_find`) .set('kbn-xsrf', 'foo') .send({ filter: 'alert.attributes.params.risk_score:40', @@ -286,17 +290,52 @@ export default function createFindTests({ getService }: FtrProviderContext) { expect(response.body.total).to.equal(1); expect(response.body.data[0].params.risk_score).to.eql(40); }); + }); - it('should error if filtering on mapped parameters directly using the public API', async () => { - const response = await supertest - .post(`${getUrlPrefix(Spaces.space1.id)}/internal/alerting/rules/_find`) - .set('kbn-xsrf', 'foo') - .send({ - filter: 'alert.attributes.mapped_params.risk_score:40', - }); + it('should filter rules by rule type IDs', async () => { + await createAlert(objectRemover, supertest, { + rule_type_id: 'test.noop', + consumer: 'alertsFixture', + }); - expect(response.status).to.eql(200); + await createAlert(objectRemover, supertest, { + rule_type_id: 'test.restricted-noop', + consumer: 'alertsRestrictedFixture', }); + + const response = await supertest + .post(`${getUrlPrefix(Spaces.space1.id)}/internal/alerting/rules/_find`) + .set('kbn-xsrf', 'foo') + .send({ + rule_type_ids: ['test.restricted-noop'], + }); + + expect(response.status).to.eql(200); + expect(response.body.total).to.equal(1); + expect(response.body.data[0].rule_type_id).to.eql('test.restricted-noop'); + }); + + it('should filter rules by consumers', async () => { + await createAlert(objectRemover, supertest, { + rule_type_id: 'test.noop', + consumer: 'alertsFixture', + }); + + await createAlert(objectRemover, supertest, { + rule_type_id: 'test.restricted-noop', + consumer: 'alertsRestrictedFixture', + }); + + const response = await supertest + .post(`${getUrlPrefix(Spaces.space1.id)}/internal/alerting/rules/_find`) + .set('kbn-xsrf', 'foo') + .send({ + consumers: ['alertsRestrictedFixture'], + }); + + expect(response.status).to.eql(200); + expect(response.body.total).to.equal(1); + expect(response.body.data[0].consumer).to.eql('alertsRestrictedFixture'); }); describe('legacy', function () { @@ -309,11 +348,7 @@ export default function createFindTests({ getService }: FtrProviderContext) { .expect(200); objectRemover.add(Spaces.space1.id, createdAlert.id, 'rule', 'alerting'); - const response = await supertest.get( - `${getUrlPrefix( - Spaces.space1.id - )}/api/alerts/_find?search=test.noop&search_fields=alertTypeId` - ); + const response = await supertest.get(`${getUrlPrefix(Spaces.space1.id)}/api/alerts/_find`); expect(response.status).to.eql(200); expect(response.body.page).to.equal(1); diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group1/index.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group1/index.ts index 7a0c24878d07f..d750fd7bcfb4e 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group1/index.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group1/index.ts @@ -14,12 +14,13 @@ export default function alertingTests({ loadTestFile, getService }: FtrProviderC before(async () => await buildUp(getService)); after(async () => await tearDown(getService)); - loadTestFile(require.resolve('./aggregate_post')); + loadTestFile(require.resolve('./aggregate')); loadTestFile(require.resolve('./create')); loadTestFile(require.resolve('./delete')); loadTestFile(require.resolve('./disable')); loadTestFile(require.resolve('./enable')); loadTestFile(require.resolve('./find')); + loadTestFile(require.resolve('./find_internal')); loadTestFile(require.resolve('./get')); loadTestFile(require.resolve('./get_alert_state')); loadTestFile(require.resolve('./get_alert_summary')); diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group4/ephemeral.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group4/ephemeral.ts deleted file mode 100644 index 51149a3008ff0..0000000000000 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group4/ephemeral.ts +++ /dev/null @@ -1,124 +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 { flatten } from 'lodash'; -import { IValidatedEvent } from '@kbn/event-log-plugin/server'; -import { DEFAULT_MAX_EPHEMERAL_ACTIONS_PER_ALERT } from '@kbn/alerting-plugin/server/config'; -import { ESTestIndexTool, ES_TEST_INDEX_NAME } from '@kbn/alerting-api-integration-helpers'; -import { Spaces } from '../../../scenarios'; -import { getUrlPrefix, ObjectRemover, getTestRuleData, getEventLog } from '../../../../common/lib'; -import { FtrProviderContext } from '../../../../common/ftr_provider_context'; - -// eslint-disable-next-line import/no-default-export -export default function createNotifyWhenTests({ getService }: FtrProviderContext) { - const supertest = getService('supertest'); - const retry = getService('retry'); - const es = getService('es'); - - const esTestIndexTool = new ESTestIndexTool(es, retry); - - describe('ephemeral', () => { - const objectRemover = new ObjectRemover(supertest); - - beforeEach(async () => { - await esTestIndexTool.destroy(); - await esTestIndexTool.setup(); - }); - afterEach(async () => await esTestIndexTool.destroy()); - after(async () => { - await objectRemover.removeAll(); - }); - - it('should execute all requests, when some will be ephemeral and some not', async () => { - const nonEphemeralTasks = 3; - const actionPromises = []; - for (let i = 0; i < DEFAULT_MAX_EPHEMERAL_ACTIONS_PER_ALERT + nonEphemeralTasks; i++) { - actionPromises.push( - supertest - .post(`${getUrlPrefix(Spaces.space1.id)}/api/actions/connector`) - .set('kbn-xsrf', 'foo') - .send({ - name: `My action${i}`, - connector_type_id: 'test.index-record', - config: { - unencrypted: `This value shouldn't get encrypted`, - }, - secrets: { - encrypted: 'This value should be encrypted', - }, - }) - .expect(200) - ); - } - const createdActions = await Promise.all(actionPromises); - createdActions.forEach((createdAction) => - objectRemover.add(Spaces.space1.id, createdAction.body.id, 'connector', 'actions') - ); - - const pattern = { - instance: [true, true, true, false, true, true], - }; - const alertData = getTestRuleData({ - rule_type_id: 'test.patternFiring', - params: { pattern }, - schedule: { interval: '1m' }, - throttle: null, - notify_when: 'onActiveAlert', - actions: createdActions.map((createdAction) => { - return { - id: createdAction.body.id, - group: 'default', - params: { - index: ES_TEST_INDEX_NAME, - reference: '', - message: 'test message', - }, - }; - }), - }); - const { body: createdAlert } = await supertest - .post(`${getUrlPrefix(Spaces.space1.id)}/api/alerting/rule`) - .set('kbn-xsrf', 'foo') - .send(alertData) - .expect(200); - objectRemover.add(Spaces.space1.id, createdAlert.id, 'rule', 'alerting'); - - const events = flatten( - await Promise.all( - createdActions.map(async (createdAction) => { - return await retry.try(async () => { - return await getEventLog({ - getService, - spaceId: Spaces.space1.id, - type: 'action', - id: createdAction.body.id, - provider: 'actions', - actions: new Map([['execute', { gte: 1 }]]), - }); - }); - }) - ) - ); - - const executeActionsEvents = getEventsByAction(events, 'execute'); - expect(executeActionsEvents.length).equal( - nonEphemeralTasks + DEFAULT_MAX_EPHEMERAL_ACTIONS_PER_ALERT - ); - - const searchResult = await esTestIndexTool.search('action:test.index-record'); - // @ts-expect-error doesnt handle total: number - expect(searchResult.body.hits.total.value).equal( - nonEphemeralTasks + DEFAULT_MAX_EPHEMERAL_ACTIONS_PER_ALERT - ); - }); - }); -} - -function getEventsByAction(events: IValidatedEvent[], action: string) { - return events.filter((event) => event?.event?.action === action); -} diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group4/index.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group4/index.ts index 79dae86b6a8d5..1da03fbbcc54c 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group4/index.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group4/index.ts @@ -18,7 +18,6 @@ export default function alertingTests({ loadTestFile, getService }: FtrProviderC loadTestFile(require.resolve('./builtin_alert_types')); loadTestFile(require.resolve('./mustache_templates.ts')); loadTestFile(require.resolve('./notify_when')); - loadTestFile(require.resolve('./ephemeral')); loadTestFile(require.resolve('./event_log_alerts')); loadTestFile(require.resolve('./snooze')); loadTestFile(require.resolve('./unsnooze')); diff --git a/x-pack/test/api_integration/apis/security/privileges.ts b/x-pack/test/api_integration/apis/security/privileges.ts index b269aef6ae1cc..dc84f6c33d200 100644 --- a/x-pack/test/api_integration/apis/security/privileges.ts +++ b/x-pack/test/api_integration/apis/security/privileges.ts @@ -91,7 +91,14 @@ export default function ({ getService }: FtrProviderContext) { 'execute_operations_all', 'scan_operations_all', ], - uptime: ['all', 'read', 'minimal_all', 'minimal_read', 'elastic_managed_locations_enabled'], + uptime: [ + 'all', + 'read', + 'minimal_all', + 'minimal_read', + 'elastic_managed_locations_enabled', + 'can_manage_private_locations', + ], securitySolutionAssistant: [ 'all', 'read', diff --git a/x-pack/test/api_integration/apis/security/privileges_basic.ts b/x-pack/test/api_integration/apis/security/privileges_basic.ts index a97ee360062c0..2bbd70fcf730d 100644 --- a/x-pack/test/api_integration/apis/security/privileges_basic.ts +++ b/x-pack/test/api_integration/apis/security/privileges_basic.ts @@ -178,6 +178,7 @@ export default function ({ getService }: FtrProviderContext) { ], uptime: [ 'all', + 'can_manage_private_locations', 'elastic_managed_locations_enabled', 'read', 'minimal_all', diff --git a/x-pack/test/api_integration/apis/synthetics/private_location_apis.ts b/x-pack/test/api_integration/apis/synthetics/private_location_apis.ts index 415c91af28347..a4351ede2eda0 100644 --- a/x-pack/test/api_integration/apis/synthetics/private_location_apis.ts +++ b/x-pack/test/api_integration/apis/synthetics/private_location_apis.ts @@ -11,16 +11,21 @@ import { legacyPrivateLocationsSavedObjectName, privateLocationSavedObjectName, } from '@kbn/synthetics-plugin/common/saved_objects/private_locations'; +import { SYNTHETICS_API_URLS } from '@kbn/synthetics-plugin/common/constants'; +import { PrivateLocation } from '@kbn/synthetics-plugin/common/runtime_types'; +import { SyntheticsMonitorTestService } from './services/synthetics_monitor_test_service'; import { FtrProviderContext } from '../../ftr_provider_context'; import { PrivateLocationTestService } from './services/private_location_test_service'; export default function ({ getService }: FtrProviderContext) { describe('PrivateLocationAPI', function () { this.tags('skipCloud'); + const supertestWithoutAuth = getService('supertestWithoutAuth'); const kServer = getService('kibanaServer'); const testPrivateLocations = new PrivateLocationTestService(getService); + const monitorTestService = new SyntheticsMonitorTestService(getService); before(async () => { await testPrivateLocations.installSyntheticsPackage(); @@ -60,5 +65,72 @@ export default function ({ getService }: FtrProviderContext) { expect(e.response.status).to.be(404); } }); + + it('cannot create private location if privileges are missing', async () => { + const apiResponse = await testPrivateLocations.addFleetPolicy(); + const agentPolicyId = apiResponse.body.item.id; + + const { username, password } = await monitorTestService.addsNewSpace(['minimal_all']); + + const location: Omit = { + label: 'Test private location 10', + agentPolicyId: agentPolicyId!, + geo: { + lat: 0, + lon: 0, + }, + }; + const response = await supertestWithoutAuth + .post(SYNTHETICS_API_URLS.PRIVATE_LOCATIONS) + .auth(username, password) + .set('kbn-xsrf', 'true') + .send(location); + + expect(response.status).to.be(403); + }); + + it('can create private location if privileges are added', async () => { + const apiResponse = await testPrivateLocations.addFleetPolicy(); + const agentPolicyId = apiResponse.body.item.id; + + const { username, password } = await monitorTestService.addsNewSpace([ + 'minimal_all', + 'can_manage_private_locations', + ]); + + const location: Omit = { + label: 'Test private location 10', + agentPolicyId: agentPolicyId!, + geo: { + lat: 0, + lon: 0, + }, + }; + const response = await supertestWithoutAuth + .post(SYNTHETICS_API_URLS.PRIVATE_LOCATIONS) + .auth(username, password) + .set('kbn-xsrf', 'true') + .send(location); + + expect(response.status).to.be(200); + }); + + it('can delete private location if privileges are added', async () => { + const locs = await testPrivateLocations.fetchAll(); + + const { username, password } = await monitorTestService.addsNewSpace([ + 'minimal_all', + 'can_manage_private_locations', + ]); + + for (const loc of locs.body) { + const deleteResponse = await supertestWithoutAuth + .delete(`${SYNTHETICS_API_URLS.PRIVATE_LOCATIONS}/${loc.id}`) + .auth(username, password) + .set('kbn-xsrf', 'true'); + + expect(deleteResponse.status).to.be(200); + } + }); }); } diff --git a/x-pack/test/api_integration/apis/synthetics/synthetics_api_security.ts b/x-pack/test/api_integration/apis/synthetics/synthetics_api_security.ts index ddd0d4b209940..3969dcae88219 100644 --- a/x-pack/test/api_integration/apis/synthetics/synthetics_api_security.ts +++ b/x-pack/test/api_integration/apis/synthetics/synthetics_api_security.ts @@ -33,12 +33,18 @@ export default function ({ getService }: FtrProviderContext) { password: string; writeAccess?: boolean; tags?: string; + readUser?: boolean; } ) => { let resp; - const { statusCodes, SPACE_ID, username, password, writeAccess } = options; - const tags = !writeAccess ? '[uptime-read]' : options.tags ?? '[uptime-read,uptime-write]'; - const getStatusMessage = (respStatus: string) => + const { statusCodes, SPACE_ID, username, password, writeAccess, readUser } = options; + let tags = !writeAccess ? '[uptime-read]' : options.tags ?? '[uptime-read,uptime-write]'; + if ((method === 'POST' || method === 'DELETE') && path.includes('private_locations')) { + tags = readUser + ? '[private-location-write,uptime-write]' + : '[uptime-read,private-location-write,uptime-write]'; + } + const getStatusMessage = (respStatus: string | number) => `Expected ${statusCodes?.join( ',' )}, got ${respStatus} status code doesn't match, for path: ${path} and method ${method}`; @@ -132,6 +138,7 @@ export default function ({ getService }: FtrProviderContext) { password, writeAccess: route.writeAccess ?? true, tags: '[uptime-write]', + readUser: true, }); } }); diff --git a/x-pack/test/api_integration/apis/upgrade_assistant/config.ts b/x-pack/test/api_integration/apis/upgrade_assistant/config.ts index 5f335f116fefe..762cb8baa1ef2 100644 --- a/x-pack/test/api_integration/apis/upgrade_assistant/config.ts +++ b/x-pack/test/api_integration/apis/upgrade_assistant/config.ts @@ -13,5 +13,15 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) { return { ...baseIntegrationTestsConfig.getAll(), testFiles: [require.resolve('.')], + kbnTestServer: { + ...baseIntegrationTestsConfig.get('kbnTestServer'), + serverArgs: [ + ...baseIntegrationTestsConfig.get('kbnTestServer.serverArgs'), + '--xpack.upgrade_assistant.featureSet.mlSnapshots=true', + '--xpack.upgrade_assistant.featureSet.migrateSystemIndices=true', + '--xpack.upgrade_assistant.featureSet.migrateDataStreams=true', + '--xpack.upgrade_assistant.featureSet.reindexCorrectiveActions=true', + ], + }, }; } diff --git a/x-pack/test/api_integration/apis/upgrade_assistant/upgrade_assistant.ts b/x-pack/test/api_integration/apis/upgrade_assistant/upgrade_assistant.ts index 7d7e035741bbb..f03cb6fb80e37 100644 --- a/x-pack/test/api_integration/apis/upgrade_assistant/upgrade_assistant.ts +++ b/x-pack/test/api_integration/apis/upgrade_assistant/upgrade_assistant.ts @@ -14,8 +14,7 @@ export default function ({ getService }: FtrProviderContext) { const es = getService('es'); const supertest = getService('supertest'); - // Failing: See https://github.com/elastic/kibana/issues/199719 - describe.skip('Upgrade Assistant', function () { + describe('Upgrade Assistant', function () { describe('Reindex operation saved object', () => { const dotKibanaIndex = '.kibana'; const fakeSavedObjectId = 'fakeSavedObjectId'; diff --git a/x-pack/test/api_integration/deployment_agnostic/apis/observability/dataset_quality/check_and_load_integration.ts b/x-pack/test/api_integration/deployment_agnostic/apis/observability/dataset_quality/check_and_load_integration.ts new file mode 100644 index 0000000000000..801b5cde58833 --- /dev/null +++ b/x-pack/test/api_integration/deployment_agnostic/apis/observability/dataset_quality/check_and_load_integration.ts @@ -0,0 +1,175 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { log, timerange } from '@kbn/apm-synthtrace-client'; +import expect from '@kbn/expect'; + +import { LogsSynthtraceEsClient } from '@kbn/apm-synthtrace'; +import { DeploymentAgnosticFtrProviderContext } from '../../../ftr_provider_context'; +import { RoleCredentials, SupertestWithRoleScopeType } from '../../../services'; + +export default function ({ getService }: DeploymentAgnosticFtrProviderContext) { + const samlAuth = getService('samlAuth'); + const roleScopedSupertest = getService('roleScopedSupertest'); + const synthtrace = getService('synthtrace'); + const packageApi = getService('packageApi'); + const start = '2024-11-04T11:00:00.000Z'; + const end = '2024-11-04T11:01:00.000Z'; + const type = 'logs'; + const dataset = 'synth'; + const nginxDataset = 'nginx.access'; + const apmDataset = 'apm.app.test'; + const namespace = 'default'; + const serviceName = 'my-service'; + const hostName = 'synth-host'; + const dataStreamName = `${type}-${dataset}-${namespace}`; + const nginxDataStreamName = `${type}-${nginxDataset}-${namespace}`; + const apmAppDataStreamName = `${type}-${apmDataset}-${namespace}`; + + const pkg = 'nginx'; + + async function callApiAs({ + roleScopedSupertestWithCookieCredentials, + apiParams: { dataStream }, + }: { + roleScopedSupertestWithCookieCredentials: SupertestWithRoleScopeType; + apiParams: { + dataStream: string; + }; + }) { + return roleScopedSupertestWithCookieCredentials.get( + `/internal/dataset_quality/data_streams/${dataStream}/integration/check` + ); + } + + describe('Check and load integrations', function () { + let adminRoleAuthc: RoleCredentials; + let supertestAdminWithCookieCredentials: SupertestWithRoleScopeType; + let synthtraceLogsEsClient: LogsSynthtraceEsClient; + + before(async () => { + synthtraceLogsEsClient = await synthtrace.createLogsSynthtraceEsClient(); + adminRoleAuthc = await samlAuth.createM2mApiKeyWithRoleScope('admin'); + supertestAdminWithCookieCredentials = await roleScopedSupertest.getSupertestWithRoleScope( + 'admin', + { + useCookieHeader: true, + withInternalHeaders: true, + } + ); + // Install nginx package + await packageApi.installPackage({ + roleAuthc: adminRoleAuthc, + pkg, + }); + + await synthtraceLogsEsClient.index([ + // Ingest degraded data in Nginx data stream + timerange(start, end) + .interval('1m') + .rate(1) + .generator((timestamp) => + log + .create() + .message('This is a log message') + .timestamp(timestamp) + .dataset(nginxDataset) + .namespace(namespace) + .defaults({ + 'log.file.path': '/my-service.log', + 'service.name': serviceName, + 'host.name': hostName, + }) + ), + // ingest data in apm app data stream + timerange(start, end) + .interval('1m') + .rate(1) + .generator((timestamp) => + log + .create() + .message('This is a log message') + .timestamp(timestamp) + .dataset(apmDataset) + .namespace(namespace) + .defaults({ + 'log.file.path': '/my-service.log', + 'service.name': serviceName, + 'host.name': hostName, + }) + ), + + // Ingest data in regular datastream which is not an integration + timerange(start, end) + .interval('1m') + .rate(1) + .generator((timestamp) => + log + .create() + .message('This is a log message') + .timestamp(timestamp) + .dataset(dataset) + .namespace(namespace) + .defaults({ + 'log.file.path': '/my-service.log', + 'service.name': serviceName, + 'host.name': hostName, + }) + ), + ]); + }); + + after(async () => { + await synthtraceLogsEsClient.clean(); + await packageApi.uninstallPackage({ + roleAuthc: adminRoleAuthc, + pkg, + }); + await samlAuth.invalidateM2mApiKeyWithRoleScope(adminRoleAuthc); + }); + + describe('returns integration status', () => { + it('returns integration as false for regular data stream', async () => { + const resp = await callApiAs({ + roleScopedSupertestWithCookieCredentials: supertestAdminWithCookieCredentials, + apiParams: { + dataStream: dataStreamName, + }, + }); + + expect(resp.body.isIntegration).to.be(false); + expect(resp.body.areAssetsAvailable).to.be(false); + }); + + it('returns integration as true for nginx data stream as we installed the integration', async () => { + const resp = await callApiAs({ + roleScopedSupertestWithCookieCredentials: supertestAdminWithCookieCredentials, + apiParams: { + dataStream: nginxDataStreamName, + }, + }); + + expect(resp.body.isIntegration).to.be(true); + expect(resp.body.areAssetsAvailable).to.be(true); + expect(resp.body.integration.name).to.be(pkg); + expect(resp.body.integration.datasets[nginxDataset]).to.be.a('string'); + }); + + it('returns integration as false but assets are available for apm.app data stream as its preinstalled', async () => { + const resp = await callApiAs({ + roleScopedSupertestWithCookieCredentials: supertestAdminWithCookieCredentials, + apiParams: { + dataStream: apmAppDataStreamName, + }, + }); + + expect(resp.body.isIntegration).to.be(false); + expect(resp.body.areAssetsAvailable).to.be(true); + }); + }); + }); +} diff --git a/x-pack/test/api_integration/deployment_agnostic/apis/observability/dataset_quality/index.ts b/x-pack/test/api_integration/deployment_agnostic/apis/observability/dataset_quality/index.ts index 0481e882aee6e..17ce93321b511 100644 --- a/x-pack/test/api_integration/deployment_agnostic/apis/observability/dataset_quality/index.ts +++ b/x-pack/test/api_integration/deployment_agnostic/apis/observability/dataset_quality/index.ts @@ -14,6 +14,7 @@ export default function ({ loadTestFile }: DeploymentAgnosticFtrProviderContext) loadTestFile(require.resolve('./data_stream_settings')); loadTestFile(require.resolve('./data_stream_rollover')); loadTestFile(require.resolve('./update_field_limit')); + loadTestFile(require.resolve('./check_and_load_integration')); loadTestFile(require.resolve('./data_stream_total_docs')); loadTestFile(require.resolve('./degraded_docs')); loadTestFile(require.resolve('./degraded_fields')); diff --git a/x-pack/test/api_integration/services/security_solution_api.gen.ts b/x-pack/test/api_integration/services/security_solution_api.gen.ts index 3574199709aee..a0b1bf74926b4 100644 --- a/x-pack/test/api_integration/services/security_solution_api.gen.ts +++ b/x-pack/test/api_integration/services/security_solution_api.gen.ts @@ -80,7 +80,7 @@ import { GetEndpointSuggestionsRequestBodyInput, } from '@kbn/security-solution-plugin/common/api/endpoint/suggestions/get_suggestions.gen'; import { GetEntityEngineRequestParamsInput } from '@kbn/security-solution-plugin/common/api/entity_analytics/entity_store/engine/get.gen'; -import { GetEntityEngineStatsRequestParamsInput } from '@kbn/security-solution-plugin/common/api/entity_analytics/entity_store/engine/stats.gen'; +import { GetEntityStoreStatusRequestQueryInput } from '@kbn/security-solution-plugin/common/api/entity_analytics/entity_store/status.gen'; import { GetNotesRequestQueryInput } from '@kbn/security-solution-plugin/common/api/timeline/get_notes/get_notes_route.gen'; import { GetPolicyResponseRequestQueryInput } from '@kbn/security-solution-plugin/common/api/endpoint/policy/policy_response.gen'; import { GetProtectionUpdatesNoteRequestParamsInput } from '@kbn/security-solution-plugin/common/api/endpoint/protection_updates_note/protection_updates_note.gen'; @@ -106,8 +106,13 @@ import { InitEntityEngineRequestParamsInput, InitEntityEngineRequestBodyInput, } from '@kbn/security-solution-plugin/common/api/entity_analytics/entity_store/engine/init.gen'; -import { InitEntityStoreRequestBodyInput } from '@kbn/security-solution-plugin/common/api/entity_analytics/entity_store/enablement.gen'; +import { InitEntityStoreRequestBodyInput } from '@kbn/security-solution-plugin/common/api/entity_analytics/entity_store/enable.gen'; +import { + InstallMigrationRulesRequestParamsInput, + InstallMigrationRulesRequestBodyInput, +} from '@kbn/security-solution-plugin/common/siem_migrations/model/api/rules/rule_migration.gen'; import { InstallPrepackedTimelinesRequestBodyInput } from '@kbn/security-solution-plugin/common/api/timeline/install_prepackaged_timelines/install_prepackaged_timelines_route.gen'; +import { InstallTranslatedMigrationRulesRequestParamsInput } from '@kbn/security-solution-plugin/common/siem_migrations/model/api/rules/rule_migration.gen'; import { ListEntitiesRequestQueryInput } from '@kbn/security-solution-plugin/common/api/entity_analytics/entity_store/entities/list_entities.gen'; import { PatchRuleRequestBodyInput } from '@kbn/security-solution-plugin/common/api/detection_engine/rule_management/crud/patch_rule/patch_rule_route.gen'; import { PatchTimelineRequestBodyInput } from '@kbn/security-solution-plugin/common/api/timeline/patch_timelines/patch_timeline_route.gen'; @@ -832,24 +837,13 @@ finalize it. .set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31') .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana'); }, - getEntityEngineStats(props: GetEntityEngineStatsProps, kibanaSpace: string = 'default') { - return supertest - .post( - routeWithNamespace( - replaceParams('/api/entity_store/engines/{entityType}/stats', props.params), - kibanaSpace - ) - ) - .set('kbn-xsrf', 'true') - .set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31') - .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana'); - }, - getEntityStoreStatus(kibanaSpace: string = 'default') { + getEntityStoreStatus(props: GetEntityStoreStatusProps, kibanaSpace: string = 'default') { return supertest .get(routeWithNamespace('/api/entity_store/status', kibanaSpace)) .set('kbn-xsrf', 'true') .set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31') - .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana'); + .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') + .query(props.query); }, /** * Get all notes for a given document. @@ -1057,6 +1051,22 @@ finalize it. .set(ELASTIC_HTTP_VERSION_HEADER, '1') .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana'); }, + /** + * Installs migration rules + */ + installMigrationRules(props: InstallMigrationRulesProps, kibanaSpace: string = 'default') { + return supertest + .post( + routeWithNamespace( + replaceParams('/internal/siem_migrations/rules/{migration_id}/install', props.params), + kibanaSpace + ) + ) + .set('kbn-xsrf', 'true') + .set(ELASTIC_HTTP_VERSION_HEADER, '1') + .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') + .send(props.body as object); + }, /** * Install and update all Elastic prebuilt detection rules and Timelines. */ @@ -1081,6 +1091,27 @@ finalize it. .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') .send(props.body as object); }, + /** + * Installs all translated migration rules + */ + installTranslatedMigrationRules( + props: InstallTranslatedMigrationRulesProps, + kibanaSpace: string = 'default' + ) { + return supertest + .post( + routeWithNamespace( + replaceParams( + '/internal/siem_migrations/rules/{migration_id}/install_translated', + props.params + ), + kibanaSpace + ) + ) + .set('kbn-xsrf', 'true') + .set(ELASTIC_HTTP_VERSION_HEADER, '1') + .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana'); + }, internalUploadAssetCriticalityRecords(kibanaSpace: string = 'default') { return supertest .post(routeWithNamespace('/internal/asset_criticality/upload_csv', kibanaSpace)) @@ -1615,8 +1646,8 @@ export interface GetEndpointSuggestionsProps { export interface GetEntityEngineProps { params: GetEntityEngineRequestParamsInput; } -export interface GetEntityEngineStatsProps { - params: GetEntityEngineStatsRequestParamsInput; +export interface GetEntityStoreStatusProps { + query: GetEntityStoreStatusRequestQueryInput; } export interface GetNotesProps { query: GetNotesRequestQueryInput; @@ -1664,9 +1695,16 @@ export interface InitEntityEngineProps { export interface InitEntityStoreProps { body: InitEntityStoreRequestBodyInput; } +export interface InstallMigrationRulesProps { + params: InstallMigrationRulesRequestParamsInput; + body: InstallMigrationRulesRequestBodyInput; +} export interface InstallPrepackedTimelinesProps { body: InstallPrepackedTimelinesRequestBodyInput; } +export interface InstallTranslatedMigrationRulesProps { + params: InstallTranslatedMigrationRulesRequestParamsInput; +} export interface ListEntitiesProps { query: ListEntitiesRequestQueryInput; } diff --git a/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/attachments_framework/registered_persistable_state_trial.ts b/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/attachments_framework/registered_persistable_state_trial.ts index 0969a9261df26..bc618b1beab42 100644 --- a/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/attachments_framework/registered_persistable_state_trial.ts +++ b/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/attachments_framework/registered_persistable_state_trial.ts @@ -40,6 +40,7 @@ export default ({ getService }: FtrProviderContext): void => { ml_anomaly_swimlane: 'a3517f3e53fb041e9cbb150477fb6ef0f731bd5f', ml_single_metric_viewer: '8b9532b0a40dfdfa282e262949b82cc1a643147c', aiopsPatternAnalysisEmbeddable: '6c2809a0c51e668d11794de0815b293fdb3a9060', + aiopsLogRateAnalysisEmbeddable: '6a2e9953140fa8e89f82c394d8bff3c1a5aefe66', }); }); }); diff --git a/x-pack/test/common/services/search_secure.ts b/x-pack/test/common/services/search_secure.ts index f46e9e57ef275..9f25140df5d23 100644 --- a/x-pack/test/common/services/search_secure.ts +++ b/x-pack/test/common/services/search_secure.ts @@ -44,10 +44,12 @@ export class SearchSecureService extends FtrService { space, }: SendOptions) { const spaceUrl = getSpaceUrlPrefix(space); + const statusesWithoutRetry = [200, 400, 403, 500]; const { body } = await this.retry.try(async () => { let result; const url = `${spaceUrl}/internal/search/${strategy}`; + if (referer && kibanaVersion) { result = await supertestWithoutAuth .post(url) @@ -89,9 +91,11 @@ export class SearchSecureService extends FtrService { .set('kbn-xsrf', 'true') .send(options); } - if ((result.status === 500 || result.status === 200) && result.body) { + + if (statusesWithoutRetry.includes(result.status) && result.body) { return result; } + throw new Error('try again'); }); diff --git a/x-pack/test/functional/apps/aiops/index.ts b/x-pack/test/functional/apps/aiops/index.ts index 5397a80c85bd0..981ae301a6dc5 100644 --- a/x-pack/test/functional/apps/aiops/index.ts +++ b/x-pack/test/functional/apps/aiops/index.ts @@ -32,6 +32,7 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) { loadTestFile(require.resolve('./log_rate_analysis')); loadTestFile(require.resolve('./log_rate_analysis_anomaly_table')); loadTestFile(require.resolve('./log_rate_analysis_dashboard_embeddable')); + loadTestFile(require.resolve('./log_rate_analysis_cases')); loadTestFile(require.resolve('./change_point_detection')); loadTestFile(require.resolve('./change_point_detection_dashboard')); loadTestFile(require.resolve('./change_point_detection_cases')); diff --git a/x-pack/test/functional/apps/aiops/log_rate_analysis_cases.ts b/x-pack/test/functional/apps/aiops/log_rate_analysis_cases.ts new file mode 100644 index 0000000000000..07c632ea7df0d --- /dev/null +++ b/x-pack/test/functional/apps/aiops/log_rate_analysis_cases.ts @@ -0,0 +1,67 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor 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 { USER } from '../../services/ml/security_common'; +import { logRateAnalysisTestData } from './log_rate_analysis_test_data'; + +export default function ({ getPageObjects, getService }: FtrProviderContext) { + const elasticChart = getService('elasticChart'); + const aiops = getService('aiops'); + const cases = getService('cases'); + + const testData = logRateAnalysisTestData[0]; + + // aiops lives in the ML UI so we need some related services. + const ml = getService('ml'); + + describe('log rate analysis in cases', function () { + before(async () => { + await aiops.logRateAnalysisDataGenerator.generateData(testData.dataGenerator); + await ml.testResources.setKibanaTimeZoneToUTC(); + await ml.securityUI.loginAsMlPowerUser(); + await ml.testResources.createDataViewIfNeeded( + testData.sourceIndexOrSavedSearch, + '@timestamp' + ); + await elasticChart.setNewChartUiDebugFlag(true); + await ml.navigation.navigateToMl(); + }); + + after(async () => { + await ml.testResources.deleteDataViewByTitle(testData.sourceIndexOrSavedSearch); + await aiops.logRateAnalysisDataGenerator.removeGeneratedData(testData.dataGenerator); + await elasticChart.setNewChartUiDebugFlag(false); + await cases.api.deleteAllCases(); + }); + + it('attaches log rate analysis to a case', async () => { + await aiops.logRateAnalysisPage.navigateToDataViewSelection(); + await ml.jobSourceSelection.selectSourceForLogRateAnalysis(testData.sourceIndexOrSavedSearch); + + await aiops.logRateAnalysisPage.openAttachmentsMenu(); + await aiops.logRateAnalysisPage.assertAttachToCaseButtonDisabled(); + + await aiops.logRateAnalysisPage.clickUseFullDataButton( + testData.expected.totalDocCountFormatted + ); + + await aiops.logRateAnalysisPage.clickDocumentCountChart(testData.chartClickCoordinates); + + const caseParams = { + title: 'Log rate analysis case', + description: 'Case with log rate analysis attachment', + tag: 'ml_log_rate_analysis', + reporter: USER.ML_POWERUSER, + }; + + await aiops.logRateAnalysisPage.attachToCase(caseParams); + + await ml.cases.assertCaseWithLogRateAnalysisAttachment(caseParams); + }); + }); +} diff --git a/x-pack/test/functional/apps/dashboard/group3/reporting/screenshots.ts b/x-pack/test/functional/apps/dashboard/group3/reporting/screenshots.ts index 60a7f754933de..42c933f8792a8 100644 --- a/x-pack/test/functional/apps/dashboard/group3/reporting/screenshots.ts +++ b/x-pack/test/functional/apps/dashboard/group3/reporting/screenshots.ts @@ -221,7 +221,6 @@ export default function ({ }); it('downloads a PDF file with saved search given EuiDataGrid enabled', async function () { - await kibanaServer.uiSettings.update({ 'doc_table:legacy': false }); this.timeout(300000); await dashboard.navigateToApp(); await dashboard.loadSavedDashboard('Ecom Dashboard'); diff --git a/x-pack/test/functional/apps/dataset_quality/dataset_quality_details.ts b/x-pack/test/functional/apps/dataset_quality/dataset_quality_details.ts index 01dbbe1a0fc80..28a7cc9a9963d 100644 --- a/x-pack/test/functional/apps/dataset_quality/dataset_quality_details.ts +++ b/x-pack/test/functional/apps/dataset_quality/dataset_quality_details.ts @@ -250,7 +250,7 @@ export default function ({ getService, getPageObjects }: DatasetQualityFtrProvid ); }); - it('Should navigate to integration overview page on clicking integration overview action', async () => { + it('should navigate to integration overview page on clicking integration overview action', async () => { await PageObjects.datasetQuality.navigateToDetails({ dataStream: bitbucketAuditDataStreamName, }); @@ -359,7 +359,7 @@ export default function ({ getService, getPageObjects }: DatasetQualityFtrProvid ); }); - it('should show the degraded fields table with data when present', async () => { + it('should show the degraded fields table with data and spark plots when present', async () => { await PageObjects.datasetQuality.navigateToDetails({ dataStream: degradedDataStreamName, }); @@ -372,15 +372,6 @@ export default function ({ getService, getPageObjects }: DatasetQualityFtrProvid await PageObjects.datasetQuality.getDatasetQualityDetailsDegradedFieldTableRows(); expect(rows.length).to.eql(3); - }); - - it('should display Spark Plot for every row of degraded fields', async () => { - await PageObjects.datasetQuality.navigateToDetails({ - dataStream: degradedDataStreamName, - }); - - const rows = - await PageObjects.datasetQuality.getDatasetQualityDetailsDegradedFieldTableRows(); const sparkPlots = await testSubjects.findAll( PageObjects.datasetQuality.testSubjectSelectors.datasetQualitySparkPlot diff --git a/x-pack/test/functional/apps/dataset_quality/degraded_field_flyout.ts b/x-pack/test/functional/apps/dataset_quality/degraded_field_flyout.ts index f5d695b8f165c..19a2001603925 100644 --- a/x-pack/test/functional/apps/dataset_quality/degraded_field_flyout.ts +++ b/x-pack/test/functional/apps/dataset_quality/degraded_field_flyout.ts @@ -42,13 +42,16 @@ export default function ({ getService, getPageObjects }: DatasetQualityFtrProvid const customComponentTemplateName = 'logs-synth@mappings'; const nginxAccessDatasetName = 'nginx.access'; - const customComponentTemplateNameNginx = 'logs-nginx.access@custom'; + const customComponentTemplateNameNginx = `logs-${nginxAccessDatasetName}@custom`; const nginxAccessDataStreamName = `${type}-${nginxAccessDatasetName}-${defaultNamespace}`; const nginxPkg = { name: 'nginx', version: '1.23.0', }; + const apmAppDatasetName = 'apm.app.tug'; + const apmAppDataStreamName = `${type}-${apmAppDatasetName}-${defaultNamespace}`; + describe('Degraded fields flyout', () => { describe('degraded field flyout open-close', () => { before(async () => { @@ -131,7 +134,7 @@ export default function ({ getService, getPageObjects }: DatasetQualityFtrProvid // Install Nginx Integration and ingest logs for it await PageObjects.observabilityLogsExplorer.installPackage(nginxPkg); - // Create custom component template to avoid issues with LogsDB + // Create custom component template for Nginx to avoid issues with LogsDB await synthtrace.createComponentTemplate( customComponentTemplateNameNginx, logsNginxMappings(nginxAccessDatasetName) @@ -184,6 +187,29 @@ export default function ({ getService, getPageObjects }: DatasetQualityFtrProvid .timestamp(timestamp) ); }), + // Ingest Degraded Logs with 26 fields in Apm DataSet + timerange(moment(to).subtract(count, 'minute'), moment(to)) + .interval('1m') + .rate(1) + .generator((timestamp) => { + return Array(1) + .fill(0) + .flatMap(() => + log + .create() + .dataset(apmAppDatasetName) + .message('a log message') + .logLevel(MORE_THAN_1024_CHARS) + .service(serviceName) + .namespace(defaultNamespace) + .defaults({ + 'service.name': serviceName, + 'trace.id': generateShortId(), + test_field: [MORE_THAN_1024_CHARS, ANOTHER_1024_CHARS], + }) + .timestamp(timestamp) + ); + }), ]); // Set Limit of 25 @@ -199,6 +225,11 @@ export default function ({ getService, getPageObjects }: DatasetQualityFtrProvid 'mapping.total_fields.limit': 42, }); + // Set Limit of 26 + await PageObjects.datasetQuality.setDataStreamSettings(apmAppDataStreamName, { + 'mapping.total_fields.limit': 25, + }); + await synthtrace.index([ // Ingest Degraded Logs with 26 field timerange(moment(to).subtract(count, 'minute'), moment(to)) @@ -248,11 +279,36 @@ export default function ({ getService, getPageObjects }: DatasetQualityFtrProvid .timestamp(timestamp) ); }), + // Ingest Degraded Logs with 27 fields in Apm APP DataSet + timerange(moment(to).subtract(count, 'minute'), moment(to)) + .interval('1m') + .rate(1) + .generator((timestamp) => { + return Array(1) + .fill(0) + .flatMap(() => + log + .create() + .dataset(apmAppDatasetName) + .message('a log message') + .logLevel(MORE_THAN_1024_CHARS) + .service(serviceName) + .namespace(defaultNamespace) + .defaults({ + 'service.name': serviceName, + 'trace.id': generateShortId(), + test_field: [MORE_THAN_1024_CHARS, ANOTHER_1024_CHARS], + 'cloud.project.id': generateShortId(), + }) + .timestamp(timestamp) + ); + }), ]); // Rollover Datastream to reset the limit to default which is 1000 await PageObjects.datasetQuality.rolloverDataStream(degradedDatasetWithLimitDataStreamName); await PageObjects.datasetQuality.rolloverDataStream(nginxAccessDataStreamName); + await PageObjects.datasetQuality.rolloverDataStream(apmAppDataStreamName); // Set Limit of 26 await PageObjects.datasetQuality.setDataStreamSettings( @@ -274,6 +330,16 @@ export default function ({ getService, getPageObjects }: DatasetQualityFtrProvid } ); + // Set Limit of 27 + await PageObjects.datasetQuality.setDataStreamSettings( + PageObjects.datasetQuality.generateBackingIndexNameWithoutVersion({ + dataset: apmAppDatasetName, + }) + '-000002', + { + 'mapping.total_fields.limit': 27, + } + ); + await synthtrace.index([ // Ingest Degraded Logs with 26 field timerange(moment(to).subtract(count, 'minute'), moment(to)) @@ -323,6 +389,30 @@ export default function ({ getService, getPageObjects }: DatasetQualityFtrProvid .timestamp(timestamp) ); }), + // Ingest Degraded Logs with 27 fields in Apm APP DataSet + timerange(moment(to).subtract(count, 'minute'), moment(to)) + .interval('1m') + .rate(1) + .generator((timestamp) => { + return Array(1) + .fill(0) + .flatMap(() => + log + .create() + .dataset(apmAppDatasetName) + .message('a log message') + .logLevel(MORE_THAN_1024_CHARS) + .service(serviceName) + .namespace(defaultNamespace) + .defaults({ + 'service.name': serviceName, + 'trace.id': generateShortId(), + test_field: [MORE_THAN_1024_CHARS, ANOTHER_1024_CHARS], + 'cloud.project.id': generateShortId(), + }) + .timestamp(timestamp) + ); + }), ]); }); @@ -568,6 +658,8 @@ export default function ({ getService, getPageObjects }: DatasetQualityFtrProvid expandedDegradedField: 'test_field', }); + await PageObjects.datasetQuality.waitUntilPossibleMitigationsLoaded(); + // Possible Mitigation Section should exist await testSubjects.existOrFail( 'datasetQualityDetailsDegradedFieldFlyoutPossibleMitigationTitle' @@ -703,6 +795,36 @@ export default function ({ getService, getPageObjects }: DatasetQualityFtrProvid expect(linkURL?.endsWith('mapping-settings-limit.html')).to.be(true); }); + it('should display increase field limit as a possible mitigation for special packages like apm app', async () => { + await PageObjects.datasetQuality.navigateToDetails({ + dataStream: apmAppDataStreamName, + expandedDegradedField: 'cloud.project', + }); + + // Field Limit Mitigation Section should exist + await testSubjects.existOrFail( + 'datasetQualityDetailsDegradedFieldFlyoutFieldLimitMitigationAccordion' + ); + + // Should display the panel to increase field limit + await testSubjects.existOrFail( + 'datasetQualityDetailsDegradedFieldFlyoutIncreaseFieldLimitPanel' + ); + + // Should display official online documentation link + await testSubjects.existOrFail( + 'datasetQualityManualMitigationsPipelineOfficialDocumentationLink' + ); + + const linkButton = await testSubjects.find( + 'datasetQualityManualMitigationsPipelineOfficialDocumentationLink' + ); + + const linkURL = await linkButton.getAttribute('href'); + + expect(linkURL?.endsWith('mapping-settings-limit.html')).to.be(true); + }); + it('should display increase field limit as a possible mitigation for non integration', async () => { await PageObjects.datasetQuality.navigateToDetails({ dataStream: degradedDatasetWithLimitDataStreamName, @@ -764,10 +886,10 @@ export default function ({ getService, getPageObjects }: DatasetQualityFtrProvid expect(newFieldLimit).to.be(newLimit); // Should display the apply button - await testSubjects.existOrFail('datasetQualityIncreaseFieldMappingLimitButtonButton'); + await testSubjects.existOrFail('datasetQualityIncreaseFieldMappingLimitButton'); const applyButton = await testSubjects.find( - 'datasetQualityIncreaseFieldMappingLimitButtonButton' + 'datasetQualityIncreaseFieldMappingLimitButton' ); const applyButtonDisabledStatus = await applyButton.getAttribute('disabled'); @@ -792,7 +914,7 @@ export default function ({ getService, getPageObjects }: DatasetQualityFtrProvid ); const applyButton = await testSubjects.find( - 'datasetQualityIncreaseFieldMappingLimitButtonButton' + 'datasetQualityIncreaseFieldMappingLimitButton' ); const applyButtonDisabledStatus = await applyButton.getAttribute('disabled'); @@ -814,7 +936,7 @@ export default function ({ getService, getPageObjects }: DatasetQualityFtrProvid }); const applyButton = await testSubjects.find( - 'datasetQualityIncreaseFieldMappingLimitButtonButton' + 'datasetQualityIncreaseFieldMappingLimitButton' ); await applyButton.click(); diff --git a/x-pack/test/functional/apps/discover/saved_searches.ts b/x-pack/test/functional/apps/discover/saved_searches.ts index 3b039c8da9eee..ee733b4c4c46d 100644 --- a/x-pack/test/functional/apps/discover/saved_searches.ts +++ b/x-pack/test/functional/apps/discover/saved_searches.ts @@ -28,7 +28,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const ecommerceSOPath = 'x-pack/test/functional/fixtures/kbn_archiver/reporting/ecommerce.json'; const defaultSettings = { defaultIndex: 'logstash-*', - 'doc_table:legacy': false, }; const from = 'Apr 27, 2019 @ 23:56:51.374'; @@ -47,7 +46,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await esArchiver.unload('x-pack/test/functional/es_archives/reporting/ecommerce'); await kibanaServer.importExport.unload('test/functional/fixtures/kbn_archiver/discover'); await kibanaServer.importExport.unload(ecommerceSOPath); - await kibanaServer.uiSettings.unset('doc_table:legacy'); await common.unsetTime(); }); diff --git a/x-pack/test/functional/apps/discover/value_suggestions.ts b/x-pack/test/functional/apps/discover/value_suggestions.ts index f949a890d90c2..21a577ece13bf 100644 --- a/x-pack/test/functional/apps/discover/value_suggestions.ts +++ b/x-pack/test/functional/apps/discover/value_suggestions.ts @@ -35,14 +35,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await kibanaServer.importExport.load( 'x-pack/test/functional/fixtures/kbn_archiver/dashboard_drilldowns/drilldowns' ); - await kibanaServer.uiSettings.update({ - 'doc_table:legacy': false, - }); await timePicker.setDefaultAbsoluteRangeViaUiSettings(); }); after(async () => { - await kibanaServer.uiSettings.unset('doc_table:legacy'); await common.unsetTime(); await kibanaServer.savedObjects.cleanStandardList(); }); diff --git a/x-pack/test/functional/apps/discover/value_suggestions_non_timebased.ts b/x-pack/test/functional/apps/discover/value_suggestions_non_timebased.ts index b40c74bf06e41..47cc04b5b60fd 100644 --- a/x-pack/test/functional/apps/discover/value_suggestions_non_timebased.ts +++ b/x-pack/test/functional/apps/discover/value_suggestions_non_timebased.ts @@ -23,9 +23,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { 'test/functional/fixtures/kbn_archiver/index_pattern_without_timefield' ); await kibanaServer.uiSettings.replace({ defaultIndex: 'without-timefield' }); - await kibanaServer.uiSettings.update({ - 'doc_table:legacy': false, - }); }); after(async () => { @@ -34,7 +31,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { ); await kibanaServer.savedObjects.clean({ types: ['search', 'index-pattern'] }); await kibanaServer.uiSettings.unset('defaultIndex'); - await kibanaServer.uiSettings.unset('doc_table:legacy'); }); it('shows all autosuggest options for a filter in discover context app', async () => { diff --git a/x-pack/test/functional/apps/index_management/config.ts b/x-pack/test/functional/apps/index_management/config.ts index d0d07ff200281..16999df37efd0 100644 --- a/x-pack/test/functional/apps/index_management/config.ts +++ b/x-pack/test/functional/apps/index_management/config.ts @@ -10,8 +10,90 @@ import { FtrConfigProviderContext } from '@kbn/test'; export default async function ({ readConfigFile }: FtrConfigProviderContext) { const functionalConfig = await readConfigFile(require.resolve('../../config.base.js')); + const baseConfig = functionalConfig.getAll(); + + baseConfig.security.roles.index_management_manage_index_templates = { + elasticsearch: { + cluster: ['manage_index_templates'], + indices: [ + { + names: ['*'], + privileges: ['all'], + }, + ], + }, + kibana: [ + { + feature: { + advancedSettings: ['read'], + }, + spaces: ['*'], + }, + ], + }; + + baseConfig.security.roles.index_management_monitor_only = { + elasticsearch: { + cluster: ['monitor'], + indices: [ + { + names: ['*'], + privileges: ['all'], + }, + ], + }, + kibana: [ + { + feature: { + advancedSettings: ['read'], + }, + spaces: ['*'], + }, + ], + }; + + baseConfig.security.roles.index_management_manage_enrich_only = { + elasticsearch: { + cluster: ['manage_enrich'], + indices: [ + { + names: ['*'], + privileges: ['all'], + }, + ], + }, + kibana: [ + { + feature: { + advancedSettings: ['read'], + }, + spaces: ['*'], + }, + ], + }; + + baseConfig.security.roles.index_management_monitor_enrich_only = { + elasticsearch: { + cluster: ['monitor_enrich'], + indices: [ + { + names: ['*'], + privileges: ['all'], + }, + ], + }, + kibana: [ + { + feature: { + advancedSettings: ['read'], + }, + spaces: ['*'], + }, + ], + }; + return { - ...functionalConfig.getAll(), + ...baseConfig, testFiles: [require.resolve('.')], }; } diff --git a/x-pack/test/functional/apps/index_management/enrich_policies_tab/enrich_policies_tab.ts b/x-pack/test/functional/apps/index_management/enrich_policies_tab/enrich_policies_tab.ts index a473a33d298c0..e74a14fe4f26b 100644 --- a/x-pack/test/functional/apps/index_management/enrich_policies_tab/enrich_policies_tab.ts +++ b/x-pack/test/functional/apps/index_management/enrich_policies_tab/enrich_policies_tab.ts @@ -23,6 +23,12 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { describe('Enrich policies tab', function () { before(async () => { await log.debug('Creating required index and enrich policy'); + + try { + await es.indices.delete({ index: ENRICH_INDEX_NAME }); + // eslint-disable-next-line no-empty + } catch (e) {} + try { await es.indices.create({ index: ENRICH_INDEX_NAME, @@ -94,7 +100,22 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { expect(await successToast.getVisibleText()).to.contain(`Executed ${ENRICH_POLICY_NAME}`); }); + it('read only access', async () => { + await security.testUser.setRoles(['index_management_monitor_enrich_only']); + await pageObjects.common.navigateToApp('indexManagement'); + await pageObjects.indexManagement.changeTabs('enrich_policiesTab'); + await pageObjects.header.waitUntilLoadingHasFinished(); + + await testSubjects.missingOrFail('createPolicyButton'); + await testSubjects.missingOrFail('deletePolicyButton'); + }); + it('can delete a policy', async () => { + await security.testUser.setRoles(['index_management_user']); + await pageObjects.common.navigateToApp('indexManagement'); + // Navigate to the enrich policies tab + await pageObjects.indexManagement.changeTabs('enrich_policiesTab'); + await pageObjects.header.waitUntilLoadingHasFinished(); // Since we disabled wait_for_completion in the server request, we dont know when // a given policy will finish executing. Until that happens the policy cannot // be deleted. 2s seems to be plenty enough to guarantee that, at least for this @@ -104,8 +125,14 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { await pageObjects.indexManagement.clickDeleteEnrichPolicyAt(0); await pageObjects.indexManagement.clickConfirmModalButton(); - const successToast = await toasts.getElementByIndex(2); + const successToast = await toasts.getElementByIndex(1); expect(await successToast.getVisibleText()).to.contain(`Deleted ${ENRICH_POLICY_NAME}`); }); + + it('no access', async () => { + await security.testUser.setRoles(['index_management_monitor_only']); + await pageObjects.common.navigateToApp('indexManagement'); + await testSubjects.missingOrFail('enrich_policiesTab'); + }); }); }; diff --git a/x-pack/test/functional/apps/infra/hosts_view.ts b/x-pack/test/functional/apps/infra/hosts_view.ts index dd6a420d27fbe..52b3484ed50e5 100644 --- a/x-pack/test/functional/apps/infra/hosts_view.ts +++ b/x-pack/test/functional/apps/infra/hosts_view.ts @@ -341,7 +341,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { const currentUrl = await browser.getCurrentUrl(); const parsedUrl = new URL(currentUrl); const baseUrl = `${parsedUrl.protocol}//${parsedUrl.host}`; - const expectedUrlPattern = `${baseUrl}/app/observabilityOnboarding/?category=logs`; + const expectedUrlPattern = `${baseUrl}/app/observabilityOnboarding/?category=host`; expect(currentUrl).to.equal(expectedUrlPattern); }); }); diff --git a/x-pack/test/functional/apps/infra/metrics_source_configuration.ts b/x-pack/test/functional/apps/infra/metrics_source_configuration.ts index 46d20489e4d36..39c6b33d2f3e2 100644 --- a/x-pack/test/functional/apps/infra/metrics_source_configuration.ts +++ b/x-pack/test/functional/apps/infra/metrics_source_configuration.ts @@ -7,13 +7,10 @@ import { cleanup, Dataset, generate, PartialConfig } from '@kbn/data-forge'; import expect from '@kbn/expect'; -import { - Aggregators, - InfraRuleType, - MetricThresholdParams, -} from '@kbn/infra-plugin/common/alerting/metrics'; +import { Aggregators, MetricThresholdParams } from '@kbn/infra-plugin/common/alerting/metrics'; import { COMPARATORS } from '@kbn/alerting-comparators'; +import { InfraRuleType } from '@kbn/rule-data-utils'; import { createRule } from '../../../alerting_api_integration/observability/helpers/alerting_api_helper'; import { waitForDocumentInIndex, diff --git a/x-pack/test/functional/apps/lens/group4/index.ts b/x-pack/test/functional/apps/lens/group4/index.ts index 61074d6aa6d78..7caadad31c120 100644 --- a/x-pack/test/functional/apps/lens/group4/index.ts +++ b/x-pack/test/functional/apps/lens/group4/index.ts @@ -81,7 +81,6 @@ export default ({ getService, loadTestFile, getPageObjects }: FtrProviderContext loadTestFile(require.resolve('./show_underlying_data_dashboard')); // 2m 10s loadTestFile(require.resolve('./share')); // 1m 20s // keep it last in the group - loadTestFile(require.resolve('./tsdb')); // 1m - loadTestFile(require.resolve('./logsdb')); // 1m + loadTestFile(require.resolve('./tsdb')); // 3m 56s }); }; diff --git a/x-pack/test/functional/apps/lens/group4/tsdb.ts b/x-pack/test/functional/apps/lens/group4/tsdb.ts index 3a6aac5ffa39b..3834fc837b9d2 100644 --- a/x-pack/test/functional/apps/lens/group4/tsdb.ts +++ b/x-pack/test/functional/apps/lens/group4/tsdb.ts @@ -17,7 +17,7 @@ import { getDocsGenerator, setupScenarioRunner, sumFirstNValues, -} from './tsdb_logsdb_helpers'; +} from '../tsdb_logsdb_helpers'; export default function ({ getService, getPageObjects }: FtrProviderContext) { const { common, lens, dashboard } = getPageObjects(['common', 'lens', 'dashboard']); diff --git a/x-pack/test/functional/apps/lens/group6/workspace_size.ts b/x-pack/test/functional/apps/lens/group6/workspace_size.ts index 9ae8f21cebf69..86f5c481fff6c 100644 --- a/x-pack/test/functional/apps/lens/group6/workspace_size.ts +++ b/x-pack/test/functional/apps/lens/group6/workspace_size.ts @@ -267,15 +267,13 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await assertWorkspaceDimensions('600px', '375px'); }); - // Fails in chrome 128+: https://github.com/elastic/kibana-operations/issues/199 - it.skip('gauge size (absolute pixels) - major arc', async () => { + it('gauge size (absolute pixels) - major arc', async () => { await lens.openVisualOptions(); await lens.setGaugeShape('Major arc'); await assertWorkspaceDimensions('600px', '430px'); }); - // Fails in chrome 129+: https://github.com/elastic/kibana-operations/issues/199 - it.skip('gauge size (absolute pixels) - circle', async () => { + it('gauge size (absolute pixels) - circle', async () => { await lens.openVisualOptions(); await lens.setGaugeShape('Circle'); await assertWorkspaceDimensions('600px', '430px'); diff --git a/x-pack/test/functional/apps/lens/group7/config.ts b/x-pack/test/functional/apps/lens/group7/config.ts new file mode 100644 index 0000000000000..d927f93adeffd --- /dev/null +++ b/x-pack/test/functional/apps/lens/group7/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/functional/apps/lens/group7/index.ts b/x-pack/test/functional/apps/lens/group7/index.ts new file mode 100644 index 0000000000000..0ef20e0530815 --- /dev/null +++ b/x-pack/test/functional/apps/lens/group7/index.ts @@ -0,0 +1,77 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { EsArchiver } from '@kbn/es-archiver'; +import { FtrProviderContext } from '../../../ftr_provider_context'; + +export default ({ getService, loadTestFile, getPageObjects }: FtrProviderContext) => { + const browser = getService('browser'); + const log = getService('log'); + const esArchiver = getService('esArchiver'); + const kibanaServer = getService('kibanaServer'); + const { timePicker } = getPageObjects(['timePicker']); + const config = getService('config'); + let remoteEsArchiver; + + describe('lens app - group 4', () => { + const esArchive = 'x-pack/test/functional/es_archives/logstash_functional'; + const localIndexPatternString = 'logstash-*'; + const remoteIndexPatternString = 'ftr-remote:logstash-*'; + const localFixtures = { + lensBasic: 'x-pack/test/functional/fixtures/kbn_archiver/lens/lens_basic.json', + lensDefault: 'x-pack/test/functional/fixtures/kbn_archiver/lens/default', + }; + + const remoteFixtures = { + lensBasic: 'x-pack/test/functional/fixtures/kbn_archiver/lens/ccs/lens_basic.json', + lensDefault: 'x-pack/test/functional/fixtures/kbn_archiver/lens/ccs/default', + }; + let esNode: EsArchiver; + let fixtureDirs: { + lensBasic: string; + lensDefault: string; + }; + let indexPatternString: string; + before(async () => { + await log.debug('Starting lens before method'); + await browser.setWindowSize(1280, 1200); + await kibanaServer.savedObjects.cleanStandardList(); + try { + config.get('esTestCluster.ccs'); + remoteEsArchiver = getService('remoteEsArchiver' as 'esArchiver'); + esNode = remoteEsArchiver; + fixtureDirs = remoteFixtures; + indexPatternString = remoteIndexPatternString; + } catch (error) { + esNode = esArchiver; + fixtureDirs = localFixtures; + indexPatternString = localIndexPatternString; + } + + await esNode.load(esArchive); + // changing the timepicker default here saves us from having to set it in Discover (~8s) + await timePicker.setDefaultAbsoluteRangeViaUiSettings(); + await kibanaServer.uiSettings.update({ + defaultIndex: indexPatternString, + 'dateFormat:tz': 'UTC', + }); + await kibanaServer.importExport.load(fixtureDirs.lensBasic); + await kibanaServer.importExport.load(fixtureDirs.lensDefault); + }); + + after(async () => { + await esArchiver.unload(esArchive); + await timePicker.resetDefaultAbsoluteRangeViaUiSettings(); + await kibanaServer.importExport.unload(fixtureDirs.lensBasic); + await kibanaServer.importExport.unload(fixtureDirs.lensDefault); + await kibanaServer.savedObjects.cleanStandardList(); + }); + + // total run time ~30m + loadTestFile(require.resolve('./logsdb')); // 30m + }); +}; diff --git a/x-pack/test/functional/apps/lens/group4/logsdb.ts b/x-pack/test/functional/apps/lens/group7/logsdb.ts similarity index 99% rename from x-pack/test/functional/apps/lens/group4/logsdb.ts rename to x-pack/test/functional/apps/lens/group7/logsdb.ts index 8071ad58ac09a..5aeff039c4889 100644 --- a/x-pack/test/functional/apps/lens/group4/logsdb.ts +++ b/x-pack/test/functional/apps/lens/group7/logsdb.ts @@ -14,7 +14,7 @@ import { getDocsGenerator, setupScenarioRunner, TIME_PICKER_FORMAT, -} from './tsdb_logsdb_helpers'; +} from '../tsdb_logsdb_helpers'; export default function ({ getService, getPageObjects }: FtrProviderContext) { const { common, lens, discover, header, timePicker } = getPageObjects([ diff --git a/x-pack/test/functional/apps/lens/group4/tsdb_logsdb_helpers.ts b/x-pack/test/functional/apps/lens/tsdb_logsdb_helpers.ts similarity index 99% rename from x-pack/test/functional/apps/lens/group4/tsdb_logsdb_helpers.ts rename to x-pack/test/functional/apps/lens/tsdb_logsdb_helpers.ts index e0169ebbae575..d68040de27ae9 100644 --- a/x-pack/test/functional/apps/lens/group4/tsdb_logsdb_helpers.ts +++ b/x-pack/test/functional/apps/lens/tsdb_logsdb_helpers.ts @@ -9,7 +9,7 @@ import { Client } from '@elastic/elasticsearch'; import { MappingProperty } from '@elastic/elasticsearch/lib/api/types'; import { ToolingLog } from '@kbn/tooling-log'; import moment from 'moment'; -import type { FtrProviderContext } from '../../../ftr_provider_context'; +import type { FtrProviderContext } from '../../ftr_provider_context'; export const TEST_DOC_COUNT = 100; export const TIME_PICKER_FORMAT = 'MMM D, YYYY [@] HH:mm:ss.SSS'; diff --git a/x-pack/test/functional/es_archives/observability/alerts/data.json.gz b/x-pack/test/functional/es_archives/observability/alerts/data.json.gz index 4017aaab1bddf..bcab15f41c449 100644 Binary files a/x-pack/test/functional/es_archives/observability/alerts/data.json.gz and b/x-pack/test/functional/es_archives/observability/alerts/data.json.gz differ diff --git a/x-pack/test/functional/es_archives/security_solution/alerts/8.1.0/data.json.gz b/x-pack/test/functional/es_archives/security_solution/alerts/8.1.0/data.json.gz index 50d664aa24ced..bebcb0d90f838 100644 Binary files a/x-pack/test/functional/es_archives/security_solution/alerts/8.1.0/data.json.gz and b/x-pack/test/functional/es_archives/security_solution/alerts/8.1.0/data.json.gz differ diff --git a/x-pack/test/functional/es_archives/task_manager_removed_types/data.json b/x-pack/test/functional/es_archives/task_manager_removed_types/data.json index 3fc1a2cad2d28..29333b60b292b 100644 --- a/x-pack/test/functional/es_archives/task_manager_removed_types/data.json +++ b/x-pack/test/functional/es_archives/task_manager_removed_types/data.json @@ -2,11 +2,9 @@ "type": "doc", "value": { "id": "task:ce7e1250-3322-11eb-94c1-db6995e83f6b", - "index": ".kibana_task_manager_1", + "index": ".kibana_task_manager", "source": { - "migrationVersion": { - "task": "7.6.0" - }, + "typeMigrationVersion": "7.6.0", "references": [ ], "task": { @@ -33,11 +31,9 @@ "type": "doc", "value": { "id": "task:be7e1250-3322-11eb-94c1-db6995e83f6a", - "index": ".kibana_task_manager_1", + "index": ".kibana_task_manager", "source": { - "migrationVersion": { - "task": "7.6.0" - }, + "typeMigrationVersion": "7.6.0", "references": [ ], "task": { diff --git a/x-pack/test/functional/es_archives/task_manager_removed_types/mappings.json b/x-pack/test/functional/es_archives/task_manager_removed_types/mappings.json deleted file mode 100644 index f35681efb089d..0000000000000 --- a/x-pack/test/functional/es_archives/task_manager_removed_types/mappings.json +++ /dev/null @@ -1,224 +0,0 @@ -{ - "type": "index", - "value": { - "aliases": { - ".kibana": { - } - }, - "index": ".kibana_1", - "mappings": { - "_meta": { - "migrationMappingPropertyHashes": { - "action": "6e96ac5e648f57523879661ea72525b7", - "action_task_params": "a9d49f184ee89641044be0ca2950fa3a", - "alert": "0359d7fcc04da9878ee9aadbda38ba55", - "api_key_pending_invalidation": "16f515278a295f6245149ad7c5ddedb7", - "apm-indices": "9bb9b2bf1fa636ed8619cbab5ce6a1dd", - "apm-telemetry": "3d1b76c39bfb2cc8296b024d73854724", - "app_search_telemetry": "3d1b76c39bfb2cc8296b024d73854724", - "application_usage_daily": "43b8830d5d0df85a6823d290885fc9fd", - "application_usage_totals": "3d1b76c39bfb2cc8296b024d73854724", - "application_usage_transactional": "3d1b76c39bfb2cc8296b024d73854724", - "search-session": "721df406dbb7e35ac22e4df6c3ad2b2a", - "canvas-element": "7390014e1091044523666d97247392fc", - "canvas-workpad": "b0a1706d356228dbdcb4a17e6b9eb231", - "canvas-workpad-template": "ae2673f678281e2c055d764b153e9715", - "cases": "477f214ff61acc3af26a7b7818e380c1", - "cases-comments": "8a50736330e953bca91747723a319593", - "cases-configure": "387c5f3a3bda7e0ae0dd4e106f914a69", - "cases-user-actions": "32277330ec6b721abe3b846cfd939a71", - "config": "c63748b75f39d0c54de12d12c1ccbc20", - "dashboard": "40554caf09725935e2c02e02563a2d07", - "endpoint:user-artifact": "4a11183eee21e6fbad864f7a30b39ad0", - "endpoint:user-artifact-manifest": "a0d7b04ad405eed54d76e279c3727862", - "enterprise_search_telemetry": "3d1b76c39bfb2cc8296b024d73854724", - "epm-packages": "2b83397e3eaaaa8ef15e38813f3721c3", - "event_log_test": "bef808d4a9c27f204ffbda3359233931", - "exception-list": "67f055ab8c10abd7b2ebfd969b836788", - "exception-list-agnostic": "67f055ab8c10abd7b2ebfd969b836788", - "file-upload-telemetry": "0ed4d3e1983d1217a30982630897092e", - "fleet-agent-actions": "9511b565b1cc6441a42033db3d5de8e9", - "fleet-agent-events": "e20a508b6e805189356be381dbfac8db", - "fleet-agents": "cb661e8ede2b640c42c8e5ef99db0683", - "fleet-enrollment-api-keys": "a69ef7ae661dab31561d6c6f052ef2a7", - "graph-workspace": "cd7ba1330e6682e9cc00b78850874be1", - "index-pattern": "45915a1ad866812242df474eb0479052", - "infrastructure-ui-source": "3d1b76c39bfb2cc8296b024d73854724", - "ingest-agent-policies": "8b0733cce189659593659dad8db426f0", - "ingest-outputs": "8854f34453a47e26f86a29f8f3b80b4e", - "ingest-package-policies": "c91ca97b1ff700f0fc64dc6b13d65a85", - "ingest_manager_settings": "02a03095f0e05b7a538fa801b88a217f", - "inventory-view": "3d1b76c39bfb2cc8296b024d73854724", - "kql-telemetry": "d12a98a6f19a2d273696597547e064ee", - "lens": "52346cfec69ff7b47d5f0c12361a2797", - "lens-ui-telemetry": "509bfa5978586998e05f9e303c07a327", - "map": "4a05b35c3a3a58fbc72dd0202dc3487f", - "maps-telemetry": "5ef305b18111b77789afefbd36b66171", - "metrics-explorer-view": "3d1b76c39bfb2cc8296b024d73854724", - "migrationVersion": "4a1746014a75ade3a714e1db5763276f", - "ml-job": "3bb64c31915acf93fc724af137a0891b", - "ml-telemetry": "257fd1d4b4fdbb9cb4b8a3b27da201e9", - "monitoring-telemetry": "2669d5ec15e82391cf58df4294ee9c68", - "namespace": "2f4316de49999235636386fe51dc06c1", - "namespaces": "2f4316de49999235636386fe51dc06c1", - "originId": "2f4316de49999235636386fe51dc06c1", - "query": "11aaeb7f5f7fa5bb43f25e18ce26e7d9", - "references": "7997cf5a56cc02bdc9c93361bde732b0", - "sample-data-telemetry": "7d3cfeb915303c9641c59681967ffeb4", - "search": "43012c7ebc4cb57054e0a490e4b43023", - "search-telemetry": "3d1b76c39bfb2cc8296b024d73854724", - "siem-detection-engine-rule-actions": "6569b288c169539db10cb262bf79de18", - "siem-detection-engine-rule-status": "ae783f41c6937db6b7a2ef5c93a9e9b0", - "siem-ui-timeline": "d12c5474364d737d17252acf1dc4585c", - "siem-ui-timeline-note": "8874706eedc49059d4cf0f5094559084", - "siem-ui-timeline-pinned-event": "20638091112f0e14f0e443d512301c29", - "space": "c5ca8acafa0beaa4d08d014a97b6bc6b", - "tag": "83d55da58f6530f7055415717ec06474", - "telemetry": "36a616f7026dfa617d6655df850fe16d", - "tsvb-validation-telemetry": "3a37ef6c8700ae6fc97d5c7da00e9215", - "type": "2f4316de49999235636386fe51dc06c1", - "ui-metric": "0d409297dc5ebe1e3a1da691c6ee32e3", - "updated_at": "00da57df13e94e9d98437d13ace4bfe0", - "upgrade-assistant-reindex-operation": "215107c281839ea9b3ad5f6419819763", - "upgrade-assistant-telemetry": "56702cec857e0a9dacfb696655b4ff7b", - "uptime-dynamic-settings": "3d1b76c39bfb2cc8296b024d73854724", - "url": "c7f66a0df8b1b52f17c28c4adb111105", - "visualization": "f819cf6636b75c9e76ba733a0c6ef355", - "workplace_search_telemetry": "3d1b76c39bfb2cc8296b024d73854724" - } - }, - "dynamic": "strict", - "properties": { - "type": { - "type": "keyword" - }, - "updated_at": { - "type": "date" - } - } - }, - "settings": { - "index": { - "auto_expand_replicas": "0-1", - "number_of_replicas": "0", - "number_of_shards": "1" - } - } - } -} - -{ - "type": "index", - "value": { - "aliases": { - ".kibana_task_manager": { - } - }, - "index": ".kibana_task_manager_1", - "mappings": { - "_meta": { - "migrationMappingPropertyHashes": { - "migrationVersion": "4a1746014a75ade3a714e1db5763276f", - "namespace": "2f4316de49999235636386fe51dc06c1", - "namespaces": "2f4316de49999235636386fe51dc06c1", - "originId": "2f4316de49999235636386fe51dc06c1", - "references": "7997cf5a56cc02bdc9c93361bde732b0", - "task": "235412e52d09e7165fac8a67a43ad6b4", - "type": "2f4316de49999235636386fe51dc06c1", - "updated_at": "00da57df13e94e9d98437d13ace4bfe0" - } - }, - "dynamic": "strict", - "properties": { - "migrationVersion": { - "dynamic": "true", - "properties": { - "task": { - "fields": { - "keyword": { - "ignore_above": 256, - "type": "keyword" - } - }, - "type": "text" - } - } - }, - "references": { - "properties": { - "id": { - "type": "keyword" - }, - "name": { - "type": "keyword" - }, - "type": { - "type": "keyword" - } - }, - "type": "nested" - }, - "task": { - "properties": { - "attempts": { - "type": "integer" - }, - "ownerId": { - "type": "keyword" - }, - "params": { - "type": "text" - }, - "retryAt": { - "type": "date" - }, - "runAt": { - "type": "date" - }, - "schedule": { - "properties": { - "interval": { - "type": "keyword" - } - } - }, - "scheduledAt": { - "type": "date" - }, - "scope": { - "type": "keyword" - }, - "startedAt": { - "type": "date" - }, - "state": { - "type": "text" - }, - "status": { - "type": "keyword" - }, - "taskType": { - "type": "keyword" - }, - "user": { - "type": "keyword" - } - } - }, - "type": { - "type": "keyword" - }, - "updated_at": { - "type": "date" - } - } - }, - "settings": { - "index": { - "auto_expand_replicas": "0-1", - "number_of_replicas": "0", - "number_of_shards": "1" - } - } - } -} diff --git a/x-pack/test/functional/page_objects/dataset_quality.ts b/x-pack/test/functional/page_objects/dataset_quality.ts index cef881fe0797c..47a9261c906f7 100644 --- a/x-pack/test/functional/page_objects/dataset_quality.ts +++ b/x-pack/test/functional/page_objects/dataset_quality.ts @@ -205,7 +205,10 @@ export function DatasetQualityPageObject({ getPageObjects, getService }: FtrProv }, async waitUntilPossibleMitigationsLoaded() { - await find.waitForDeletedByCssSelector('.euiFlyoutBody .euiSkeletonRectangle', 20 * 1000); + await find.waitForDeletedByCssSelector( + '.euiFlyoutBody .datasetQualityDetailsFlyoutManualMitigationsLoading', + 20 * 1000 + ); }, async waitUntilDegradedFieldFlyoutLoaded() { 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 3da7659419f0f..a0a243dad7d83 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 @@ -13,6 +13,7 @@ import type { LogRateAnalysisType } from '@kbn/aiops-log-rate-analysis'; import type { FtrProviderContext } from '../../ftr_provider_context'; import type { LogRateAnalysisDataGenerator } from './log_rate_analysis_data_generator'; +import { CreateCaseParams } from '../cases/create'; export function LogRateAnalysisPageProvider({ getService, getPageObject }: FtrProviderContext) { const browser = getService('browser'); @@ -22,6 +23,7 @@ export function LogRateAnalysisPageProvider({ getService, getPageObject }: FtrPr const retry = getService('retry'); const header = getPageObject('header'); const dashboardPage = getPageObject('dashboard'); + const cases = getService('cases'); return { async assertTimeRangeSelectorSectionExists() { @@ -435,5 +437,22 @@ export function LogRateAnalysisPageProvider({ getService, getPageObject }: FtrPr await this.confirmAttachToDashboard(); await this.completeSaveToDashboardForm(true); }, + + async assertAttachToCaseButtonDisabled() { + const button = await testSubjects.find('aiopsLogRateAnalysisAttachToCaseButton'); + const isEnabled = await button.isEnabled(); + expect(isEnabled).to.be(false); + }, + + async clickAttachToCase() { + await testSubjects.click('aiopsLogRateAnalysisAttachToCaseButton'); + }, + + async attachToCase(params: CreateCaseParams) { + await this.openAttachmentsMenu(); + await this.clickAttachToCase(); + + await cases.create.createCaseFromModal(params); + }, }; } diff --git a/x-pack/test/functional/services/ml/cases.ts b/x-pack/test/functional/services/ml/cases.ts index 2245410985592..3f31e6da65dff 100644 --- a/x-pack/test/functional/services/ml/cases.ts +++ b/x-pack/test/functional/services/ml/cases.ts @@ -94,5 +94,13 @@ export function MachineLearningCasesProvider( await testSubjects.existOrFail('comment-persistableState-aiopsChangePointChart'); await testSubjects.existOrFail('aiopsEmbeddableChangePointChart'); }, + + async assertCaseWithLogRateAnalysisAttachment(params: CaseParams) { + await this.assertBasicCaseProps(params); + await testSubjects.existOrFail('comment-persistableState-aiopsLogRateAnalysisEmbeddable'); + await testSubjects.existOrFail('aiopsEmbeddableLogRateAnalysis'); + await testSubjects.existOrFail('aiopsDocumentCountChart'); + await testSubjects.existOrFail('aiopsLogRateAnalysisResults'); + }, }; } diff --git a/x-pack/test/functional_execution_context/plugins/alerts/server/plugin.ts b/x-pack/test/functional_execution_context/plugins/alerts/server/plugin.ts index 9f6d33d9ca164..78c79375f3e9f 100644 --- a/x-pack/test/functional_execution_context/plugins/alerts/server/plugin.ts +++ b/x-pack/test/functional_execution_context/plugins/alerts/server/plugin.ts @@ -7,7 +7,7 @@ import apmAgent from 'elastic-apm-node'; import type { Plugin, CoreSetup } from '@kbn/core/server'; -import { PluginSetupContract as AlertingPluginSetup } from '@kbn/alerting-plugin/server/plugin'; +import { AlertingServerSetup } from '@kbn/alerting-plugin/server/plugin'; import { EncryptedSavedObjectsPluginStart } from '@kbn/encrypted-saved-objects-plugin/server'; import { FeaturesPluginSetup } from '@kbn/features-plugin/server'; import { SpacesPluginStart } from '@kbn/spaces-plugin/server'; @@ -16,7 +16,7 @@ import { KibanaFeatureScope } from '@kbn/features-plugin/common'; export interface FixtureSetupDeps { features: FeaturesPluginSetup; - alerting: AlertingPluginSetup; + alerting: AlertingServerSetup; } export interface FixtureStartDeps { @@ -34,8 +34,8 @@ export class FixturePlugin implements Plugin { } // Failing: See https://github.com/elastic/kibana/issues/196153 - describe('create alert', function () { + // Failing: See https://github.com/elastic/kibana/issues/196153 + describe.skip('create alert', function () { let apmSynthtraceEsClient: ApmSynthtraceEsClient; const webhookConnectorName = 'webhook-test'; before(async () => { diff --git a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/home_page.ts b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/home_page.ts index c03d6dcf74a88..bffe63a97634f 100644 --- a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/home_page.ts +++ b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/home_page.ts @@ -8,7 +8,7 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../ftr_provider_context'; import { ObjectRemover } from '../../lib/object_remover'; -import { getTestAlertData, getTestConnectorData } from '../../lib/get_test_data'; +import { getTestAlertData } from '../../lib/get_test_data'; export default ({ getPageObjects, getService }: FtrProviderContext) => { const testSubjects = getService('testSubjects'); @@ -24,6 +24,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { before(async () => { await security.testUser.setRoles(['alerts_and_actions_role']); }); + after(async () => { await security.testUser.restoreDefaults(); }); @@ -41,6 +42,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { before(async () => { await security.testUser.setRoles(['only_actions_role']); }); + after(async () => { await security.testUser.restoreDefaults(); }); @@ -57,19 +59,35 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { await pageObjects.common.navigateToApp('triggersActions'); }); - after(async () => { - await objectRemover.removeAll(); - }); - it('Loads the Alerts page', async () => { - await log.debug('Checking for section heading to say Rules.'); + log.debug('Checking for section heading to say Rules.'); const headingText = await pageObjects.triggersActionsUI.getSectionHeadingText(); expect(headingText).to.be('Rules'); }); describe('Alerts tab', () => { + let createdRule: { name: string; id: string }; + + before(async () => { + const resRule = await supertest + .post(`/api/alerting/rule`) + .set('kbn-xsrf', 'foo') + .send(getTestAlertData()) + .expect(200); + + createdRule = resRule.body; + objectRemover.add(createdRule.id, 'rule', 'alerting'); + }); + + after(async () => { + await objectRemover.removeAll(); + }); + it('renders the alerts tab', async () => { + // refresh to see alert + await browser.refresh(); + // Navigate to the alerts tab await pageObjects.triggersActionsUI.changeTabs('rulesTab'); @@ -84,20 +102,6 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { }); it('navigates to an alert details page', async () => { - const { body: createdConnector } = await supertest - .post(`/api/actions/connector`) - .set('kbn-xsrf', 'foo') - .send(getTestConnectorData()) - .expect(200); - objectRemover.add(createdConnector.id, 'connector', 'actions'); - - const { body: createdAlert } = await supertest - .post(`/api/alerting/rule`) - .set('kbn-xsrf', 'foo') - .send(getTestAlertData()) - .expect(200); - objectRemover.add(createdAlert.id, 'alert', 'alerts'); - // refresh to see alert await browser.refresh(); @@ -107,10 +111,10 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { await testSubjects.existOrFail('rulesList'); // click on first alert - await pageObjects.triggersActionsUI.clickOnAlertInAlertsList(createdAlert.name); + await pageObjects.triggersActionsUI.clickOnAlertInAlertsList(createdRule.name); // Verify url - expect(await browser.getCurrentUrl()).to.contain(`/rule/${createdAlert.id}`); + expect(await browser.getCurrentUrl()).to.contain(`/rule/${createdRule.id}`); }); }); }); diff --git a/x-pack/test/functional_with_es_ssl/plugins/alerts/server/plugin.ts b/x-pack/test/functional_with_es_ssl/plugins/alerts/server/plugin.ts index 972b9cf2b3af6..b4a2ee84566cc 100644 --- a/x-pack/test/functional_with_es_ssl/plugins/alerts/server/plugin.ts +++ b/x-pack/test/functional_with_es_ssl/plugins/alerts/server/plugin.ts @@ -6,17 +6,14 @@ */ import { Plugin, CoreSetup } from '@kbn/core/server'; -import { - PluginSetupContract as AlertingSetup, - RuleType, - RuleTypeParams, -} from '@kbn/alerting-plugin/server'; +import { AlertingServerSetup, RuleType, RuleTypeParams } from '@kbn/alerting-plugin/server'; import { FeaturesPluginSetup } from '@kbn/features-plugin/server'; +import { ALERTING_FEATURE_ID } from '@kbn/alerting-plugin/common'; import { KibanaFeatureScope } from '@kbn/features-plugin/common'; // this plugin's dependendencies export interface AlertingExampleDeps { - alerting: AlertingSetup; + alerting: AlertingServerSetup; features: FeaturesPluginSetup; } @@ -117,13 +114,27 @@ export class AlertingFixturePlugin implements Plugin { + async function updateInstruction(text: string) { + await observabilityAIAssistantAPIClient + .editor({ + endpoint: 'PUT /internal/observability_ai_assistant/kb/user_instructions', + params: { + body: { + id: 'my-instruction-that-will-be-cleared', + text, + public: false, + }, + }, + }) + .expect(200); + + const res = await observabilityAIAssistantAPIClient + .editor({ endpoint: 'GET /internal/observability_ai_assistant/kb/user_instructions' }) + .expect(200); + + return res.body.userInstructions[0].text; + } + + it('can clear the instruction', async () => { + const res1 = await updateInstruction('This is a user instruction that will be cleared'); + expect(res1).to.be('This is a user instruction that will be cleared'); + + const res2 = await updateInstruction(''); + expect(res2).to.be(''); + }); + }); }); } diff --git a/x-pack/test/observability_functional/apps/observability/pages/rules_page.ts b/x-pack/test/observability_functional/apps/observability/pages/rules_page.ts index 4ec0f412e1f03..f084c4ec2a0aa 100644 --- a/x-pack/test/observability_functional/apps/observability/pages/rules_page.ts +++ b/x-pack/test/observability_functional/apps/observability/pages/rules_page.ts @@ -36,6 +36,7 @@ export default ({ getService, getPageObjects }: FtrProviderContext) => { search_fields: ['name'], }) .expect(200); + return rules.find((rule: any) => rule.name === name); } diff --git a/x-pack/test/plugin_api_integration/test_suites/task_manager/task_management_removed_types.ts b/x-pack/test/plugin_api_integration/test_suites/task_manager/task_management_removed_types.ts index 60d858206d68e..a7447353e805a 100644 --- a/x-pack/test/plugin_api_integration/test_suites/task_manager/task_management_removed_types.ts +++ b/x-pack/test/plugin_api_integration/test_suites/task_manager/task_management_removed_types.ts @@ -47,8 +47,7 @@ export default function ({ getService }: FtrProviderContext) { const UNREGISTERED_TASK_TYPE_ID = 'ce7e1250-3322-11eb-94c1-db6995e83f6b'; const REMOVED_TASK_TYPE_ID = 'be7e1250-3322-11eb-94c1-db6995e83f6a'; - // FLAKY: https://github.com/elastic/kibana/issues/200154 - describe.skip('not registered task types', () => { + describe('not registered task types', () => { before(async () => { await esArchiver.load('x-pack/test/functional/es_archives/task_manager_removed_types'); }); diff --git a/x-pack/test/rule_registry/security_and_spaces/tests/basic/bulk_update_alerts.ts b/x-pack/test/rule_registry/security_and_spaces/tests/basic/bulk_update_alerts.ts index 68feb37137397..e54af674f6572 100644 --- a/x-pack/test/rule_registry/security_and_spaces/tests/basic/bulk_update_alerts.ts +++ b/x-pack/test/rule_registry/security_and_spaces/tests/basic/bulk_update_alerts.ts @@ -102,7 +102,6 @@ export default ({ getService }: FtrProviderContext) => { function addTests({ space, authorizedUsers, unauthorizedUsers, alertId, index }: TestCase) { authorizedUsers.forEach(({ username, password }) => { it(`${username} should bulk update alert with given id ${alertId} in ${space}/${index}`, async () => { - await esArchiver.load('x-pack/test/functional/es_archives/rule_registry/alerts'); // since this is a success case, reload the test data immediately beforehand const { body: updated } = await supertestWithoutAuth .post(`${getSpaceUrlPrefix(space)}${TEST_URL}/bulk_update`) .auth(username, password) @@ -119,7 +118,6 @@ export default ({ getService }: FtrProviderContext) => { }); it(`${username} should bulk update alerts which match KQL query string in ${space}/${index}`, async () => { - await esArchiver.load('x-pack/test/functional/es_archives/rule_registry/alerts'); // since this is a success case, reload the test data immediately beforehand const { body: updated } = await supertestWithoutAuth .post(`${getSpaceUrlPrefix(space)}${TEST_URL}/bulk_update`) .auth(username, password) @@ -134,7 +132,6 @@ export default ({ getService }: FtrProviderContext) => { }); it(`${username} should bulk update alerts which match query in DSL in ${space}/${index}`, async () => { - await esArchiver.load('x-pack/test/functional/es_archives/rule_registry/alerts'); // since this is a success case, reload the test data immediately beforehand const { body: updated } = await supertestWithoutAuth .post(`${getSpaceUrlPrefix(space)}${TEST_URL}/bulk_update`) .auth(username, password) diff --git a/x-pack/test/rule_registry/security_and_spaces/tests/basic/find_alerts.ts b/x-pack/test/rule_registry/security_and_spaces/tests/basic/find_alerts.ts index 694c27060f191..404250a169e0a 100644 --- a/x-pack/test/rule_registry/security_and_spaces/tests/basic/find_alerts.ts +++ b/x-pack/test/rule_registry/security_and_spaces/tests/basic/find_alerts.ts @@ -7,7 +7,7 @@ import expect from '@kbn/expect'; import { - ALERT_RULE_CONSUMER, + ALERT_RULE_TYPE_ID, ALERT_WORKFLOW_STATUS, } from '@kbn/rule-registry-plugin/common/technical_rule_data_field_names'; import { @@ -268,30 +268,30 @@ export default ({ getService }: FtrProviderContext) => { expect(found.body.aggregations.nbr_consumer.value).to.be.equal(2); }); - it(`${superUser.username} should handle 'siem' featureIds`, async () => { + it(`${superUser.username} should handle 'siem' rule type IDs`, async () => { const found = await supertestWithoutAuth .post(`${getSpaceUrlPrefix(SPACE1)}${TEST_URL}/find`) .auth(superUser.username, superUser.password) .set('kbn-xsrf', 'true') .send({ - feature_ids: ['siem'], + rule_type_ids: ['siem.queryRule'], }); - expect(found.body.hits.hits.every((hit: any) => hit[ALERT_RULE_CONSUMER] === 'siem')).equal( + expect(found.body.hits.hits.every((hit: any) => hit[ALERT_RULE_TYPE_ID] === 'siem')).equal( true ); }); - it(`${superUser.username} should handle 'apm' featureIds`, async () => { + it(`${superUser.username} should handle 'apm' rule type IDs`, async () => { const found = await supertestWithoutAuth .post(`${getSpaceUrlPrefix(SPACE1)}${TEST_URL}/find`) .auth(superUser.username, superUser.password) .set('kbn-xsrf', 'true') .send({ - feature_ids: ['apm'], + rule_type_ids: ['apm.error_rate'], }); - expect(found.body.hits.hits.every((hit: any) => hit[ALERT_RULE_CONSUMER] === 'apm')).equal( + expect(found.body.hits.hits.every((hit: any) => hit[ALERT_RULE_TYPE_ID] === 'apm')).equal( true ); }); diff --git a/x-pack/test/rule_registry/security_and_spaces/tests/basic/get_aad_fields_by_rule_type.ts b/x-pack/test/rule_registry/security_and_spaces/tests/basic/get_aad_fields_by_rule_type.ts index 4d8fed02a7c71..1e7759b06c30d 100644 --- a/x-pack/test/rule_registry/security_and_spaces/tests/basic/get_aad_fields_by_rule_type.ts +++ b/x-pack/test/rule_registry/security_and_spaces/tests/basic/get_aad_fields_by_rule_type.ts @@ -38,8 +38,12 @@ export default ({ getService }: FtrProviderContext) => { await esArchiver.load('x-pack/test/functional/es_archives/rule_registry/alerts'); }); + after(async () => { + await esArchiver.unload('x-pack/test/functional/es_archives/rule_registry/alerts'); + }); + describe('Users:', () => { - it(`${obsOnlySpacesAll.username} should be able to get browser fields for o11y featureIds`, async () => { + it(`${obsOnlySpacesAll.username} should be able to get browser fields for o11y rule type ids`, async () => { await retry.try(async () => { const aadFields = await getAADFieldsByRuleType( obsOnlySpacesAll, diff --git a/x-pack/test/rule_registry/security_and_spaces/tests/basic/get_alert_summary.ts b/x-pack/test/rule_registry/security_and_spaces/tests/basic/get_alert_summary.ts index 5da72c7f6a76a..abfc4c9d5aa79 100644 --- a/x-pack/test/rule_registry/security_and_spaces/tests/basic/get_alert_summary.ts +++ b/x-pack/test/rule_registry/security_and_spaces/tests/basic/get_alert_summary.ts @@ -39,7 +39,7 @@ export default ({ getService }: FtrProviderContext) => { .send({ gte: '2020-12-16T15:00:00.000Z', lte: '2020-12-16T16:00:00.000Z', - featureIds: ['logs'], + ruleTypeIds: ['logs.alert.document.count'], fixed_interval: '10m', }) .expect(200); @@ -83,7 +83,7 @@ export default ({ getService }: FtrProviderContext) => { }, }, ], - featureIds: ['logs'], + ruleTypeIds: ['logs.alert.document.count'], fixed_interval: '10m', }) .expect(200); @@ -127,7 +127,7 @@ export default ({ getService }: FtrProviderContext) => { }, }, ], - featureIds: ['logs'], + ruleTypeIds: ['logs.alert.document.count'], fixed_interval: '10m', }) .expect(200); diff --git a/x-pack/test/rule_registry/security_and_spaces/tests/basic/get_alerts_index.ts b/x-pack/test/rule_registry/security_and_spaces/tests/basic/get_alerts_index.ts index 530c0a57b02ef..604cff34865d9 100644 --- a/x-pack/test/rule_registry/security_and_spaces/tests/basic/get_alerts_index.ts +++ b/x-pack/test/rule_registry/security_and_spaces/tests/basic/get_alerts_index.ts @@ -30,16 +30,18 @@ export default ({ getService }: FtrProviderContext) => { const STACK_ALERT_INDEX = '.alerts-stack.alerts-default'; const getIndexName = async ( - featureIds: string[], + ruleTypeIds: string[], user: User, space: string, expectedStatusCode: number = 200 ) => { const resp = await supertestWithoutAuth - .get(`${getSpaceUrlPrefix(space)}${ALERTS_INDEX_URL}?features=${featureIds.join(',')}`) + .get(`${getSpaceUrlPrefix(space)}${ALERTS_INDEX_URL}`) + .query({ ruleTypeIds }) .auth(user.username, user.password) .set('kbn-xsrf', 'true') .expect(expectedStatusCode); + return resp.body.index_name as string[]; }; @@ -47,33 +49,34 @@ export default ({ getService }: FtrProviderContext) => { before(async () => { await esArchiver.load('x-pack/test/functional/es_archives/rule_registry/alerts'); }); + + before(async () => { + await esArchiver.unload('x-pack/test/functional/es_archives/rule_registry/alerts'); + }); + describe('Users:', () => { it(`${obsOnlySpacesAll.username} should be able to access the APM alert in ${SPACE1}`, async () => { - const indexNames = await getIndexName(['apm'], obsOnlySpacesAll, SPACE1); + const indexNames = await getIndexName(['apm.error_rate'], obsOnlySpacesAll, SPACE1); expect(indexNames.includes(APM_ALERT_INDEX)).to.eql(true); // assert this here so we can use constants in the dynamically-defined test cases below }); it(`${superUser.username} should be able to access the APM alert in ${SPACE1}`, async () => { - const indexNames = await getIndexName(['apm'], superUser, SPACE1); + const indexNames = await getIndexName(['apm.error_rate'], superUser, SPACE1); expect(indexNames.includes(APM_ALERT_INDEX)).to.eql(true); // assert this here so we can use constants in the dynamically-defined test cases below }); it(`${secOnlyRead.username} should NOT be able to access the APM alert in ${SPACE1}`, async () => { - const indexNames = await getIndexName(['apm'], secOnlyRead, SPACE1); + const indexNames = await getIndexName(['apm.error_rate'], secOnlyRead, SPACE1); expect(indexNames?.length).to.eql(0); }); it(`${secOnlyRead.username} should be able to access the security solution alert in ${SPACE1}`, async () => { - const indexNames = await getIndexName(['siem'], secOnlyRead, SPACE1); + const indexNames = await getIndexName(['siem.esqlRule'], secOnlyRead, SPACE1); expect(indexNames.includes(`${SECURITY_SOLUTION_ALERT_INDEX}-${SPACE1}`)).to.eql(true); // assert this here so we can use constants in the dynamically-defined test cases below }); it(`${stackAlertsOnlyReadSpacesAll.username} should be able to access the stack alert in ${SPACE1}`, async () => { - const indexNames = await getIndexName( - ['stackAlerts'], - stackAlertsOnlyReadSpacesAll, - SPACE1 - ); + const indexNames = await getIndexName(['.es-query'], stackAlertsOnlyReadSpacesAll, SPACE1); expect(indexNames.includes(STACK_ALERT_INDEX)).to.eql(true); }); }); 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_rule_type_ids.ts similarity index 74% rename from x-pack/test/rule_registry/security_and_spaces/tests/basic/get_browser_fields_by_feature_id.ts rename to x-pack/test/rule_registry/security_and_spaces/tests/basic/get_browser_fields_by_rule_type_ids.ts index 352ff0188b015..ac05dad573c65 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_rule_type_ids.ts @@ -6,6 +6,7 @@ */ import expect from 'expect'; +import { OBSERVABILITY_RULE_TYPE_IDS } from '@kbn/rule-data-utils'; import { superUser, obsOnlySpacesAll, secOnlyRead } from '../../../common/lib/authentication/users'; import type { User } from '../../../common/lib/authentication/types'; import { FtrProviderContext } from '../../../common/ftr_provider_context'; @@ -20,31 +21,38 @@ export default ({ getService }: FtrProviderContext) => { const getBrowserFieldsByFeatureId = async ( user: User, - featureIds: string[], + ruleTypeIds: string[], expectedStatusCode: number = 200 ) => { const resp = await supertestWithoutAuth .get(`${getSpaceUrlPrefix(SPACE1)}${TEST_URL}`) - .query({ featureIds }) + .query({ ruleTypeIds }) .auth(user.username, user.password) .set('kbn-xsrf', 'true') .expect(expectedStatusCode); + return resp.body; }; - describe('Alert - Get browser fields by featureId', () => { + describe('Alert - Get browser fields by rule type IDs', () => { + const ruleTypeIds = [ + ...OBSERVABILITY_RULE_TYPE_IDS, + '.es-query', + 'xpack.ml.anomaly_detection_alert', + ]; + before(async () => { await esArchiver.load('x-pack/test/functional/es_archives/rule_registry/alerts'); }); + after(async () => { + await esArchiver.unload('x-pack/test/functional/es_archives/rule_registry/alerts'); + }); + describe('Users:', () => { - it(`${obsOnlySpacesAll.username} should be able to get browser fields for o11y featureIds`, async () => { - const resp = await getBrowserFieldsByFeatureId(obsOnlySpacesAll, [ - 'apm', - 'infrastructure', - 'logs', - 'uptime', - ]); + it(`${obsOnlySpacesAll.username} should be able to get browser fields for o11y ruleTypeIds that has access to`, async () => { + const resp = await getBrowserFieldsByFeatureId(obsOnlySpacesAll, ruleTypeIds); + expect(Object.keys(resp.browserFields)).toEqual([ 'base', 'agent', @@ -61,13 +69,9 @@ export default ({ getService }: FtrProviderContext) => { ]); }); - it(`${superUser.username} should be able to get browser fields for o11y featureIds`, async () => { - const resp = await getBrowserFieldsByFeatureId(superUser, [ - 'apm', - 'infrastructure', - 'logs', - 'uptime', - ]); + it(`${superUser.username} should be able to get browser fields for all o11y ruleTypeIds`, async () => { + const resp = await getBrowserFieldsByFeatureId(superUser, ruleTypeIds); + expect(Object.keys(resp.browserFields)).toEqual([ 'base', 'agent', @@ -82,17 +86,18 @@ export default ({ getService }: FtrProviderContext) => { 'observer', 'orchestrator', 'service', + 'slo', 'tls', 'url', ]); }); - it(`${superUser.username} should NOT be able to get browser fields for siem featureId`, async () => { - await getBrowserFieldsByFeatureId(superUser, ['siem'], 404); + it(`${superUser.username} should NOT be able to get browser fields for siem rule types`, async () => { + await getBrowserFieldsByFeatureId(superUser, ['siem.queryRule'], 404); }); - it(`${secOnlyRead.username} should NOT be able to get browser fields for siem featureId`, async () => { - await getBrowserFieldsByFeatureId(secOnlyRead, ['siem'], 404); + it(`${secOnlyRead.username} should NOT be able to get browser fields for siem rule types`, async () => { + await getBrowserFieldsByFeatureId(secOnlyRead, ['siem.queryRule'], 404); }); }); }); diff --git a/x-pack/test/rule_registry/security_and_spaces/tests/basic/get_feature_ids_by_registration_contexts.ts b/x-pack/test/rule_registry/security_and_spaces/tests/basic/get_feature_ids_by_registration_contexts.ts deleted file mode 100644 index 5b4063cfe5285..0000000000000 --- a/x-pack/test/rule_registry/security_and_spaces/tests/basic/get_feature_ids_by_registration_contexts.ts +++ /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; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import expect from '@kbn/expect'; - -import { superUser, obsOnlySpacesAll, secOnlyRead } from '../../../common/lib/authentication/users'; -import type { User } from '../../../common/lib/authentication/types'; -import { FtrProviderContext } from '../../../common/ftr_provider_context'; -import { getSpaceUrlPrefix } from '../../../common/lib/authentication/spaces'; - -// eslint-disable-next-line import/no-default-export -export default ({ getService }: FtrProviderContext) => { - const supertestWithoutAuth = getService('supertestWithoutAuth'); - const esArchiver = getService('esArchiver'); - - const TEST_URL = '/internal/rac/alerts'; - const ALERTS_FEATURE_IDS_URL = `${TEST_URL}/_feature_ids`; - const SPACE1 = 'space1'; - - const getApmFeatureIdByRegistrationContexts = async ( - user: User, - space: string, - expectedStatusCode: number = 200 - ) => { - const resp = await supertestWithoutAuth - .get( - `${getSpaceUrlPrefix(space)}${ALERTS_FEATURE_IDS_URL}?registrationContext=observability.apm` - ) - .auth(user.username, user.password) - .set('kbn-xsrf', 'true') - .expect(expectedStatusCode); - return resp.body as string[]; - }; - - const getSecurityFeatureIdByRegistrationContexts = async ( - user: User, - space: string, - expectedStatusCode: number = 200 - ) => { - const resp = await supertestWithoutAuth - .get(`${getSpaceUrlPrefix(space)}${ALERTS_FEATURE_IDS_URL}?registrationContext=security`) - .auth(user.username, user.password) - .set('kbn-xsrf', 'true') - .expect(expectedStatusCode); - - return resp.body as string[]; - }; - - describe('Alert - Get feature ids by registration context', () => { - before(async () => { - await esArchiver.load('x-pack/test/functional/es_archives/rule_registry/alerts'); - }); - describe('Users:', () => { - it(`${obsOnlySpacesAll.username} should be able to get feature id for registration context 'observability.apm' in ${SPACE1}`, async () => { - const featureIds = await getApmFeatureIdByRegistrationContexts(obsOnlySpacesAll, SPACE1); - expect(featureIds).to.eql(['apm']); - }); - - it(`${superUser.username} should be able to get feature id for registration context 'observability.apm' in ${SPACE1}`, async () => { - const featureIds = await getApmFeatureIdByRegistrationContexts(superUser, SPACE1); - expect(featureIds).to.eql(['apm']); - }); - - it(`${secOnlyRead.username} should NOT be able to get feature id for registration context 'observability.apm' in ${SPACE1}`, async () => { - const featureIds = await getApmFeatureIdByRegistrationContexts(secOnlyRead, SPACE1); - expect(featureIds).to.eql([]); - }); - - it(`${secOnlyRead.username} should be able to get feature id for registration context 'security' in ${SPACE1}`, async () => { - const featureIds = await getSecurityFeatureIdByRegistrationContexts(secOnlyRead, SPACE1); - expect(featureIds).to.eql(['siem']); - }); - }); - }); -}; diff --git a/x-pack/test/rule_registry/security_and_spaces/tests/basic/index.ts b/x-pack/test/rule_registry/security_and_spaces/tests/basic/index.ts index 5237cd02c0c89..e7593121bc2d0 100644 --- a/x-pack/test/rule_registry/security_and_spaces/tests/basic/index.ts +++ b/x-pack/test/rule_registry/security_and_spaces/tests/basic/index.ts @@ -25,11 +25,10 @@ export default ({ loadTestFile, getService }: FtrProviderContext): void => { // loadTestFile(require.resolve('./update_alert')); // loadTestFile(require.resolve('./bulk_update_alerts')); - loadTestFile(require.resolve('./get_feature_ids_by_registration_contexts')); loadTestFile(require.resolve('./get_alerts_index')); loadTestFile(require.resolve('./find_alerts')); loadTestFile(require.resolve('./search_strategy')); - loadTestFile(require.resolve('./get_browser_fields_by_feature_id')); + loadTestFile(require.resolve('./get_browser_fields_by_rule_type_ids')); loadTestFile(require.resolve('./get_alert_summary')); loadTestFile(require.resolve('./get_aad_fields_by_rule_type')); }); diff --git a/x-pack/test/rule_registry/security_and_spaces/tests/basic/search_strategy.ts b/x-pack/test/rule_registry/security_and_spaces/tests/basic/search_strategy.ts index ffcd6fee5cf85..6462e2a1ec807 100644 --- a/x-pack/test/rule_registry/security_and_spaces/tests/basic/search_strategy.ts +++ b/x-pack/test/rule_registry/security_and_spaces/tests/basic/search_strategy.ts @@ -5,7 +5,6 @@ * 2.0. */ import expect from '@kbn/expect'; -import { AlertConsumers } from '@kbn/rule-data-utils'; import type { RuleRegistrySearchResponse } from '@kbn/rule-registry-plugin/common'; import type { FtrProviderContext } from '../../../common/ftr_provider_context'; @@ -39,6 +38,7 @@ export default ({ getService }: FtrProviderContext) => { before(async () => { await esArchiver.load('x-pack/test/functional/es_archives/observability/alerts'); }); + after(async () => { await esArchiver.unload('x-pack/test/functional/es_archives/observability/alerts'); }); @@ -54,15 +54,14 @@ export default ({ getService }: FtrProviderContext) => { kibanaVersion, internalOrigin: 'Kibana', options: { - featureIds: [AlertConsumers.LOGS], + ruleTypeIds: ['logs.alert.document.count'], }, strategy: 'privateRuleRegistryAlertsSearchStrategy', }); + expect(result.rawResponse.hits.total).to.eql(5); - const consumers = result.rawResponse.hits.hits.map((hit) => { - return hit.fields?.['kibana.alert.rule.consumer']; - }); - expect(consumers.every((consumer) => consumer === AlertConsumers.LOGS)); + + validateRuleTypeIds(result, ['logs.alert.document.count']); }); it('should support pagination and sorting', async () => { @@ -76,7 +75,7 @@ export default ({ getService }: FtrProviderContext) => { kibanaVersion, internalOrigin: 'Kibana', options: { - featureIds: [AlertConsumers.LOGS], + ruleTypeIds: ['logs.alert.document.count'], pagination: { pageSize: 2, pageIndex: 1, @@ -91,25 +90,35 @@ export default ({ getService }: FtrProviderContext) => { }, strategy: 'privateRuleRegistryAlertsSearchStrategy', }); + expect(result.rawResponse.hits.total).to.eql(5); expect(result.rawResponse.hits.hits.length).to.eql(2); + const first = result.rawResponse.hits.hits[0].fields?.['kibana.alert.evaluation.value']; const second = result.rawResponse.hits.hits[1].fields?.['kibana.alert.evaluation.value']; + expect(first > second).to.be(true); }); }); describe('siem', () => { + const siemRuleTypeIds = [ + 'siem.indicatorRule', + 'siem.thresholdRule', + 'siem.eqlRule', + 'siem.queryRule', + ]; + before(async () => { await esArchiver.load('x-pack/test/functional/es_archives/observability/alerts'); await esArchiver.load('x-pack/test/functional/es_archives/security_solution/alerts/8.1.0'); }); after(async () => { + await esArchiver.unload('x-pack/test/functional/es_archives/observability/alerts'); await esArchiver.unload( 'x-pack/test/functional/es_archives/security_solution/alerts/8.1.0' ); - await esArchiver.unload('x-pack/test/functional/es_archives/observability/alerts'); }); it('should return alerts from siem rules', async () => { @@ -123,15 +132,14 @@ export default ({ getService }: FtrProviderContext) => { kibanaVersion, internalOrigin: 'Kibana', options: { - featureIds: [AlertConsumers.SIEM], + ruleTypeIds: siemRuleTypeIds, }, strategy: 'privateRuleRegistryAlertsSearchStrategy', }); + expect(result.rawResponse.hits.total).to.eql(50); - const consumers = result.rawResponse.hits.hits.map( - (hit) => hit.fields?.['kibana.alert.rule.consumer'] - ); - expect(consumers.every((consumer) => consumer === AlertConsumers.SIEM)); + + validateRuleTypeIds(result, siemRuleTypeIds); }); it('should throw an error when trying to to search for more than just siem', async () => { @@ -145,13 +153,14 @@ export default ({ getService }: FtrProviderContext) => { kibanaVersion, internalOrigin: 'Kibana', options: { - featureIds: [AlertConsumers.SIEM, AlertConsumers.LOGS], + ruleTypeIds: ['siem.indicatorRule', 'logs.alert.document.count'], }, strategy: 'privateRuleRegistryAlertsSearchStrategy', }); - expect(result.statusCode).to.be(500); + + expect(result.statusCode).to.be(400); expect(result.message).to.be( - `The privateRuleRegistryAlertsSearchStrategy search strategy is unable to accommodate requests containing multiple feature IDs and one of those IDs is SIEM.` + 'The privateRuleRegistryAlertsSearchStrategy search strategy is unable to accommodate requests containing multiple rule types with mixed authorization.' ); }); @@ -168,7 +177,7 @@ export default ({ getService }: FtrProviderContext) => { kibanaVersion, internalOrigin: 'Kibana', options: { - featureIds: [AlertConsumers.SIEM], + ruleTypeIds: siemRuleTypeIds, runtimeMappings: { [runtimeFieldKey]: { type: 'keyword', @@ -180,18 +189,24 @@ export default ({ getService }: FtrProviderContext) => { }, strategy: 'privateRuleRegistryAlertsSearchStrategy', }); + expect(result.rawResponse.hits.total).to.eql(50); + const runtimeFields = result.rawResponse.hits.hits.map( (hit) => hit.fields?.[runtimeFieldKey] ); + expect(runtimeFields.every((field) => field === runtimeFieldValue)); }); }); describe('apm', () => { + const apmRuleTypeIds = ['apm.transaction_error_rate', 'apm.error_rate']; + before(async () => { await esArchiver.load('x-pack/test/functional/es_archives/observability/alerts'); }); + after(async () => { await esArchiver.unload('x-pack/test/functional/es_archives/observability/alerts'); }); @@ -207,19 +222,20 @@ export default ({ getService }: FtrProviderContext) => { kibanaVersion, internalOrigin: 'Kibana', options: { - featureIds: [AlertConsumers.APM], + ruleTypeIds: apmRuleTypeIds, }, strategy: 'privateRuleRegistryAlertsSearchStrategy', space: 'default', }); + expect(result.rawResponse.hits.total).to.eql(9); - const consumers = result.rawResponse.hits.hits.map( - (hit) => hit.fields?.['kibana.alert.rule.consumer'] - ); - expect(consumers.every((consumer) => consumer === AlertConsumers.APM)); + + validateRuleTypeIds(result, apmRuleTypeIds); }); - it('should not by pass our RBAC authz filter with a should filter', async () => { + it('should return alerts from different rules', async () => { + const ruleTypeIds = [...apmRuleTypeIds, 'logs.alert.document.count']; + const result = await secureSearch.send({ supertestWithoutAuth, auth: { @@ -230,7 +246,83 @@ export default ({ getService }: FtrProviderContext) => { kibanaVersion, internalOrigin: 'Kibana', options: { - featureIds: [AlertConsumers.APM], + ruleTypeIds, + }, + strategy: 'privateRuleRegistryAlertsSearchStrategy', + space: 'default', + }); + + expect(result.rawResponse.hits.total).to.eql(14); + + validateRuleTypeIds(result, ruleTypeIds); + }); + + it('should filter alerts by rule type IDs with consumers', async () => { + const result = await secureSearch.send({ + supertestWithoutAuth, + auth: { + username: obsOnlySpacesAll.username, + password: obsOnlySpacesAll.password, + }, + referer: 'test', + kibanaVersion, + internalOrigin: 'Kibana', + options: { + ruleTypeIds: apmRuleTypeIds, + consumers: ['alerts', 'logs'], + }, + strategy: 'privateRuleRegistryAlertsSearchStrategy', + space: 'default', + }); + + expect(result.rawResponse.hits.total).to.eql(9); + + validateRuleTypeIds(result, apmRuleTypeIds); + }); + + it('should filter alerts by consumers with rule type IDs', async () => { + const ruleTypeIds = [...apmRuleTypeIds, 'logs.alert.document.count']; + + const result = await secureSearch.send({ + supertestWithoutAuth, + auth: { + username: obsOnlySpacesAll.username, + password: obsOnlySpacesAll.password, + }, + referer: 'test', + kibanaVersion, + internalOrigin: 'Kibana', + options: { + ruleTypeIds, + consumers: ['alerts'], + }, + strategy: 'privateRuleRegistryAlertsSearchStrategy', + space: 'default', + }); + + /** + *There are five documents of rule type logs.alert.document.count + * The four have the consumer set to alerts + * and the one has the consumer set to logs. + * All apm rule types (nine in total) have consumer set to alerts. + */ + expect(result.rawResponse.hits.total).to.eql(13); + + validateRuleTypeIds(result, ruleTypeIds); + }); + + it('should not by pass our RBAC authz filter with a should filter for rule type ids', async () => { + const result = await secureSearch.send({ + supertestWithoutAuth, + auth: { + username: obsOnlySpacesAll.username, + password: obsOnlySpacesAll.password, + }, + referer: 'test', + kibanaVersion, + internalOrigin: 'Kibana', + options: { + ruleTypeIds: apmRuleTypeIds, query: { bool: { filter: [], @@ -240,7 +332,7 @@ export default ({ getService }: FtrProviderContext) => { should: [ { match: { - 'kibana.alert.rule.consumer': 'logs', + 'kibana.alert.rule.rule_type_id': 'metrics.alert.inventory.threshold', }, }, ], @@ -256,14 +348,56 @@ export default ({ getService }: FtrProviderContext) => { strategy: 'privateRuleRegistryAlertsSearchStrategy', space: 'default', }); + expect(result.rawResponse.hits.total).to.eql(9); - const consumers = result.rawResponse.hits.hits.map( - (hit) => hit.fields?.['kibana.alert.rule.consumer'] - ); - expect(consumers.every((consumer) => consumer === AlertConsumers.APM)); + + validateRuleTypeIds(result, apmRuleTypeIds); + }); + + it('should not by pass our RBAC authz filter with a should filter for consumers', async () => { + const result = await secureSearch.send({ + supertestWithoutAuth, + auth: { + username: obsOnlySpacesAll.username, + password: obsOnlySpacesAll.password, + }, + referer: 'test', + kibanaVersion, + internalOrigin: 'Kibana', + options: { + ruleTypeIds: apmRuleTypeIds, + query: { + bool: { + filter: [], + should: [ + { + bool: { + should: [ + { + match: { + 'kibana.alert.rule.consumer': 'infrastructure', + }, + }, + ], + minimum_should_match: 1, + }, + }, + ], + must: [], + must_not: [], + }, + }, + }, + strategy: 'privateRuleRegistryAlertsSearchStrategy', + space: 'default', + }); + + expect(result.rawResponse.hits.total).to.eql(9); + + validateRuleTypeIds(result, apmRuleTypeIds); }); - it('should return an empty response with must filter and our RBAC authz filter', async () => { + it('should return an empty response with must filter and our RBAC authz filter for rule type ids', async () => { const result = await secureSearch.send({ supertestWithoutAuth, auth: { @@ -274,7 +408,7 @@ export default ({ getService }: FtrProviderContext) => { kibanaVersion, internalOrigin: 'Kibana', options: { - featureIds: [AlertConsumers.APM], + ruleTypeIds: apmRuleTypeIds, query: { bool: { filter: [], @@ -284,7 +418,7 @@ export default ({ getService }: FtrProviderContext) => { should: [ { match: { - 'kibana.alert.rule.consumer': 'logs', + 'kibana.alert.rule.rule_type_id': 'metrics.alert.inventory.threshold', }, }, ], @@ -300,10 +434,11 @@ export default ({ getService }: FtrProviderContext) => { strategy: 'privateRuleRegistryAlertsSearchStrategy', space: 'default', }); + expect(result.rawResponse.hits.total).to.eql(0); }); - it('should not by pass our RBAC authz filter with must_not filter', async () => { + it('should return an empty response with must filter and our RBAC authz filter for consumers', async () => { const result = await secureSearch.send({ supertestWithoutAuth, auth: { @@ -314,7 +449,91 @@ export default ({ getService }: FtrProviderContext) => { kibanaVersion, internalOrigin: 'Kibana', options: { - featureIds: [AlertConsumers.APM], + ruleTypeIds: apmRuleTypeIds, + query: { + bool: { + filter: [], + must: [ + { + bool: { + should: [ + { + match: { + 'kibana.alert.rule.consumer': 'infrastructure', + }, + }, + ], + minimum_should_match: 1, + }, + }, + ], + should: [], + must_not: [], + }, + }, + }, + strategy: 'privateRuleRegistryAlertsSearchStrategy', + space: 'default', + }); + + expect(result.rawResponse.hits.total).to.eql(0); + }); + + it('should not by pass our RBAC authz filter with must_not filter for rule type ids', async () => { + const result = await secureSearch.send({ + supertestWithoutAuth, + auth: { + username: obsOnlySpacesAll.username, + password: obsOnlySpacesAll.password, + }, + referer: 'test', + kibanaVersion, + internalOrigin: 'Kibana', + options: { + ruleTypeIds: apmRuleTypeIds, + query: { + bool: { + filter: [], + must: [], + must_not: [ + { + bool: { + should: [ + ...apmRuleTypeIds.map((apmRuleTypeId) => ({ + match: { + 'kibana.alert.rule.rule_type_id': apmRuleTypeId, + }, + })), + ], + minimum_should_match: apmRuleTypeIds.length, + }, + }, + ], + should: [], + }, + }, + }, + strategy: 'privateRuleRegistryAlertsSearchStrategy', + space: 'default', + }); + + expect(result.rawResponse.hits.total).to.eql(9); + + validateRuleTypeIds(result, apmRuleTypeIds); + }); + + it('should not by pass our RBAC authz filter with must_not filter for consumers', async () => { + const result = await secureSearch.send({ + supertestWithoutAuth, + auth: { + username: obsOnlySpacesAll.username, + password: obsOnlySpacesAll.password, + }, + referer: 'test', + kibanaVersion, + internalOrigin: 'Kibana', + options: { + ruleTypeIds: apmRuleTypeIds, query: { bool: { filter: [], @@ -340,11 +559,136 @@ export default ({ getService }: FtrProviderContext) => { strategy: 'privateRuleRegistryAlertsSearchStrategy', space: 'default', }); + expect(result.rawResponse.hits.total).to.eql(9); - const consumers = result.rawResponse.hits.hits.map( - (hit) => hit.fields?.['kibana.alert.rule.consumer'] - ); - expect(consumers.every((consumer) => consumer === AlertConsumers.APM)); + + validateRuleTypeIds(result, apmRuleTypeIds); + }); + + it('should not by pass our RBAC authz filter with the ruleTypeIds and consumers parameter', async () => { + const ruleTypeIds = [ + ...apmRuleTypeIds, + 'metrics.alert.inventory.threshold', + 'metrics.alert.threshold', + '.es-query', + ]; + + const result = await secureSearch.send({ + supertestWithoutAuth, + auth: { + /** + * obsOnlySpacesAll does not have access to the following pairs: + * + * Rule type ID: metrics.alert.inventory.threshold + * Consumer: alerts + * + * Rule type ID: metrics.alert.threshold + * Consumer: alerts + * + * Rule type ID: .es-query + * Consumer: discover + */ + username: obsOnlySpacesAll.username, + password: obsOnlySpacesAll.password, + }, + referer: 'test', + kibanaVersion, + internalOrigin: 'Kibana', + options: { + ruleTypeIds, + consumers: ['alerts', 'discover'], + }, + strategy: 'privateRuleRegistryAlertsSearchStrategy', + space: 'default', + }); + + expect(result.rawResponse.hits.total).to.eql(9); + + validateRuleTypeIds(result, apmRuleTypeIds); + }); + + it('should not return any alerts if the user does not have access to any alerts', async () => { + const result = await secureSearch.send({ + supertestWithoutAuth, + auth: { + username: obsOnlySpacesAll.username, + password: obsOnlySpacesAll.password, + }, + referer: 'test', + kibanaVersion, + internalOrigin: 'Kibana', + options: { + ruleTypeIds: ['metrics.alert.threshold', 'metrics.alert.inventory.threshold'], + }, + strategy: 'privateRuleRegistryAlertsSearchStrategy', + space: 'default', + }); + + expect(result.rawResponse.hits.total).to.eql(0); + }); + + it('should not return alerts that the user does not have access to', async () => { + const result = await secureSearch.send({ + supertestWithoutAuth, + auth: { + username: obsOnlySpacesAll.username, + password: obsOnlySpacesAll.password, + }, + referer: 'test', + kibanaVersion, + internalOrigin: 'Kibana', + options: { + ruleTypeIds: ['metrics.alert.threshold', 'logs.alert.document.count'], + }, + strategy: 'privateRuleRegistryAlertsSearchStrategy', + space: 'default', + }); + + expect(result.rawResponse.hits.total).to.eql(5); + validateRuleTypeIds(result, ['logs.alert.document.count']); + }); + + it('should not return alerts if the user does not have access to using a filter', async () => { + const result = await secureSearch.send({ + supertestWithoutAuth, + auth: { + username: obsOnlySpacesAll.username, + password: obsOnlySpacesAll.password, + }, + referer: 'test', + kibanaVersion, + internalOrigin: 'Kibana', + options: { + ruleTypeIds: apmRuleTypeIds, + query: { + bool: { + filter: [], + should: [ + { + bool: { + should: [ + { + match: { + 'kibana.alert.rule.rule_type_id': 'metrics.alert.inventory.threshold', + }, + }, + ], + minimum_should_match: 1, + }, + }, + ], + must: [], + must_not: [], + }, + }, + }, + strategy: 'privateRuleRegistryAlertsSearchStrategy', + space: 'default', + }); + + expect(result.rawResponse.hits.total).to.eql(9); + + validateRuleTypeIds(result, apmRuleTypeIds); }); }); @@ -367,11 +711,13 @@ export default ({ getService }: FtrProviderContext) => { kibanaVersion, internalOrigin: 'Kibana', options: { - featureIds: ['discover'], + ruleTypeIds: ['.es-query'], }, strategy: 'privateRuleRegistryAlertsSearchStrategy', }); + validateRuleTypeIds(result, ['.es-query']); + expect(result.rawResponse.hits.total).to.eql(1); const consumers = result.rawResponse.hits.hits.map((hit) => { @@ -392,11 +738,13 @@ export default ({ getService }: FtrProviderContext) => { kibanaVersion, internalOrigin: 'Kibana', options: { - featureIds: ['discover'], + ruleTypeIds: ['.es-query'], }, strategy: 'privateRuleRegistryAlertsSearchStrategy', }); + validateRuleTypeIds(result, ['.es-query']); + expect(result.rawResponse.hits.total).to.eql(1); const consumers = result.rawResponse.hits.hits.map((hit) => { @@ -417,13 +765,12 @@ export default ({ getService }: FtrProviderContext) => { kibanaVersion, internalOrigin: 'Kibana', options: { - featureIds: ['discover'], + ruleTypeIds: ['.es-query'], }, strategy: 'privateRuleRegistryAlertsSearchStrategy', }); - expect(result.statusCode).to.be(500); - expect(result.message).to.be('Unauthorized to find alerts for any rule types'); + expect(result.rawResponse.hits.total).to.eql(0); }); }); @@ -439,12 +786,29 @@ export default ({ getService }: FtrProviderContext) => { kibanaVersion, internalOrigin: 'Kibana', options: { - featureIds: [], + ruleTypeIds: [], }, strategy: 'privateRuleRegistryAlertsSearchStrategy', }); - expect(result.rawResponse).to.eql({}); + + expect(result.rawResponse.hits.total).to.eql(0); }); }); }); }; + +const validateRuleTypeIds = (result: RuleRegistrySearchResponse, ruleTypeIdsToVerify: string[]) => { + expect(result.rawResponse.hits.total).to.greaterThan(0); + + const ruleTypeIds = result.rawResponse.hits.hits + .map((hit) => { + return hit.fields?.['kibana.alert.rule.rule_type_id']; + }) + .flat(); + + expect( + ruleTypeIds.every((ruleTypeId) => + ruleTypeIdsToVerify.some((ruleTypeIdToVerify) => ruleTypeIdToVerify === ruleTypeId) + ) + ).to.eql(true); +}; diff --git a/x-pack/test/rule_registry/security_and_spaces/tests/basic/update_alert.ts b/x-pack/test/rule_registry/security_and_spaces/tests/basic/update_alert.ts index 4d7607442fbcb..237f492ebf363 100644 --- a/x-pack/test/rule_registry/security_and_spaces/tests/basic/update_alert.ts +++ b/x-pack/test/rule_registry/security_and_spaces/tests/basic/update_alert.ts @@ -101,7 +101,6 @@ export default ({ getService }: FtrProviderContext) => { function addTests({ space, authorizedUsers, unauthorizedUsers, alertId, index }: TestCase) { authorizedUsers.forEach(({ username, password }) => { it(`${username} should be able to update alert ${alertId} in ${space}/${index}`, async () => { - await esArchiver.load('x-pack/test/functional/es_archives/rule_registry/alerts'); // since this is a success case, reload the test data immediately beforehand await supertestWithoutAuth .post(`${getSpaceUrlPrefix(space)}${TEST_URL}`) .auth(username, password) diff --git a/x-pack/test/rule_registry/security_and_spaces/tests/trial/get_alerts.ts b/x-pack/test/rule_registry/security_and_spaces/tests/trial/get_alerts.ts index f4aa5c503bc19..f3c4a4e6146a2 100644 --- a/x-pack/test/rule_registry/security_and_spaces/tests/trial/get_alerts.ts +++ b/x-pack/test/rule_registry/security_and_spaces/tests/trial/get_alerts.ts @@ -47,6 +47,11 @@ export default ({ getService }: FtrProviderContext) => { before(async () => { await esArchiver.load('x-pack/test/functional/es_archives/rule_registry/alerts'); }); + + after(async () => { + await esArchiver.unload('x-pack/test/functional/es_archives/rule_registry/alerts'); + }); + describe('Users:', () => { // user with minimal_read and alerts_read privileges should be able to access apm alert it(`${obsMinReadAlertsRead.username} should be able to access the APM alert in ${SPACE1}`, async () => { diff --git a/x-pack/test/rule_registry/security_and_spaces/tests/trial/update_alert.ts b/x-pack/test/rule_registry/security_and_spaces/tests/trial/update_alert.ts index 9b4e4b70d59c8..0de2adbf0f57f 100644 --- a/x-pack/test/rule_registry/security_and_spaces/tests/trial/update_alert.ts +++ b/x-pack/test/rule_registry/security_and_spaces/tests/trial/update_alert.ts @@ -46,9 +46,11 @@ export default ({ getService }: FtrProviderContext) => { beforeEach(async () => { await esArchiver.load('x-pack/test/functional/es_archives/rule_registry/alerts'); }); + afterEach(async () => { await esArchiver.unload('x-pack/test/functional/es_archives/rule_registry/alerts'); }); + it(`${superUser.username} should be able to update the APM alert in ${SPACE1}`, async () => { const apmIndex = await getAPMIndexName(superUser); await supertestWithoutAuth diff --git a/x-pack/test/rule_registry/spaces_only/tests/trial/update_alert.ts b/x-pack/test/rule_registry/spaces_only/tests/trial/update_alert.ts index 31c3cfdecb9ee..2fe7ff9dac0c4 100644 --- a/x-pack/test/rule_registry/spaces_only/tests/trial/update_alert.ts +++ b/x-pack/test/rule_registry/spaces_only/tests/trial/update_alert.ts @@ -90,7 +90,6 @@ export default ({ getService }: FtrProviderContext) => { }); it(`${superUser.username} should be able to update alert ${APM_ALERT_ID} in ${SPACE2}/${APM_ALERT_INDEX}`, async () => { - await esArchiver.load('x-pack/test/functional/es_archives/rule_registry/alerts'); // since this is a success case, reload the test data immediately beforehand await supertestWithoutAuth .post(`${getSpaceUrlPrefix(SPACE2)}${TEST_URL}`) .set('kbn-xsrf', 'true') diff --git a/x-pack/test/search_sessions_integration/tests/apps/discover/async_search.ts b/x-pack/test/search_sessions_integration/tests/apps/discover/async_search.ts index d4c87209c64c7..eadd2b544953f 100644 --- a/x-pack/test/search_sessions_integration/tests/apps/discover/async_search.ts +++ b/x-pack/test/search_sessions_integration/tests/apps/discover/async_search.ts @@ -28,6 +28,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { const retry = getService('retry'); const kibanaServer = getService('kibanaServer'); const toasts = getService('toasts'); + const dataGrid = getService('dataGrid'); // FLAKY: https://github.com/elastic/kibana/issues/195955 describe.skip('discover async search', () => { @@ -95,16 +96,14 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { }); it('navigation to context cleans the session', async () => { - const table = await discover.getDocTable(); - const isLegacy = await discover.useLegacyTable(); - await table.clickRowToggle({ rowIndex: 0 }); + await dataGrid.clickRowToggle({ rowIndex: 0 }); await retry.try(async () => { - const rowActions = await table.getRowActions({ rowIndex: 0 }); + const rowActions = await dataGrid.getRowActions({ rowIndex: 0 }); if (!rowActions.length) { throw new Error('row actions empty, trying again'); } - const idxToClick = isLegacy ? 0 : 1; + const idxToClick = 1; await rowActions[idxToClick].click(); }); diff --git a/x-pack/test/security_api_integration/plugins/features_provider/server/index.ts b/x-pack/test/security_api_integration/plugins/features_provider/server/index.ts index 61100babefea7..9b7158aca7b32 100644 --- a/x-pack/test/security_api_integration/plugins/features_provider/server/index.ts +++ b/x-pack/test/security_api_integration/plugins/features_provider/server/index.ts @@ -5,7 +5,7 @@ * 2.0. */ -import type { PluginSetupContract as AlertingPluginsSetup } from '@kbn/alerting-plugin/server/plugin'; +import type { AlertingServerSetup } from '@kbn/alerting-plugin/server/plugin'; import { schema } from '@kbn/config-schema'; import type { CoreSetup, Plugin, PluginInitializer } from '@kbn/core/server'; import { DEFAULT_APP_CATEGORIES } from '@kbn/core/server'; @@ -16,7 +16,7 @@ import { initRoutes } from './init_routes'; export interface PluginSetupDependencies { features: FeaturesPluginSetup; - alerting: AlertingPluginsSetup; + alerting: AlertingServerSetup; } export interface PluginStartDependencies { @@ -110,7 +110,10 @@ function case2FeatureSplit(deps: PluginSetupDependencies) { category: DEFAULT_APP_CATEGORIES.kibana, id: 'case_2_feature_a', name: 'Case #2 feature A (DEPRECATED)', - alerting: ['alerting_rule_type_one', 'alerting_rule_type_two'], + alerting: [ + { ruleTypeId: 'alerting_rule_type_one', consumers: ['case_2_feature_a'] }, + { ruleTypeId: 'alerting_rule_type_two', consumers: ['case_2_feature_a'] }, + ], cases: ['cases_owner_one', 'cases_owner_two'], privileges: { all: { @@ -122,12 +125,18 @@ function case2FeatureSplit(deps: PluginSetupDependencies) { management: { kibana: ['management_one', 'management_two'] }, alerting: { rule: { - all: ['alerting_rule_type_one', 'alerting_rule_type_two'], - read: ['alerting_rule_type_one', 'alerting_rule_type_two'], + all: [ + { ruleTypeId: 'alerting_rule_type_one', consumers: ['case_2_feature_a'] }, + { ruleTypeId: 'alerting_rule_type_two', consumers: ['case_2_feature_a'] }, + ], + read: [ + { ruleTypeId: 'alerting_rule_type_one', consumers: ['case_2_feature_a'] }, + { ruleTypeId: 'alerting_rule_type_two', consumers: ['case_2_feature_a'] }, + ], }, alert: { - all: ['alerting_rule_type_one', 'alerting_rule_type_two'], - read: ['alerting_rule_type_one', 'alerting_rule_type_two'], + all: [{ ruleTypeId: 'alerting_rule_type_one', consumers: ['case_2_feature_a'] }], + read: [{ ruleTypeId: 'alerting_rule_type_two', consumers: ['case_2_feature_a'] }], }, }, cases: { @@ -167,7 +176,12 @@ function case2FeatureSplit(deps: PluginSetupDependencies) { app: ['app_one'], catalogue: ['cat_one'], management: { kibana: ['management_one'] }, - alerting: ['alerting_rule_type_one'], + // In addition to registering the `case_2_feature_b` consumer, we also need to register + // `case_2_feature_a` as an additional consumer to ensure that users with either deprecated or + // replacement privileges can access the rules, regardless of which one created them. + alerting: [ + { ruleTypeId: 'alerting_rule_type_one', consumers: ['case_2_feature_a', 'case_2_feature_b'] }, + ], cases: ['cases_owner_one'], privileges: { all: { @@ -178,8 +192,34 @@ function case2FeatureSplit(deps: PluginSetupDependencies) { catalogue: ['cat_one'], management: { kibana: ['management_one'] }, alerting: { - rule: { all: ['alerting_rule_type_one'], read: ['alerting_rule_type_one'] }, - alert: { all: ['alerting_rule_type_one'], read: ['alerting_rule_type_one'] }, + rule: { + all: [ + { + ruleTypeId: 'alerting_rule_type_one', + consumers: ['case_2_feature_a', 'case_2_feature_b'], + }, + ], + read: [ + { + ruleTypeId: 'alerting_rule_type_one', + consumers: ['case_2_feature_a', 'case_2_feature_b'], + }, + ], + }, + alert: { + all: [ + { + ruleTypeId: 'alerting_rule_type_one', + consumers: ['case_2_feature_a', 'case_2_feature_b'], + }, + ], + read: [ + { + ruleTypeId: 'alerting_rule_type_one', + consumers: ['case_2_feature_a', 'case_2_feature_b'], + }, + ], + }, }, cases: { all: ['cases_owner_one'], @@ -208,7 +248,12 @@ function case2FeatureSplit(deps: PluginSetupDependencies) { app: ['app_two'], catalogue: ['cat_two'], management: { kibana: ['management_two'] }, - alerting: ['alerting_rule_type_two'], + // In addition to registering the `case_2_feature_c` consumer, we also need to register + // `case_2_feature_a` as an additional consumer to ensure that users with either deprecated or + // replacement privileges can access the rules, regardless of which one created them. + alerting: [ + { ruleTypeId: 'alerting_rule_type_two', consumers: ['case_2_feature_a', 'case_2_feature_c'] }, + ], cases: ['cases_owner_two'], privileges: { all: { @@ -219,8 +264,34 @@ function case2FeatureSplit(deps: PluginSetupDependencies) { catalogue: ['cat_two'], management: { kibana: ['management_two'] }, alerting: { - rule: { all: ['alerting_rule_type_two'], read: ['alerting_rule_type_two'] }, - alert: { all: ['alerting_rule_type_two'], read: ['alerting_rule_type_two'] }, + rule: { + all: [ + { + ruleTypeId: 'alerting_rule_type_two', + consumers: ['case_2_feature_a', 'case_2_feature_c'], + }, + ], + read: [ + { + ruleTypeId: 'alerting_rule_type_two', + consumers: ['case_2_feature_a', 'case_2_feature_c'], + }, + ], + }, + alert: { + all: [ + { + ruleTypeId: 'alerting_rule_type_two', + consumers: ['case_2_feature_a', 'case_2_feature_c'], + }, + ], + read: [ + { + ruleTypeId: 'alerting_rule_type_two', + consumers: ['case_2_feature_a', 'case_2_feature_c'], + }, + ], + }, }, cases: { all: ['cases_owner_two'], diff --git a/x-pack/test/security_api_integration/tests/features/deprecated_features.ts b/x-pack/test/security_api_integration/tests/features/deprecated_features.ts index 29135ff2440b2..7887cd6a23dc0 100644 --- a/x-pack/test/security_api_integration/tests/features/deprecated_features.ts +++ b/x-pack/test/security_api_integration/tests/features/deprecated_features.ts @@ -492,56 +492,88 @@ export default function ({ getService }: FtrProviderContext) { const ruleOneTransformed = await createRule( transformedUser, 'case_2_a_transform_one', - 'case_2_feature_b', + 'case_2_feature_a', 'alerting_rule_type_one' ); const ruleTwoTransformed = await createRule( transformedUser, 'case_2_a_transform_two', + 'case_2_feature_a', + 'alerting_rule_type_two' + ); + + // Create rules as user with new privileges (B). + const newUserB = getUserCredentials('case_2_b_new'); + const ruleOneNewBConsumerA = await createRule( + newUserB, + 'case_2_b_new_one', + 'case_2_feature_a', + 'alerting_rule_type_one' + ); + const ruleOneNewBConsumerB = await createRule( + newUserB, + 'case_2_b_new_one', + 'case_2_feature_b', + 'alerting_rule_type_one' + ); + + // Create cases as user with new privileges (C). + const newUserC = getUserCredentials('case_2_c_new'); + const ruleTwoNewCConsumerA = await createRule( + newUserC, + 'case_2_c_new_two', + 'case_2_feature_a', + 'alerting_rule_type_two' + ); + const ruleTwoNewCConsumerC = await createRule( + newUserC, + 'case_2_c_new_two', 'case_2_feature_c', 'alerting_rule_type_two' ); // Users with deprecated privileges should be able to access rules created by themselves and - // users with new privileges. + // users with new privileges assuming the consumer is the same. for (const ruleToCheck of [ ruleOneDeprecated, ruleTwoDeprecated, ruleOneTransformed, ruleTwoTransformed, + ruleOneNewBConsumerA, + ruleTwoNewCConsumerA, ]) { expect(await getRule(deprecatedUser, ruleToCheck.id)).toBeDefined(); + expect(await getRule(transformedUser, ruleToCheck.id)).toBeDefined(); } - // NOTE: Scenarios below require SO migrations for both alerting rules and alerts to switch to - // a new producer that is tied to feature ID. Presumably we won't have this requirement once - // https://github.com/elastic/kibana/pull/183756 is resolved. - - // Create rules as user with new privileges (B). - // const newUserB = getUserCredentials('case_2_b_new'); - // const caseOneNewB = await createRule(newUserB, { - // title: 'case_2_b_new_one', - // owner: 'cases_owner_one', - // }); - // - // // Create cases as user with new privileges (C). - // const newUserC = getUserCredentials('case_2_c_new'); - // const caseTwoNewC = await createRule(newUserC, { - // title: 'case_2_c_new_two', - // owner: 'cases_owner_two', - // }); - // + // Any new consumer that is not known to the deprecated feature shouldn't be available to the + // users with the deprecated privileges unless deprecated features are update to explicitly + // support new consumers. + for (const ruleToCheck of [ruleOneNewBConsumerB, ruleTwoNewCConsumerC]) { + expect(await getRule(deprecatedUser, ruleToCheck.id)).toBeUndefined(); + expect(await getRule(transformedUser, ruleToCheck.id)).toBeDefined(); + } - // User B and User C should be able to access cases created by themselves and users with - // deprecated and transformed privileges, but only for the specific owner. - // for (const caseToCheck of [ruleOneDeprecated, ruleOneTransformed, caseOneNewB]) { - // expect(await getRule(newUserB, caseToCheck.id)).toBeDefined(); - // expect(await getRule(newUserC, caseToCheck.id)).toBeUndefined(); - // } - // for (const caseToCheck of [ruleTwoDeprecated, ruleTwoTransformed, caseTwoNewC]) { - // expect(await getRule(newUserC, caseToCheck.id)).toBeDefined(); - // expect(await getRule(newUserB, caseToCheck.id)).toBeUndefined(); - // } + // User B and User C should be able to access rule types created by themselves and users with + // deprecated and transformed privileges, but only for the specific consumer. + for (const ruleToCheck of [ + ruleOneDeprecated, + ruleOneTransformed, + ruleOneNewBConsumerA, + ruleOneNewBConsumerB, + ]) { + expect(await getRule(newUserB, ruleToCheck.id)).toBeDefined(); + expect(await getRule(newUserC, ruleToCheck.id)).toBeUndefined(); + } + for (const ruleToCheck of [ + ruleTwoDeprecated, + ruleTwoTransformed, + ruleTwoNewCConsumerA, + ruleTwoNewCConsumerC, + ]) { + expect(await getRule(newUserC, ruleToCheck.id)).toBeDefined(); + expect(await getRule(newUserB, ruleToCheck.id)).toBeUndefined(); + } }); }); } diff --git a/x-pack/test/security_solution_api_integration/README.md b/x-pack/test/security_solution_api_integration/README.md index 8f5aafdf15f94..e2ffcb8ac79dc 100644 --- a/x-pack/test/security_solution_api_integration/README.md +++ b/x-pack/test/security_solution_api_integration/README.md @@ -3,42 +3,39 @@ This directory serves as a centralized location to place the security solution tests that run in Serverless and ESS environments. ## Subdirectories - -1. `config` stores base configurations specific to both the Serverless and ESS environments, These configurations build upon the base configuration provided by `xpack/test_serverless` and `x-pack-api_integrations`, incorporating additional settings such as environment variables and tagging options. - - -2. `test_suites` directory now houses all the tests along with their utility functions. As an initial step, -we have introduced the `detection_response` directory to consolidate all the integration tests related to detection and response APIs. - +- `config` stores base configurations specific to both the Serverless and ESS environments, These configurations build upon the base configuration provided by `xpack/test_serverless` and `x-pack-api_integrations`, incorporating additional settings such as environment variables and tagging options. +- `es_archive` and `es_archive_path_builder` directories contain the data that can be used by the tests +- `scripts` directory contains various scripts used to run the tests +- `test_suites` directory houses all the tests along with their utility functions. As an initial step, we have introduced the `detection_response` directory to consolidate all the integration tests related to detection and response APIs. ## Overview -- In this directory, Mocha tagging is utilized to assign tags to specific test suites and individual test cases. This tagging system enables the ability to selectively apply tags to test suites and test cases, facilitating the exclusion of specific test cases within a test suite as needed. - -- Test suites and cases are prefixed with specific tags to determine their execution in particular environments or to exclude them from specific environments. - -- We are using the following tags: - * `@ess`: Runs in an ESS environment (on-prem installation) as part of the CI validation on PRs. - - * `@serverless`: Runs in the first quality gate and in the periodic pipeline. +Test suites and cases are prefixed with specific tags to determine their execution in particular environments or to exclude them from specific environments: +* `@ess`: Runs in an ESS environment (on-prem installation) as part of the CI validation on PRs. - * `@serverlessQA`: Runs in the Kibana QA quality gate. +* `@serverless`: Runs in an simulated serverless environment as part of the CI validation on PRs and in the periodic pipeline. - * `@skipInEss`: Skipped for ESS environment. +* `@serverlessQA`: Runs in the Kibana QA quality gate. - * `@skipInServerless`: Skipped for all quality gates, CI and periodic pipeline. +* `@skipInEss`: Skipped for ESS environment. +* `@skipInServerless`: Skipped for all quality gates and periodic pipeline. +* `@skipInServerlessMKI`: Skipped from being executed in any MKI environment (periodic pipeline and Kibana QA quality gate), but executed as part of the first quality gate if the `@serverless` tag is present. - * `@skipInServerlessMKI`: Skipped for all the MKI environments. +For example: +```typescript +// tests in this suite will run in both Ess and Serverless on every PRs as well as on the first quality gate and the periodic pipeline +describe('@serverless @ess create_rules', () => { + describe('creating rules', () => { + it('my first test', async () => { ... }); + it('my second test', async () => { ... }); + }); -ex: -``` - describe('@serverless @ess create_rules', () => { ==> tests in this suite will run in both Ess and Serverless - describe('creating rules', () => {}); - - // This test is skipped due to flakiness in serverless environments: https://github.com/elastic/kibana/issues/497777 - describe('@skipInServerless missing timestamps', () => {}); ==> tests in this suite will be excluded in Serverless - - ``` + // tests in this suite will be excluded in Serverless on every PRs as well as on the first quality gate and the periodic pipeline + describe('@skipInServerless missing timestamps', () => { + it('another test', async () => { ... }); + }); +}); +``` # Adding new security area's tests @@ -53,7 +50,8 @@ The default project type configuration in Serverless is complete. If for the nee There are already configurations in the `./scripts/api_configs.json` which you can follow in order to add yours when it is needed. The currently supported configuration, allows **ONLY** the PLIs to be configured. Thus, experimental feature flags **are not yet supported** and the test should be skipped until further notice. -**NOTE**: If a target script living in `package.json` file, does not require any further configuration, then the entry in `./scripts/api_configs.json` file, **can be omitted!** +> **Note:** +>If a target script living in `package.json` file, does not require any further configuration, then the entry in `./scripts/api_configs.json` file, **can be omitted!** # Testing locally @@ -80,41 +78,39 @@ In this project, you can run various commands to execute tests and workflows, ea - Description: Runs the tests for the Detections Response area with the default license. - - 2. Executes particular sets of test suites linked to the designated environment and license: - - The command structure follows this pattern: - - - ``: The test folder or workflow you want to run. - - ``: The type of project to pick the relevant configurations, either "serverless" or "ess." - - "serverless" and "ess" help determine the configuration specific to the chosen test. - - ``: The testing environment, such as "serverlessEnv," "essEnv," or "qaEnv." - - When using "serverlessEnv,.." in the script, it appends the correct grep command for filtering tests in the serverless testing environment. - - "serverlessEnv,..." is used to customize the test execution based on the serverless environment. - - - Here are some command examples for "exceptions" which defined under the "detection_engine" area using the default license: - - 1. **Run the server for "exception_workflows" in the "serverlessEnv" environment:** - ```shell - npm run initialize-server:dr:default exceptions/workflows serverless - ``` - 2. **To run tests for the "exception_workflows" using the serverless runner in the "serverlessEnv" environment, you can use the following command:** - ```shell - npm run run-tests:dr:default exceptions/workflows serverless serverlessEnv - ``` - 3. **Run tests for "exception_workflows" using the serverless runner in the "qaEnv" environment:** - ```shell - npm run run-tests:dr:default exceptions/workflows serverless qaPeriodicEnv - ``` - 4. **Run the server for "exception_workflows" in the "essEnv" environment:** - ```shell - npm run initialize-server:dr:default exceptions/workflows ess - ``` - 5. **Run tests for "exception_workflows" using the ess runner in the "essEnv" environment:** - ```shell - npm run run-tests:dr:default exceptions/workflows ess essEnv - ``` +2. Executes particular sets of test suites linked to the designated environment and license: + + The command structure follows this pattern: + + - ``: The test folder or workflow you want to run. + - ``: The type of project to pick the relevant configurations, either "serverless" or "ess." + - "serverless" and "ess" help determine the configuration specific to the chosen test. + - ``: The testing environment, such as "serverlessEnv," "essEnv," or "qaEnv." + - When using "serverlessEnv,.." in the script, it appends the correct grep command for filtering tests in the serverless testing environment. + - "serverlessEnv,..." is used to customize the test execution based on the serverless environment. + + Here are some command examples for "exceptions" which defined under the "detection_engine" area using the default license: + +- Run the server for "exception_workflows" in the "serverlessEnv" environment: + ```shell + npm run initialize-server:dr:default exceptions/workflows serverless + ``` +- To run tests for the "exception_workflows" using the serverless runner in the "serverlessEnv" environment, you can use the following command: + ```shell + npm run run-tests:dr:default exceptions/workflows serverless serverlessEnv + ``` +- Run tests for "exception_workflows" using the serverless runner in the "qaEnv" environment: + ```shell + npm run run-tests:dr:default exceptions/workflows serverless qaPeriodicEnv + ``` +- Run the server for "exception_workflows" in the "essEnv" environment: + ```shell + npm run initialize-server:dr:default exceptions/workflows ess + ``` +- Run tests for "exception_workflows" using the ess runner in the "essEnv" environment: + ```shell + npm run run-tests:dr:default exceptions/workflows ess essEnv + ``` ## Testing with serverless roles @@ -126,28 +122,29 @@ All API calls using the returned instance will inject the required auth headers. **On ESS, `createSuperTest` returns a basic `supertest` instance without headers.* -```js +```typescript import TestAgent from 'supertest/lib/agent'; export default ({ getService }: FtrProviderContext) => { - const utils = getService('securitySolutionUtils'); + const utils = getService('securitySolutionUtils'); - describe('@ess @serverless my_test', () => { - let supertest: TestAgent; + describe('@ess @serverless my_test', () => { + let supertest: TestAgent; - before(async () => { - supertest = await utils.createSuperTest('admin'); - }); - ... + before(async () => { + supertest = await utils.createSuperTest('admin'); + }); + ... + }); +}); ``` If you need to use multiple roles in a single test, you can instantiate multiple `supertest` versions. -```js +```typescript before(async () => { adminSupertest = await utils.createSuperTest('admin'); viewerSupertest = await utils.createSuperTest('viewer'); }); -... ``` -The helper keeps track of only one active session per role. So, if you instantiate `supertest` twice for the same role, the first instance will have an invalid API key. +The helper keeps track of only one active session per role. So, if you instantiate `supertest` twice for the same role, the first instance will have an invalid API key. \ No newline at end of file diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_disabled/configs/ess.config.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_disabled/configs/ess.config.ts new file mode 100644 index 0000000000000..2e1b278c9247f --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_disabled/configs/ess.config.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 { FtrConfigProviderContext } from '@kbn/test'; + +export default async function ({ readConfigFile }: FtrConfigProviderContext) { + const functionalConfig = await readConfigFile( + require.resolve('../../../../../../../config/ess/config.base.trial') + ); + + const testConfig = { + ...functionalConfig.getAll(), + testFiles: [require.resolve('..')], + junit: { + reportName: + 'Rules Management - Prebuilt Rule Customization Disabled Integration Tests - ESS Env', + }, + }; + + return testConfig; +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_disabled/configs/serverless.config.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_disabled/configs/serverless.config.ts new file mode 100644 index 0000000000000..462a971d8dda7 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_disabled/configs/serverless.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 { createTestConfig } from '../../../../../../../config/serverless/config.base'; + +export default createTestConfig({ + testFiles: [require.resolve('..')], + junit: { + reportName: + 'Rules Management - Prebuilt Rule Customization Disabled Integration Tests - Serverless Env', + }, + kbnTestServerArgs: [], +}); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_disabled/index.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_disabled/index.ts new file mode 100644 index 0000000000000..0d78605426dbf --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_disabled/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. + */ + +import { FtrProviderContext } from '../../../../../../ftr_provider_context'; + +export default ({ loadTestFile }: FtrProviderContext): void => { + describe('Rules Management - Prebuilt Rules - Prebuilt Rule Customization Disabled', function () { + loadTestFile(require.resolve('./is_customized_calculation')); + }); +}; diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_disabled/is_customized_calculation.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_disabled/is_customized_calculation.ts new file mode 100644 index 0000000000000..e4ae135b481ed --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_disabled/is_customized_calculation.ts @@ -0,0 +1,218 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor 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 { + BulkActionEditTypeEnum, + BulkActionTypeEnum, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { deleteAllRules } from '../../../../../../../common/utils/security_solution'; +import { FtrProviderContext } from '../../../../../../ftr_provider_context'; +import { + deleteAllPrebuiltRuleAssets, + createRuleAssetSavedObject, + createPrebuiltRuleAssetSavedObjects, + installPrebuiltRules, +} from '../../../../utils'; + +export default ({ getService }: FtrProviderContext) => { + const supertest = getService('supertest'); + const securitySolutionApi = getService('securitySolutionApi'); + const log = getService('log'); + const es = getService('es'); + + const ruleAsset = createRuleAssetSavedObject({ + rule_id: 'test-rule-id', + }); + + describe('@ess @serverless @skipInServerlessMKI is_customized calculation with disabled customization', () => { + beforeEach(async () => { + await deleteAllRules(supertest, log); + await deleteAllPrebuiltRuleAssets(es, log); + }); + + it('should set is_customized to "false" on prebuilt rule PATCH', async () => { + await createPrebuiltRuleAssetSavedObjects(es, [ruleAsset]); + await installPrebuiltRules(es, supertest); + + const { body: findResult } = await securitySolutionApi + .findRules({ + query: { + per_page: 1, + filter: `alert.attributes.params.immutable: true`, + }, + }) + .expect(200); + const prebuiltRule = findResult.data[0]; + + // Check that the rule has been created and is not customized + expect(prebuiltRule).not.toBeNull(); + expect(prebuiltRule.rule_source.is_customized).toEqual(false); + + const { body } = await securitySolutionApi + .patchRule({ + body: { + rule_id: 'test-rule-id', + name: 'some other rule name', + }, + }) + .expect(200); + + // Check that the rule name has been updated and the rule is still not customized + expect(body).toEqual( + expect.objectContaining({ + name: 'some other rule name', + }) + ); + expect(body.rule_source.is_customized).toEqual(false); + }); + + it('should set is_customized to "false" on prebuilt rule UPDATE', async () => { + await createPrebuiltRuleAssetSavedObjects(es, [ruleAsset]); + await installPrebuiltRules(es, supertest); + + const { body: findResult } = await securitySolutionApi + .findRules({ + query: { + per_page: 1, + filter: `alert.attributes.params.immutable: true`, + }, + }) + .expect(200); + const prebuiltRule = findResult.data[0]; + + // Check that the rule has been created and is not customized + expect(prebuiltRule).not.toBeNull(); + expect(prebuiltRule.rule_source.is_customized).toEqual(false); + + const { body } = await securitySolutionApi + .updateRule({ + body: { + ...prebuiltRule, + id: undefined, // id together with rule_id is not allowed + name: 'some other rule name', + }, + }) + .expect(200); + + // Check that the rule name has been updated and the rule is still not customized + expect(body).toEqual( + expect.objectContaining({ + name: 'some other rule name', + }) + ); + expect(body.rule_source.is_customized).toEqual(false); + }); + + it('should not allow prebuilt rule customization on import', async () => { + await createPrebuiltRuleAssetSavedObjects(es, [ruleAsset]); + await installPrebuiltRules(es, supertest); + + const { body: findResult } = await securitySolutionApi + .findRules({ + query: { + per_page: 1, + filter: `alert.attributes.params.immutable: true`, + }, + }) + .expect(200); + const prebuiltRule = findResult.data[0]; + + // Check that the rule has been created and is not customized + expect(prebuiltRule).not.toBeNull(); + expect(prebuiltRule.rule_source.is_customized).toEqual(false); + + const ruleBuffer = Buffer.from( + JSON.stringify({ + ...prebuiltRule, + name: 'some other rule name', + }) + ); + + const { body } = await securitySolutionApi + .importRules({ query: {} }) + .attach('file', ruleBuffer, 'rules.ndjson') + .expect('Content-Type', 'application/json; charset=utf-8') + .expect(200); + + expect(body).toMatchObject({ + rules_count: 1, + success: false, + success_count: 0, + errors: [ + { + error: { + message: expect.stringContaining('Importing prebuilt rules is not supported'), + }, + rule_id: 'test-rule-id', + }, + ], + }); + + // Check that the rule has not been customized + const { body: importedRule } = await securitySolutionApi.readRule({ + query: { rule_id: prebuiltRule.rule_id }, + }); + expect(importedRule.rule_source.is_customized).toEqual(false); + }); + + it('should not allow rule customization on bulk edit', async () => { + await createPrebuiltRuleAssetSavedObjects(es, [ruleAsset]); + await installPrebuiltRules(es, supertest); + + const { body: findResult } = await securitySolutionApi + .findRules({ + query: { + per_page: 1, + filter: `alert.attributes.params.immutable: true`, + }, + }) + .expect(200); + const prebuiltRule = findResult.data[0]; + + // Check that the rule has been created and is not customized + expect(prebuiltRule).not.toBeNull(); + expect(prebuiltRule.rule_source.is_customized).toEqual(false); + + const { body: bulkResult } = await securitySolutionApi + .performRulesBulkAction({ + query: {}, + body: { + ids: [prebuiltRule.id], + action: BulkActionTypeEnum.edit, + [BulkActionTypeEnum.edit]: [ + { + type: BulkActionEditTypeEnum.add_tags, + value: ['test'], + }, + ], + }, + }) + .expect(500); + + expect(bulkResult).toMatchObject( + expect.objectContaining({ + attributes: expect.objectContaining({ + summary: { + failed: 1, + skipped: 0, + succeeded: 0, + total: 1, + }, + errors: [expect.objectContaining({ message: "Elastic rule can't be edited" })], + }), + }) + ); + + // Check that the rule has not been customized + const { body: ruleAfterUpdate } = await securitySolutionApi.readRule({ + query: { rule_id: prebuiltRule.rule_id }, + }); + expect(ruleAfterUpdate.rule_source.is_customized).toEqual(false); + }); + }); +}; diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/trial_license_complete_tier/configs/ess.config.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/configs/ess.config.ts similarity index 91% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/trial_license_complete_tier/configs/ess.config.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/configs/ess.config.ts index eee14323c9b98..ff46ebb70d7c8 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/trial_license_complete_tier/configs/ess.config.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/configs/ess.config.ts @@ -17,7 +17,7 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) { testFiles: [require.resolve('..')], junit: { reportName: - 'Rules Management - Prebuilt Rule Customization Integration Tests - ESS Env - Trial License', + 'Rules Management - Prebuilt Rule Customization Enabled Integration Tests - ESS Env', }, }; testConfig.kbnTestServer.serverArgs = testConfig.kbnTestServer.serverArgs.map((arg: string) => { diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/trial_license_complete_tier/configs/serverless.config.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/configs/serverless.config.ts similarity index 84% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/trial_license_complete_tier/configs/serverless.config.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/configs/serverless.config.ts index 79a23c85d2279..8c1d777665667 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/trial_license_complete_tier/configs/serverless.config.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/configs/serverless.config.ts @@ -11,7 +11,7 @@ export default createTestConfig({ testFiles: [require.resolve('..')], junit: { reportName: - 'Rules Management - Prebuilt Rule Customization Integration Tests - Serverless Env - Complete Tier', + 'Rules Management - Prebuilt Rule Customization Enabled Integration Tests - Serverless Env', }, kbnTestServerArgs: [ `--xpack.securitySolution.enableExperimental=${JSON.stringify([ diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/trial_license_complete_tier/import_rules.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/import_rules.ts similarity index 100% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/trial_license_complete_tier/import_rules.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/import_rules.ts diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/trial_license_complete_tier/index.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/index.ts similarity index 94% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/trial_license_complete_tier/index.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/index.ts index 58904243e51ca..d89f8ed5d49d3 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/trial_license_complete_tier/index.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/index.ts @@ -8,7 +8,7 @@ import { FtrProviderContext } from '../../../../../../ftr_provider_context'; export default ({ loadTestFile }: FtrProviderContext): void => { - describe('Rules Management - Prebuilt Rules - Prebuilt Rule Customization', function () { + describe('Rules Management - Prebuilt Rules - Prebuilt Rule Customization Enabled', function () { loadTestFile(require.resolve('./is_customized_calculation')); loadTestFile(require.resolve('./import_rules')); loadTestFile(require.resolve('./rules_export')); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/trial_license_complete_tier/is_customized_calculation.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/is_customized_calculation.ts similarity index 100% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/trial_license_complete_tier/is_customized_calculation.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/is_customized_calculation.ts diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/trial_license_complete_tier/rules_export.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/rules_export.ts similarity index 100% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/trial_license_complete_tier/rules_export.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/rules_export.ts diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/rule_patch/basic_license_essentials_tier/patch_rules.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/rule_patch/basic_license_essentials_tier/patch_rules.ts index 86dde0735424e..a47f84ef930ad 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/rule_patch/basic_license_essentials_tier/patch_rules.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/rule_patch/basic_license_essentials_tier/patch_rules.ts @@ -7,25 +7,21 @@ import expect from 'expect'; +import { createRule, deleteAllRules } from '../../../../../../common/utils/security_solution'; import { FtrProviderContext } from '../../../../../ftr_provider_context'; import { + createHistoricalPrebuiltRuleAssetSavedObjects, + createRuleAssetSavedObject, + deleteAllPrebuiltRuleAssets, + getCustomQueryRuleParams, getSimpleRule, getSimpleRuleOutput, - getCustomQueryRuleParams, + getSimpleRuleOutputWithoutRuleId, + installPrebuiltRules, removeServerGeneratedProperties, removeServerGeneratedPropertiesIncludingRuleId, - getSimpleRuleOutputWithoutRuleId, updateUsername, - createHistoricalPrebuiltRuleAssetSavedObjects, - installPrebuiltRules, - createRuleAssetSavedObject, } from '../../../utils'; -import { - createAlertsIndex, - deleteAllRules, - createRule, - deleteAllAlerts, -} from '../../../../../../common/utils/security_solution'; export default ({ getService }: FtrProviderContext) => { const supertest = getService('supertest'); @@ -37,12 +33,8 @@ export default ({ getService }: FtrProviderContext) => { describe('@ess @serverless @serverlessQA patch_rules', () => { describe('patch rules', () => { beforeEach(async () => { - await createAlertsIndex(supertest, log); - }); - - afterEach(async () => { - await deleteAllAlerts(supertest, log, es); await deleteAllRules(supertest, log); + await deleteAllPrebuiltRuleAssets(es, log); }); it('should patch a single rule property of name using a rule_id', async () => { @@ -262,10 +254,6 @@ export default ({ getService }: FtrProviderContext) => { }); describe('max signals', () => { - afterEach(async () => { - await deleteAllRules(supertest, log); - }); - it('does NOT patch a rule when max_signals is less than 1', async () => { await securitySolutionApi.createRule({ body: getCustomQueryRuleParams({ rule_id: 'rule-1', max_signals: 100 }), diff --git a/x-pack/test/security_solution_api_integration/test_suites/entity_analytics/entity_store/trial_license_complete_tier/entity_store.ts b/x-pack/test/security_solution_api_integration/test_suites/entity_analytics/entity_store/trial_license_complete_tier/entity_store.ts index 5d0dcec11d9b6..104fbf05b5159 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/entity_analytics/entity_store/trial_license_complete_tier/entity_store.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/entity_analytics/entity_store/trial_license_complete_tier/entity_store.ts @@ -5,7 +5,7 @@ * 2.0. */ -import expect from '@kbn/expect'; +import expect from 'expect'; import { FtrProviderContext } from '../../../../ftr_provider_context'; import { EntityStoreUtils } from '../../utils'; import { dataViewRouteHelpersFactory } from '../../utils/data_view'; @@ -14,8 +14,7 @@ export default ({ getService }: FtrProviderContext) => { const supertest = getService('supertest'); const utils = EntityStoreUtils(getService); - // Failing: See https://github.com/elastic/kibana/issues/200758 - describe.skip('@ess @skipInServerlessMKI Entity Store APIs', () => { + describe('@ess @skipInServerlessMKI Entity Store APIs', () => { const dataView = dataViewRouteHelpersFactory(supertest); before(async () => { @@ -85,7 +84,7 @@ export default ({ getService }: FtrProviderContext) => { }) .expect(200); - expect(getResponse.body).to.eql({ + expect(getResponse.body).toEqual({ status: 'started', type: 'host', indexPattern: '', @@ -101,7 +100,7 @@ export default ({ getService }: FtrProviderContext) => { }) .expect(200); - expect(getResponse.body).to.eql({ + expect(getResponse.body).toEqual({ status: 'started', type: 'user', indexPattern: '', @@ -118,7 +117,7 @@ export default ({ getService }: FtrProviderContext) => { // @ts-expect-error body is any const sortedEngines = body.engines.sort((a, b) => a.type.localeCompare(b.type)); - expect(sortedEngines).to.eql([ + expect(sortedEngines).toEqual([ { status: 'started', type: 'host', @@ -160,7 +159,7 @@ export default ({ getService }: FtrProviderContext) => { }) .expect(200); - expect(body.status).to.eql('stopped'); + expect(body.status).toEqual('stopped'); }); it('should start the entity engine', async () => { @@ -176,7 +175,7 @@ export default ({ getService }: FtrProviderContext) => { }) .expect(200); - expect(body.status).to.eql('started'); + expect(body.status).toEqual('started'); }); }); @@ -213,10 +212,11 @@ export default ({ getService }: FtrProviderContext) => { afterEach(async () => { await utils.cleanEngines(); }); + it('should return "not_installed" when no engines have been initialized', async () => { - const { body } = await api.getEntityStoreStatus().expect(200); + const { body } = await api.getEntityStoreStatus({ query: {} }).expect(200); - expect(body).to.eql({ + expect(body).toEqual({ engines: [], status: 'not_installed', }); @@ -225,23 +225,56 @@ export default ({ getService }: FtrProviderContext) => { it('should return "installing" when at least one engine is being initialized', async () => { await utils.enableEntityStore(); - const { body } = await api.getEntityStoreStatus().expect(200); + const { body } = await api.getEntityStoreStatus({ query: {} }).expect(200); - expect(body.status).to.eql('installing'); - expect(body.engines.length).to.eql(2); - expect(body.engines[0].status).to.eql('installing'); - expect(body.engines[1].status).to.eql('installing'); + expect(body.status).toEqual('installing'); + expect(body.engines.length).toEqual(2); + expect(body.engines[0].status).toEqual('installing'); + expect(body.engines[1].status).toEqual('installing'); }); it('should return "started" when all engines are started', async () => { await utils.initEntityEngineForEntityTypesAndWait(['host', 'user']); - const { body } = await api.getEntityStoreStatus().expect(200); + const { body } = await api.getEntityStoreStatus({ query: {} }).expect(200); + + expect(body.status).toEqual('running'); + expect(body.engines.length).toEqual(2); + expect(body.engines[0].status).toEqual('started'); + expect(body.engines[1].status).toEqual('started'); + }); - expect(body.status).to.eql('running'); - expect(body.engines.length).to.eql(2); - expect(body.engines[0].status).to.eql('started'); - expect(body.engines[1].status).to.eql('started'); + describe('status with components', () => { + it('should return empty list when when no engines have been initialized', async () => { + const { body } = await api + .getEntityStoreStatus({ query: { include_components: true } }) + .expect(200); + + expect(body).toEqual({ + engines: [], + status: 'not_installed', + }); + }); + + it('should return components status when engines are installed', async () => { + await utils.initEntityEngineForEntityTypesAndWait(['host']); + + const { body } = await api + .getEntityStoreStatus({ query: { include_components: true } }) + .expect(200); + + expect(body.engines[0].components).toEqual([ + expect.objectContaining({ resource: 'entity_definition' }), + expect.objectContaining({ resource: 'transform' }), + expect.objectContaining({ resource: 'ingest_pipeline' }), + expect.objectContaining({ resource: 'index_template' }), + expect.objectContaining({ resource: 'task' }), + expect.objectContaining({ resource: 'ingest_pipeline' }), + expect.objectContaining({ resource: 'enrich_policy' }), + expect.objectContaining({ resource: 'index' }), + expect.objectContaining({ resource: 'component_template' }), + ]); + }); }); }); @@ -262,14 +295,14 @@ export default ({ getService }: FtrProviderContext) => { it("should not update the index patten when it didn't change", async () => { const response = await api.applyEntityEngineDataviewIndices(); - expect(response.body).to.eql({ success: true, result: [{ type: 'host', changes: {} }] }); + expect(response.body).toEqual({ success: true, result: [{ type: 'host', changes: {} }] }); }); it('should update the index pattern when the data view changes', async () => { await dataView.updateIndexPattern('security-solution', 'test-*'); const response = await api.applyEntityEngineDataviewIndices(); - expect(response.body).to.eql({ + expect(response.body).toEqual({ success: true, result: [ { diff --git a/x-pack/test_serverless/api_integration/test_suites/common/data_usage/tests/data_streams.ts b/x-pack/test_serverless/api_integration/test_suites/common/data_usage/tests/data_streams.ts index d26b73f8689c8..b4dd8d51c331a 100644 --- a/x-pack/test_serverless/api_integration/test_suites/common/data_usage/tests/data_streams.ts +++ b/x-pack/test_serverless/api_integration/test_suites/common/data_usage/tests/data_streams.ts @@ -14,10 +14,10 @@ import { FtrProviderContext } from '../../../../ftr_provider_context'; export default function ({ getService }: FtrProviderContext) { const svlDatastreamsHelpers = getService('svlDatastreamsHelpers'); const roleScopedSupertest = getService('roleScopedSupertest'); + const retry = getService('retry'); let supertestAdminWithCookieCredentials: SupertestWithRoleScope; const testDataStreamName = 'test-data-stream'; describe(`GET ${DATA_USAGE_DATA_STREAMS_API_ROUTE}`, function () { - // due to the plugin depending on yml config (xpack.dataUsage.enabled), we cannot test in MKI until it is on by default this.tags(['skipMKI']); before(async () => { await svlDatastreamsHelpers.createDataStream(testDataStreamName); @@ -33,18 +33,31 @@ export default function ({ getService }: FtrProviderContext) { await svlDatastreamsHelpers.deleteDataStream(testDataStreamName); }); - // skipped because we filter out data streams with 0 storage size, - // and metering api does not pick up indexed data here - // TODO: route should potentially not depend solely on metering API - it.skip('returns created data streams', async () => { + it('returns created data streams', async () => { + await retry.tryForTime(10000, async () => { + const res = await supertestAdminWithCookieCredentials + .get(DATA_USAGE_DATA_STREAMS_API_ROUTE) + .query({ includeZeroStorage: true }) + .set('elastic-api-version', '1'); + const dataStreams: DataStreamsResponseBodySchemaBody = res.body; + const foundStream = dataStreams.find((stream) => stream.name === testDataStreamName); + if (!foundStream) { + throw new Error(`Data stream "${testDataStreamName}" not found. Retrying...`); + } + expect(res.statusCode).to.be(200); + expect(foundStream?.name).to.be(testDataStreamName); + expect(foundStream?.storageSizeBytes).to.be(0); + return true; + }); + }); + it('does not return created data streams without size', async () => { const res = await supertestAdminWithCookieCredentials .get(DATA_USAGE_DATA_STREAMS_API_ROUTE) .set('elastic-api-version', '1'); const dataStreams: DataStreamsResponseBodySchemaBody = res.body; const foundStream = dataStreams.find((stream) => stream.name === testDataStreamName); - expect(foundStream?.name).to.be(testDataStreamName); - expect(foundStream?.storageSizeBytes).to.be(0); expect(res.statusCode).to.be(200); + expect(foundStream).to.be(undefined); }); }); } diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/platform_security/authorization.ts b/x-pack/test_serverless/api_integration/test_suites/observability/platform_security/authorization.ts index e49a9ed45871e..b6dbceedfe65e 100644 --- a/x-pack/test_serverless/api_integration/test_suites/observability/platform_security/authorization.ts +++ b/x-pack/test_serverless/api_integration/test_suites/observability/platform_security/authorization.ts @@ -44,6 +44,7 @@ export default function ({ getService }: FtrProviderContext) { const features = Object.fromEntries( Object.entries(body.features).filter(([key]) => compositeFeatureIds.includes(key)) ); + expectSnapshot(features).toMatchInline(` Object { "apm": Object { @@ -126,6 +127,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.error_rate/apm/rule/runSoon", "alerting:apm.error_rate/apm/rule/scheduleBackfill", "alerting:apm.error_rate/apm/rule/deleteBackfill", + "alerting:apm.error_rate/alerts/rule/get", + "alerting:apm.error_rate/alerts/rule/getRuleState", + "alerting:apm.error_rate/alerts/rule/getAlertSummary", + "alerting:apm.error_rate/alerts/rule/getExecutionLog", + "alerting:apm.error_rate/alerts/rule/getActionErrorLog", + "alerting:apm.error_rate/alerts/rule/find", + "alerting:apm.error_rate/alerts/rule/getRuleExecutionKPI", + "alerting:apm.error_rate/alerts/rule/getBackfill", + "alerting:apm.error_rate/alerts/rule/findBackfill", + "alerting:apm.error_rate/alerts/rule/create", + "alerting:apm.error_rate/alerts/rule/delete", + "alerting:apm.error_rate/alerts/rule/update", + "alerting:apm.error_rate/alerts/rule/updateApiKey", + "alerting:apm.error_rate/alerts/rule/enable", + "alerting:apm.error_rate/alerts/rule/disable", + "alerting:apm.error_rate/alerts/rule/muteAll", + "alerting:apm.error_rate/alerts/rule/unmuteAll", + "alerting:apm.error_rate/alerts/rule/muteAlert", + "alerting:apm.error_rate/alerts/rule/unmuteAlert", + "alerting:apm.error_rate/alerts/rule/snooze", + "alerting:apm.error_rate/alerts/rule/bulkEdit", + "alerting:apm.error_rate/alerts/rule/bulkDelete", + "alerting:apm.error_rate/alerts/rule/bulkEnable", + "alerting:apm.error_rate/alerts/rule/bulkDisable", + "alerting:apm.error_rate/alerts/rule/unsnooze", + "alerting:apm.error_rate/alerts/rule/runSoon", + "alerting:apm.error_rate/alerts/rule/scheduleBackfill", + "alerting:apm.error_rate/alerts/rule/deleteBackfill", "alerting:apm.transaction_error_rate/apm/rule/get", "alerting:apm.transaction_error_rate/apm/rule/getRuleState", "alerting:apm.transaction_error_rate/apm/rule/getAlertSummary", @@ -154,6 +183,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.transaction_error_rate/apm/rule/runSoon", "alerting:apm.transaction_error_rate/apm/rule/scheduleBackfill", "alerting:apm.transaction_error_rate/apm/rule/deleteBackfill", + "alerting:apm.transaction_error_rate/alerts/rule/get", + "alerting:apm.transaction_error_rate/alerts/rule/getRuleState", + "alerting:apm.transaction_error_rate/alerts/rule/getAlertSummary", + "alerting:apm.transaction_error_rate/alerts/rule/getExecutionLog", + "alerting:apm.transaction_error_rate/alerts/rule/getActionErrorLog", + "alerting:apm.transaction_error_rate/alerts/rule/find", + "alerting:apm.transaction_error_rate/alerts/rule/getRuleExecutionKPI", + "alerting:apm.transaction_error_rate/alerts/rule/getBackfill", + "alerting:apm.transaction_error_rate/alerts/rule/findBackfill", + "alerting:apm.transaction_error_rate/alerts/rule/create", + "alerting:apm.transaction_error_rate/alerts/rule/delete", + "alerting:apm.transaction_error_rate/alerts/rule/update", + "alerting:apm.transaction_error_rate/alerts/rule/updateApiKey", + "alerting:apm.transaction_error_rate/alerts/rule/enable", + "alerting:apm.transaction_error_rate/alerts/rule/disable", + "alerting:apm.transaction_error_rate/alerts/rule/muteAll", + "alerting:apm.transaction_error_rate/alerts/rule/unmuteAll", + "alerting:apm.transaction_error_rate/alerts/rule/muteAlert", + "alerting:apm.transaction_error_rate/alerts/rule/unmuteAlert", + "alerting:apm.transaction_error_rate/alerts/rule/snooze", + "alerting:apm.transaction_error_rate/alerts/rule/bulkEdit", + "alerting:apm.transaction_error_rate/alerts/rule/bulkDelete", + "alerting:apm.transaction_error_rate/alerts/rule/bulkEnable", + "alerting:apm.transaction_error_rate/alerts/rule/bulkDisable", + "alerting:apm.transaction_error_rate/alerts/rule/unsnooze", + "alerting:apm.transaction_error_rate/alerts/rule/runSoon", + "alerting:apm.transaction_error_rate/alerts/rule/scheduleBackfill", + "alerting:apm.transaction_error_rate/alerts/rule/deleteBackfill", "alerting:apm.transaction_duration/apm/rule/get", "alerting:apm.transaction_duration/apm/rule/getRuleState", "alerting:apm.transaction_duration/apm/rule/getAlertSummary", @@ -182,6 +239,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.transaction_duration/apm/rule/runSoon", "alerting:apm.transaction_duration/apm/rule/scheduleBackfill", "alerting:apm.transaction_duration/apm/rule/deleteBackfill", + "alerting:apm.transaction_duration/alerts/rule/get", + "alerting:apm.transaction_duration/alerts/rule/getRuleState", + "alerting:apm.transaction_duration/alerts/rule/getAlertSummary", + "alerting:apm.transaction_duration/alerts/rule/getExecutionLog", + "alerting:apm.transaction_duration/alerts/rule/getActionErrorLog", + "alerting:apm.transaction_duration/alerts/rule/find", + "alerting:apm.transaction_duration/alerts/rule/getRuleExecutionKPI", + "alerting:apm.transaction_duration/alerts/rule/getBackfill", + "alerting:apm.transaction_duration/alerts/rule/findBackfill", + "alerting:apm.transaction_duration/alerts/rule/create", + "alerting:apm.transaction_duration/alerts/rule/delete", + "alerting:apm.transaction_duration/alerts/rule/update", + "alerting:apm.transaction_duration/alerts/rule/updateApiKey", + "alerting:apm.transaction_duration/alerts/rule/enable", + "alerting:apm.transaction_duration/alerts/rule/disable", + "alerting:apm.transaction_duration/alerts/rule/muteAll", + "alerting:apm.transaction_duration/alerts/rule/unmuteAll", + "alerting:apm.transaction_duration/alerts/rule/muteAlert", + "alerting:apm.transaction_duration/alerts/rule/unmuteAlert", + "alerting:apm.transaction_duration/alerts/rule/snooze", + "alerting:apm.transaction_duration/alerts/rule/bulkEdit", + "alerting:apm.transaction_duration/alerts/rule/bulkDelete", + "alerting:apm.transaction_duration/alerts/rule/bulkEnable", + "alerting:apm.transaction_duration/alerts/rule/bulkDisable", + "alerting:apm.transaction_duration/alerts/rule/unsnooze", + "alerting:apm.transaction_duration/alerts/rule/runSoon", + "alerting:apm.transaction_duration/alerts/rule/scheduleBackfill", + "alerting:apm.transaction_duration/alerts/rule/deleteBackfill", "alerting:apm.anomaly/apm/rule/get", "alerting:apm.anomaly/apm/rule/getRuleState", "alerting:apm.anomaly/apm/rule/getAlertSummary", @@ -210,26 +295,74 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.anomaly/apm/rule/runSoon", "alerting:apm.anomaly/apm/rule/scheduleBackfill", "alerting:apm.anomaly/apm/rule/deleteBackfill", + "alerting:apm.anomaly/alerts/rule/get", + "alerting:apm.anomaly/alerts/rule/getRuleState", + "alerting:apm.anomaly/alerts/rule/getAlertSummary", + "alerting:apm.anomaly/alerts/rule/getExecutionLog", + "alerting:apm.anomaly/alerts/rule/getActionErrorLog", + "alerting:apm.anomaly/alerts/rule/find", + "alerting:apm.anomaly/alerts/rule/getRuleExecutionKPI", + "alerting:apm.anomaly/alerts/rule/getBackfill", + "alerting:apm.anomaly/alerts/rule/findBackfill", + "alerting:apm.anomaly/alerts/rule/create", + "alerting:apm.anomaly/alerts/rule/delete", + "alerting:apm.anomaly/alerts/rule/update", + "alerting:apm.anomaly/alerts/rule/updateApiKey", + "alerting:apm.anomaly/alerts/rule/enable", + "alerting:apm.anomaly/alerts/rule/disable", + "alerting:apm.anomaly/alerts/rule/muteAll", + "alerting:apm.anomaly/alerts/rule/unmuteAll", + "alerting:apm.anomaly/alerts/rule/muteAlert", + "alerting:apm.anomaly/alerts/rule/unmuteAlert", + "alerting:apm.anomaly/alerts/rule/snooze", + "alerting:apm.anomaly/alerts/rule/bulkEdit", + "alerting:apm.anomaly/alerts/rule/bulkDelete", + "alerting:apm.anomaly/alerts/rule/bulkEnable", + "alerting:apm.anomaly/alerts/rule/bulkDisable", + "alerting:apm.anomaly/alerts/rule/unsnooze", + "alerting:apm.anomaly/alerts/rule/runSoon", + "alerting:apm.anomaly/alerts/rule/scheduleBackfill", + "alerting:apm.anomaly/alerts/rule/deleteBackfill", "alerting:apm.error_rate/apm/alert/get", "alerting:apm.error_rate/apm/alert/find", "alerting:apm.error_rate/apm/alert/getAuthorizedAlertsIndices", "alerting:apm.error_rate/apm/alert/getAlertSummary", "alerting:apm.error_rate/apm/alert/update", + "alerting:apm.error_rate/alerts/alert/get", + "alerting:apm.error_rate/alerts/alert/find", + "alerting:apm.error_rate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.error_rate/alerts/alert/getAlertSummary", + "alerting:apm.error_rate/alerts/alert/update", "alerting:apm.transaction_error_rate/apm/alert/get", "alerting:apm.transaction_error_rate/apm/alert/find", "alerting:apm.transaction_error_rate/apm/alert/getAuthorizedAlertsIndices", "alerting:apm.transaction_error_rate/apm/alert/getAlertSummary", "alerting:apm.transaction_error_rate/apm/alert/update", + "alerting:apm.transaction_error_rate/alerts/alert/get", + "alerting:apm.transaction_error_rate/alerts/alert/find", + "alerting:apm.transaction_error_rate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_error_rate/alerts/alert/getAlertSummary", + "alerting:apm.transaction_error_rate/alerts/alert/update", "alerting:apm.transaction_duration/apm/alert/get", "alerting:apm.transaction_duration/apm/alert/find", "alerting:apm.transaction_duration/apm/alert/getAuthorizedAlertsIndices", "alerting:apm.transaction_duration/apm/alert/getAlertSummary", "alerting:apm.transaction_duration/apm/alert/update", + "alerting:apm.transaction_duration/alerts/alert/get", + "alerting:apm.transaction_duration/alerts/alert/find", + "alerting:apm.transaction_duration/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_duration/alerts/alert/getAlertSummary", + "alerting:apm.transaction_duration/alerts/alert/update", "alerting:apm.anomaly/apm/alert/get", "alerting:apm.anomaly/apm/alert/find", "alerting:apm.anomaly/apm/alert/getAuthorizedAlertsIndices", "alerting:apm.anomaly/apm/alert/getAlertSummary", "alerting:apm.anomaly/apm/alert/update", + "alerting:apm.anomaly/alerts/alert/get", + "alerting:apm.anomaly/alerts/alert/find", + "alerting:apm.anomaly/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.anomaly/alerts/alert/getAlertSummary", + "alerting:apm.anomaly/alerts/alert/update", "api:infra", "app:infra", "app:logs", @@ -294,6 +427,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:logs.alert.document.count/logs/rule/runSoon", "alerting:logs.alert.document.count/logs/rule/scheduleBackfill", "alerting:logs.alert.document.count/logs/rule/deleteBackfill", + "alerting:logs.alert.document.count/alerts/rule/get", + "alerting:logs.alert.document.count/alerts/rule/getRuleState", + "alerting:logs.alert.document.count/alerts/rule/getAlertSummary", + "alerting:logs.alert.document.count/alerts/rule/getExecutionLog", + "alerting:logs.alert.document.count/alerts/rule/getActionErrorLog", + "alerting:logs.alert.document.count/alerts/rule/find", + "alerting:logs.alert.document.count/alerts/rule/getRuleExecutionKPI", + "alerting:logs.alert.document.count/alerts/rule/getBackfill", + "alerting:logs.alert.document.count/alerts/rule/findBackfill", + "alerting:logs.alert.document.count/alerts/rule/create", + "alerting:logs.alert.document.count/alerts/rule/delete", + "alerting:logs.alert.document.count/alerts/rule/update", + "alerting:logs.alert.document.count/alerts/rule/updateApiKey", + "alerting:logs.alert.document.count/alerts/rule/enable", + "alerting:logs.alert.document.count/alerts/rule/disable", + "alerting:logs.alert.document.count/alerts/rule/muteAll", + "alerting:logs.alert.document.count/alerts/rule/unmuteAll", + "alerting:logs.alert.document.count/alerts/rule/muteAlert", + "alerting:logs.alert.document.count/alerts/rule/unmuteAlert", + "alerting:logs.alert.document.count/alerts/rule/snooze", + "alerting:logs.alert.document.count/alerts/rule/bulkEdit", + "alerting:logs.alert.document.count/alerts/rule/bulkDelete", + "alerting:logs.alert.document.count/alerts/rule/bulkEnable", + "alerting:logs.alert.document.count/alerts/rule/bulkDisable", + "alerting:logs.alert.document.count/alerts/rule/unsnooze", + "alerting:logs.alert.document.count/alerts/rule/runSoon", + "alerting:logs.alert.document.count/alerts/rule/scheduleBackfill", + "alerting:logs.alert.document.count/alerts/rule/deleteBackfill", "alerting:.es-query/logs/rule/get", "alerting:.es-query/logs/rule/getRuleState", "alerting:.es-query/logs/rule/getAlertSummary", @@ -322,6 +483,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:.es-query/logs/rule/runSoon", "alerting:.es-query/logs/rule/scheduleBackfill", "alerting:.es-query/logs/rule/deleteBackfill", + "alerting:.es-query/alerts/rule/get", + "alerting:.es-query/alerts/rule/getRuleState", + "alerting:.es-query/alerts/rule/getAlertSummary", + "alerting:.es-query/alerts/rule/getExecutionLog", + "alerting:.es-query/alerts/rule/getActionErrorLog", + "alerting:.es-query/alerts/rule/find", + "alerting:.es-query/alerts/rule/getRuleExecutionKPI", + "alerting:.es-query/alerts/rule/getBackfill", + "alerting:.es-query/alerts/rule/findBackfill", + "alerting:.es-query/alerts/rule/create", + "alerting:.es-query/alerts/rule/delete", + "alerting:.es-query/alerts/rule/update", + "alerting:.es-query/alerts/rule/updateApiKey", + "alerting:.es-query/alerts/rule/enable", + "alerting:.es-query/alerts/rule/disable", + "alerting:.es-query/alerts/rule/muteAll", + "alerting:.es-query/alerts/rule/unmuteAll", + "alerting:.es-query/alerts/rule/muteAlert", + "alerting:.es-query/alerts/rule/unmuteAlert", + "alerting:.es-query/alerts/rule/snooze", + "alerting:.es-query/alerts/rule/bulkEdit", + "alerting:.es-query/alerts/rule/bulkDelete", + "alerting:.es-query/alerts/rule/bulkEnable", + "alerting:.es-query/alerts/rule/bulkDisable", + "alerting:.es-query/alerts/rule/unsnooze", + "alerting:.es-query/alerts/rule/runSoon", + "alerting:.es-query/alerts/rule/scheduleBackfill", + "alerting:.es-query/alerts/rule/deleteBackfill", "alerting:observability.rules.custom_threshold/logs/rule/get", "alerting:observability.rules.custom_threshold/logs/rule/getRuleState", "alerting:observability.rules.custom_threshold/logs/rule/getAlertSummary", @@ -350,6 +539,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:observability.rules.custom_threshold/logs/rule/runSoon", "alerting:observability.rules.custom_threshold/logs/rule/scheduleBackfill", "alerting:observability.rules.custom_threshold/logs/rule/deleteBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/get", + "alerting:observability.rules.custom_threshold/alerts/rule/getRuleState", + "alerting:observability.rules.custom_threshold/alerts/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/alerts/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/alerts/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/alerts/rule/find", + "alerting:observability.rules.custom_threshold/alerts/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/alerts/rule/getBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/findBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/create", + "alerting:observability.rules.custom_threshold/alerts/rule/delete", + "alerting:observability.rules.custom_threshold/alerts/rule/update", + "alerting:observability.rules.custom_threshold/alerts/rule/updateApiKey", + "alerting:observability.rules.custom_threshold/alerts/rule/enable", + "alerting:observability.rules.custom_threshold/alerts/rule/disable", + "alerting:observability.rules.custom_threshold/alerts/rule/muteAll", + "alerting:observability.rules.custom_threshold/alerts/rule/unmuteAll", + "alerting:observability.rules.custom_threshold/alerts/rule/muteAlert", + "alerting:observability.rules.custom_threshold/alerts/rule/unmuteAlert", + "alerting:observability.rules.custom_threshold/alerts/rule/snooze", + "alerting:observability.rules.custom_threshold/alerts/rule/bulkEdit", + "alerting:observability.rules.custom_threshold/alerts/rule/bulkDelete", + "alerting:observability.rules.custom_threshold/alerts/rule/bulkEnable", + "alerting:observability.rules.custom_threshold/alerts/rule/bulkDisable", + "alerting:observability.rules.custom_threshold/alerts/rule/unsnooze", + "alerting:observability.rules.custom_threshold/alerts/rule/runSoon", + "alerting:observability.rules.custom_threshold/alerts/rule/scheduleBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/deleteBackfill", "alerting:xpack.ml.anomaly_detection_alert/logs/rule/get", "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getRuleState", "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getAlertSummary", @@ -378,171 +595,79 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.ml.anomaly_detection_alert/logs/rule/runSoon", "alerting:xpack.ml.anomaly_detection_alert/logs/rule/scheduleBackfill", "alerting:xpack.ml.anomaly_detection_alert/logs/rule/deleteBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/create", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/delete", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/update", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/updateApiKey", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/enable", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/disable", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/muteAll", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/unmuteAll", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/muteAlert", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/unmuteAlert", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/snooze", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/bulkEdit", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/bulkDelete", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/bulkEnable", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/bulkDisable", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/unsnooze", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/runSoon", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/scheduleBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/deleteBackfill", "alerting:logs.alert.document.count/logs/alert/get", "alerting:logs.alert.document.count/logs/alert/find", "alerting:logs.alert.document.count/logs/alert/getAuthorizedAlertsIndices", "alerting:logs.alert.document.count/logs/alert/getAlertSummary", "alerting:logs.alert.document.count/logs/alert/update", + "alerting:logs.alert.document.count/alerts/alert/get", + "alerting:logs.alert.document.count/alerts/alert/find", + "alerting:logs.alert.document.count/alerts/alert/getAuthorizedAlertsIndices", + "alerting:logs.alert.document.count/alerts/alert/getAlertSummary", + "alerting:logs.alert.document.count/alerts/alert/update", "alerting:.es-query/logs/alert/get", "alerting:.es-query/logs/alert/find", "alerting:.es-query/logs/alert/getAuthorizedAlertsIndices", "alerting:.es-query/logs/alert/getAlertSummary", "alerting:.es-query/logs/alert/update", + "alerting:.es-query/alerts/alert/get", + "alerting:.es-query/alerts/alert/find", + "alerting:.es-query/alerts/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/alerts/alert/getAlertSummary", + "alerting:.es-query/alerts/alert/update", "alerting:observability.rules.custom_threshold/logs/alert/get", "alerting:observability.rules.custom_threshold/logs/alert/find", "alerting:observability.rules.custom_threshold/logs/alert/getAuthorizedAlertsIndices", "alerting:observability.rules.custom_threshold/logs/alert/getAlertSummary", "alerting:observability.rules.custom_threshold/logs/alert/update", + "alerting:observability.rules.custom_threshold/alerts/alert/get", + "alerting:observability.rules.custom_threshold/alerts/alert/find", + "alerting:observability.rules.custom_threshold/alerts/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/alerts/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/alerts/alert/update", "alerting:xpack.ml.anomaly_detection_alert/logs/alert/get", "alerting:xpack.ml.anomaly_detection_alert/logs/alert/find", "alerting:xpack.ml.anomaly_detection_alert/logs/alert/getAuthorizedAlertsIndices", "alerting:xpack.ml.anomaly_detection_alert/logs/alert/getAlertSummary", "alerting:xpack.ml.anomaly_detection_alert/logs/alert/update", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/update", "app:observability", "ui:catalogue/observability", "ui:navLinks/observability", "ui:observability/read", "ui:observability/write", - "alerting:slo.rules.burnRate/observability/rule/get", - "alerting:slo.rules.burnRate/observability/rule/getRuleState", - "alerting:slo.rules.burnRate/observability/rule/getAlertSummary", - "alerting:slo.rules.burnRate/observability/rule/getExecutionLog", - "alerting:slo.rules.burnRate/observability/rule/getActionErrorLog", - "alerting:slo.rules.burnRate/observability/rule/find", - "alerting:slo.rules.burnRate/observability/rule/getRuleExecutionKPI", - "alerting:slo.rules.burnRate/observability/rule/getBackfill", - "alerting:slo.rules.burnRate/observability/rule/findBackfill", - "alerting:slo.rules.burnRate/observability/rule/create", - "alerting:slo.rules.burnRate/observability/rule/delete", - "alerting:slo.rules.burnRate/observability/rule/update", - "alerting:slo.rules.burnRate/observability/rule/updateApiKey", - "alerting:slo.rules.burnRate/observability/rule/enable", - "alerting:slo.rules.burnRate/observability/rule/disable", - "alerting:slo.rules.burnRate/observability/rule/muteAll", - "alerting:slo.rules.burnRate/observability/rule/unmuteAll", - "alerting:slo.rules.burnRate/observability/rule/muteAlert", - "alerting:slo.rules.burnRate/observability/rule/unmuteAlert", - "alerting:slo.rules.burnRate/observability/rule/snooze", - "alerting:slo.rules.burnRate/observability/rule/bulkEdit", - "alerting:slo.rules.burnRate/observability/rule/bulkDelete", - "alerting:slo.rules.burnRate/observability/rule/bulkEnable", - "alerting:slo.rules.burnRate/observability/rule/bulkDisable", - "alerting:slo.rules.burnRate/observability/rule/unsnooze", - "alerting:slo.rules.burnRate/observability/rule/runSoon", - "alerting:slo.rules.burnRate/observability/rule/scheduleBackfill", - "alerting:slo.rules.burnRate/observability/rule/deleteBackfill", - "alerting:observability.rules.custom_threshold/observability/rule/get", - "alerting:observability.rules.custom_threshold/observability/rule/getRuleState", - "alerting:observability.rules.custom_threshold/observability/rule/getAlertSummary", - "alerting:observability.rules.custom_threshold/observability/rule/getExecutionLog", - "alerting:observability.rules.custom_threshold/observability/rule/getActionErrorLog", - "alerting:observability.rules.custom_threshold/observability/rule/find", - "alerting:observability.rules.custom_threshold/observability/rule/getRuleExecutionKPI", - "alerting:observability.rules.custom_threshold/observability/rule/getBackfill", - "alerting:observability.rules.custom_threshold/observability/rule/findBackfill", - "alerting:observability.rules.custom_threshold/observability/rule/create", - "alerting:observability.rules.custom_threshold/observability/rule/delete", - "alerting:observability.rules.custom_threshold/observability/rule/update", - "alerting:observability.rules.custom_threshold/observability/rule/updateApiKey", - "alerting:observability.rules.custom_threshold/observability/rule/enable", - "alerting:observability.rules.custom_threshold/observability/rule/disable", - "alerting:observability.rules.custom_threshold/observability/rule/muteAll", - "alerting:observability.rules.custom_threshold/observability/rule/unmuteAll", - "alerting:observability.rules.custom_threshold/observability/rule/muteAlert", - "alerting:observability.rules.custom_threshold/observability/rule/unmuteAlert", - "alerting:observability.rules.custom_threshold/observability/rule/snooze", - "alerting:observability.rules.custom_threshold/observability/rule/bulkEdit", - "alerting:observability.rules.custom_threshold/observability/rule/bulkDelete", - "alerting:observability.rules.custom_threshold/observability/rule/bulkEnable", - "alerting:observability.rules.custom_threshold/observability/rule/bulkDisable", - "alerting:observability.rules.custom_threshold/observability/rule/unsnooze", - "alerting:observability.rules.custom_threshold/observability/rule/runSoon", - "alerting:observability.rules.custom_threshold/observability/rule/scheduleBackfill", - "alerting:observability.rules.custom_threshold/observability/rule/deleteBackfill", - "alerting:.es-query/observability/rule/get", - "alerting:.es-query/observability/rule/getRuleState", - "alerting:.es-query/observability/rule/getAlertSummary", - "alerting:.es-query/observability/rule/getExecutionLog", - "alerting:.es-query/observability/rule/getActionErrorLog", - "alerting:.es-query/observability/rule/find", - "alerting:.es-query/observability/rule/getRuleExecutionKPI", - "alerting:.es-query/observability/rule/getBackfill", - "alerting:.es-query/observability/rule/findBackfill", - "alerting:.es-query/observability/rule/create", - "alerting:.es-query/observability/rule/delete", - "alerting:.es-query/observability/rule/update", - "alerting:.es-query/observability/rule/updateApiKey", - "alerting:.es-query/observability/rule/enable", - "alerting:.es-query/observability/rule/disable", - "alerting:.es-query/observability/rule/muteAll", - "alerting:.es-query/observability/rule/unmuteAll", - "alerting:.es-query/observability/rule/muteAlert", - "alerting:.es-query/observability/rule/unmuteAlert", - "alerting:.es-query/observability/rule/snooze", - "alerting:.es-query/observability/rule/bulkEdit", - "alerting:.es-query/observability/rule/bulkDelete", - "alerting:.es-query/observability/rule/bulkEnable", - "alerting:.es-query/observability/rule/bulkDisable", - "alerting:.es-query/observability/rule/unsnooze", - "alerting:.es-query/observability/rule/runSoon", - "alerting:.es-query/observability/rule/scheduleBackfill", - "alerting:.es-query/observability/rule/deleteBackfill", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/get", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleState", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getAlertSummary", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getExecutionLog", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getActionErrorLog", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/find", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleExecutionKPI", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getBackfill", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/findBackfill", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/create", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/delete", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/update", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/updateApiKey", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/enable", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/disable", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/muteAll", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unmuteAll", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/muteAlert", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unmuteAlert", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/snooze", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkEdit", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkDelete", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkEnable", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkDisable", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unsnooze", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/runSoon", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/scheduleBackfill", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/deleteBackfill", - "alerting:metrics.alert.inventory.threshold/observability/rule/get", - "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleState", - "alerting:metrics.alert.inventory.threshold/observability/rule/getAlertSummary", - "alerting:metrics.alert.inventory.threshold/observability/rule/getExecutionLog", - "alerting:metrics.alert.inventory.threshold/observability/rule/getActionErrorLog", - "alerting:metrics.alert.inventory.threshold/observability/rule/find", - "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleExecutionKPI", - "alerting:metrics.alert.inventory.threshold/observability/rule/getBackfill", - "alerting:metrics.alert.inventory.threshold/observability/rule/findBackfill", - "alerting:metrics.alert.inventory.threshold/observability/rule/create", - "alerting:metrics.alert.inventory.threshold/observability/rule/delete", - "alerting:metrics.alert.inventory.threshold/observability/rule/update", - "alerting:metrics.alert.inventory.threshold/observability/rule/updateApiKey", - "alerting:metrics.alert.inventory.threshold/observability/rule/enable", - "alerting:metrics.alert.inventory.threshold/observability/rule/disable", - "alerting:metrics.alert.inventory.threshold/observability/rule/muteAll", - "alerting:metrics.alert.inventory.threshold/observability/rule/unmuteAll", - "alerting:metrics.alert.inventory.threshold/observability/rule/muteAlert", - "alerting:metrics.alert.inventory.threshold/observability/rule/unmuteAlert", - "alerting:metrics.alert.inventory.threshold/observability/rule/snooze", - "alerting:metrics.alert.inventory.threshold/observability/rule/bulkEdit", - "alerting:metrics.alert.inventory.threshold/observability/rule/bulkDelete", - "alerting:metrics.alert.inventory.threshold/observability/rule/bulkEnable", - "alerting:metrics.alert.inventory.threshold/observability/rule/bulkDisable", - "alerting:metrics.alert.inventory.threshold/observability/rule/unsnooze", - "alerting:metrics.alert.inventory.threshold/observability/rule/runSoon", - "alerting:metrics.alert.inventory.threshold/observability/rule/scheduleBackfill", - "alerting:metrics.alert.inventory.threshold/observability/rule/deleteBackfill", "alerting:apm.error_rate/observability/rule/get", "alerting:apm.error_rate/observability/rule/getRuleState", "alerting:apm.error_rate/observability/rule/getAlertSummary", @@ -683,6 +808,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/runSoon", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/scheduleBackfill", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/deleteBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/get", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getRuleState", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getAlertSummary", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getExecutionLog", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getActionErrorLog", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/find", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/findBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/create", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/delete", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/update", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/updateApiKey", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/enable", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/disable", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/muteAll", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/unmuteAll", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/muteAlert", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/unmuteAlert", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/snooze", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/bulkEdit", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/bulkDelete", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/bulkEnable", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/bulkDisable", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/unsnooze", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/runSoon", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/scheduleBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/deleteBackfill", "alerting:xpack.synthetics.alerts.tls/observability/rule/get", "alerting:xpack.synthetics.alerts.tls/observability/rule/getRuleState", "alerting:xpack.synthetics.alerts.tls/observability/rule/getAlertSummary", @@ -711,121 +864,728 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.synthetics.alerts.tls/observability/rule/runSoon", "alerting:xpack.synthetics.alerts.tls/observability/rule/scheduleBackfill", "alerting:xpack.synthetics.alerts.tls/observability/rule/deleteBackfill", - "alerting:slo.rules.burnRate/observability/alert/get", - "alerting:slo.rules.burnRate/observability/alert/find", - "alerting:slo.rules.burnRate/observability/alert/getAuthorizedAlertsIndices", - "alerting:slo.rules.burnRate/observability/alert/getAlertSummary", - "alerting:slo.rules.burnRate/observability/alert/update", - "alerting:observability.rules.custom_threshold/observability/alert/get", - "alerting:observability.rules.custom_threshold/observability/alert/find", - "alerting:observability.rules.custom_threshold/observability/alert/getAuthorizedAlertsIndices", - "alerting:observability.rules.custom_threshold/observability/alert/getAlertSummary", - "alerting:observability.rules.custom_threshold/observability/alert/update", - "alerting:.es-query/observability/alert/get", - "alerting:.es-query/observability/alert/find", - "alerting:.es-query/observability/alert/getAuthorizedAlertsIndices", - "alerting:.es-query/observability/alert/getAlertSummary", - "alerting:.es-query/observability/alert/update", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/get", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/find", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAuthorizedAlertsIndices", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAlertSummary", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/update", - "alerting:metrics.alert.inventory.threshold/observability/alert/get", - "alerting:metrics.alert.inventory.threshold/observability/alert/find", - "alerting:metrics.alert.inventory.threshold/observability/alert/getAuthorizedAlertsIndices", - "alerting:metrics.alert.inventory.threshold/observability/alert/getAlertSummary", - "alerting:metrics.alert.inventory.threshold/observability/alert/update", - "alerting:apm.error_rate/observability/alert/get", - "alerting:apm.error_rate/observability/alert/find", - "alerting:apm.error_rate/observability/alert/getAuthorizedAlertsIndices", - "alerting:apm.error_rate/observability/alert/getAlertSummary", - "alerting:apm.error_rate/observability/alert/update", - "alerting:apm.transaction_error_rate/observability/alert/get", - "alerting:apm.transaction_error_rate/observability/alert/find", - "alerting:apm.transaction_error_rate/observability/alert/getAuthorizedAlertsIndices", - "alerting:apm.transaction_error_rate/observability/alert/getAlertSummary", - "alerting:apm.transaction_error_rate/observability/alert/update", - "alerting:apm.transaction_duration/observability/alert/get", - "alerting:apm.transaction_duration/observability/alert/find", - "alerting:apm.transaction_duration/observability/alert/getAuthorizedAlertsIndices", - "alerting:apm.transaction_duration/observability/alert/getAlertSummary", - "alerting:apm.transaction_duration/observability/alert/update", - "alerting:apm.anomaly/observability/alert/get", - "alerting:apm.anomaly/observability/alert/find", - "alerting:apm.anomaly/observability/alert/getAuthorizedAlertsIndices", - "alerting:apm.anomaly/observability/alert/getAlertSummary", - "alerting:apm.anomaly/observability/alert/update", - "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/get", - "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/find", - "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/getAuthorizedAlertsIndices", - "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/getAlertSummary", - "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/update", - "alerting:xpack.synthetics.alerts.tls/observability/alert/get", - "alerting:xpack.synthetics.alerts.tls/observability/alert/find", - "alerting:xpack.synthetics.alerts.tls/observability/alert/getAuthorizedAlertsIndices", - "alerting:xpack.synthetics.alerts.tls/observability/alert/getAlertSummary", - "alerting:xpack.synthetics.alerts.tls/observability/alert/update", - ], - "minimal_all": Array [ - "login:", - "api:apm", - "api:apm_write", - "api:rac", - "app:apm", - "app:ux", - "app:kibana", - "ui:catalogue/apm", - "ui:management/insightsAndAlerting/triggersActions", - "ui:navLinks/apm", - "ui:navLinks/ux", - "ui:navLinks/kibana", - "saved_object:telemetry/bulk_get", - "saved_object:telemetry/get", - "saved_object:telemetry/find", - "saved_object:telemetry/open_point_in_time", - "saved_object:telemetry/close_point_in_time", - "saved_object:telemetry/create", - "saved_object:telemetry/bulk_create", - "saved_object:telemetry/update", - "saved_object:telemetry/bulk_update", - "saved_object:telemetry/delete", - "saved_object:telemetry/bulk_delete", - "saved_object:telemetry/share_to_space", - "saved_object:apm-indices/bulk_get", - "saved_object:apm-indices/get", - "saved_object:apm-indices/find", - "saved_object:apm-indices/open_point_in_time", - "saved_object:apm-indices/close_point_in_time", - "saved_object:config/bulk_get", - "saved_object:config/get", - "saved_object:config/find", - "saved_object:config/open_point_in_time", - "saved_object:config/close_point_in_time", - "saved_object:config-global/bulk_get", - "saved_object:config-global/get", - "saved_object:config-global/find", - "saved_object:config-global/open_point_in_time", - "saved_object:config-global/close_point_in_time", - "saved_object:url/bulk_get", - "saved_object:url/get", - "saved_object:url/find", - "saved_object:url/open_point_in_time", - "saved_object:url/close_point_in_time", - "ui:apm/show", - "ui:apm/save", - "ui:apm/alerting:show", - "ui:apm/alerting:save", - "alerting:apm.error_rate/apm/rule/get", - "alerting:apm.error_rate/apm/rule/getRuleState", - "alerting:apm.error_rate/apm/rule/getAlertSummary", - "alerting:apm.error_rate/apm/rule/getExecutionLog", - "alerting:apm.error_rate/apm/rule/getActionErrorLog", - "alerting:apm.error_rate/apm/rule/find", - "alerting:apm.error_rate/apm/rule/getRuleExecutionKPI", - "alerting:apm.error_rate/apm/rule/getBackfill", - "alerting:apm.error_rate/apm/rule/findBackfill", - "alerting:apm.error_rate/apm/rule/create", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/get", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getRuleState", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getAlertSummary", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getExecutionLog", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getActionErrorLog", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/find", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getBackfill", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/findBackfill", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/create", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/delete", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/update", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/updateApiKey", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/enable", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/disable", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/muteAll", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/unmuteAll", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/muteAlert", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/unmuteAlert", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/snooze", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/bulkEdit", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/bulkDelete", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/bulkEnable", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/bulkDisable", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/unsnooze", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/runSoon", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/scheduleBackfill", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/deleteBackfill", + "alerting:metrics.alert.threshold/observability/rule/get", + "alerting:metrics.alert.threshold/observability/rule/getRuleState", + "alerting:metrics.alert.threshold/observability/rule/getAlertSummary", + "alerting:metrics.alert.threshold/observability/rule/getExecutionLog", + "alerting:metrics.alert.threshold/observability/rule/getActionErrorLog", + "alerting:metrics.alert.threshold/observability/rule/find", + "alerting:metrics.alert.threshold/observability/rule/getRuleExecutionKPI", + "alerting:metrics.alert.threshold/observability/rule/getBackfill", + "alerting:metrics.alert.threshold/observability/rule/findBackfill", + "alerting:metrics.alert.threshold/observability/rule/create", + "alerting:metrics.alert.threshold/observability/rule/delete", + "alerting:metrics.alert.threshold/observability/rule/update", + "alerting:metrics.alert.threshold/observability/rule/updateApiKey", + "alerting:metrics.alert.threshold/observability/rule/enable", + "alerting:metrics.alert.threshold/observability/rule/disable", + "alerting:metrics.alert.threshold/observability/rule/muteAll", + "alerting:metrics.alert.threshold/observability/rule/unmuteAll", + "alerting:metrics.alert.threshold/observability/rule/muteAlert", + "alerting:metrics.alert.threshold/observability/rule/unmuteAlert", + "alerting:metrics.alert.threshold/observability/rule/snooze", + "alerting:metrics.alert.threshold/observability/rule/bulkEdit", + "alerting:metrics.alert.threshold/observability/rule/bulkDelete", + "alerting:metrics.alert.threshold/observability/rule/bulkEnable", + "alerting:metrics.alert.threshold/observability/rule/bulkDisable", + "alerting:metrics.alert.threshold/observability/rule/unsnooze", + "alerting:metrics.alert.threshold/observability/rule/runSoon", + "alerting:metrics.alert.threshold/observability/rule/scheduleBackfill", + "alerting:metrics.alert.threshold/observability/rule/deleteBackfill", + "alerting:metrics.alert.threshold/alerts/rule/get", + "alerting:metrics.alert.threshold/alerts/rule/getRuleState", + "alerting:metrics.alert.threshold/alerts/rule/getAlertSummary", + "alerting:metrics.alert.threshold/alerts/rule/getExecutionLog", + "alerting:metrics.alert.threshold/alerts/rule/getActionErrorLog", + "alerting:metrics.alert.threshold/alerts/rule/find", + "alerting:metrics.alert.threshold/alerts/rule/getRuleExecutionKPI", + "alerting:metrics.alert.threshold/alerts/rule/getBackfill", + "alerting:metrics.alert.threshold/alerts/rule/findBackfill", + "alerting:metrics.alert.threshold/alerts/rule/create", + "alerting:metrics.alert.threshold/alerts/rule/delete", + "alerting:metrics.alert.threshold/alerts/rule/update", + "alerting:metrics.alert.threshold/alerts/rule/updateApiKey", + "alerting:metrics.alert.threshold/alerts/rule/enable", + "alerting:metrics.alert.threshold/alerts/rule/disable", + "alerting:metrics.alert.threshold/alerts/rule/muteAll", + "alerting:metrics.alert.threshold/alerts/rule/unmuteAll", + "alerting:metrics.alert.threshold/alerts/rule/muteAlert", + "alerting:metrics.alert.threshold/alerts/rule/unmuteAlert", + "alerting:metrics.alert.threshold/alerts/rule/snooze", + "alerting:metrics.alert.threshold/alerts/rule/bulkEdit", + "alerting:metrics.alert.threshold/alerts/rule/bulkDelete", + "alerting:metrics.alert.threshold/alerts/rule/bulkEnable", + "alerting:metrics.alert.threshold/alerts/rule/bulkDisable", + "alerting:metrics.alert.threshold/alerts/rule/unsnooze", + "alerting:metrics.alert.threshold/alerts/rule/runSoon", + "alerting:metrics.alert.threshold/alerts/rule/scheduleBackfill", + "alerting:metrics.alert.threshold/alerts/rule/deleteBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/get", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleState", + "alerting:metrics.alert.inventory.threshold/observability/rule/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/rule/getExecutionLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/getActionErrorLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/find", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleExecutionKPI", + "alerting:metrics.alert.inventory.threshold/observability/rule/getBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/findBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/create", + "alerting:metrics.alert.inventory.threshold/observability/rule/delete", + "alerting:metrics.alert.inventory.threshold/observability/rule/update", + "alerting:metrics.alert.inventory.threshold/observability/rule/updateApiKey", + "alerting:metrics.alert.inventory.threshold/observability/rule/enable", + "alerting:metrics.alert.inventory.threshold/observability/rule/disable", + "alerting:metrics.alert.inventory.threshold/observability/rule/muteAll", + "alerting:metrics.alert.inventory.threshold/observability/rule/unmuteAll", + "alerting:metrics.alert.inventory.threshold/observability/rule/muteAlert", + "alerting:metrics.alert.inventory.threshold/observability/rule/unmuteAlert", + "alerting:metrics.alert.inventory.threshold/observability/rule/snooze", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkEdit", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkDelete", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkEnable", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkDisable", + "alerting:metrics.alert.inventory.threshold/observability/rule/unsnooze", + "alerting:metrics.alert.inventory.threshold/observability/rule/runSoon", + "alerting:metrics.alert.inventory.threshold/observability/rule/scheduleBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/deleteBackfill", + "alerting:metrics.alert.inventory.threshold/alerts/rule/get", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getRuleState", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getExecutionLog", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getActionErrorLog", + "alerting:metrics.alert.inventory.threshold/alerts/rule/find", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getRuleExecutionKPI", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getBackfill", + "alerting:metrics.alert.inventory.threshold/alerts/rule/findBackfill", + "alerting:metrics.alert.inventory.threshold/alerts/rule/create", + "alerting:metrics.alert.inventory.threshold/alerts/rule/delete", + "alerting:metrics.alert.inventory.threshold/alerts/rule/update", + "alerting:metrics.alert.inventory.threshold/alerts/rule/updateApiKey", + "alerting:metrics.alert.inventory.threshold/alerts/rule/enable", + "alerting:metrics.alert.inventory.threshold/alerts/rule/disable", + "alerting:metrics.alert.inventory.threshold/alerts/rule/muteAll", + "alerting:metrics.alert.inventory.threshold/alerts/rule/unmuteAll", + "alerting:metrics.alert.inventory.threshold/alerts/rule/muteAlert", + "alerting:metrics.alert.inventory.threshold/alerts/rule/unmuteAlert", + "alerting:metrics.alert.inventory.threshold/alerts/rule/snooze", + "alerting:metrics.alert.inventory.threshold/alerts/rule/bulkEdit", + "alerting:metrics.alert.inventory.threshold/alerts/rule/bulkDelete", + "alerting:metrics.alert.inventory.threshold/alerts/rule/bulkEnable", + "alerting:metrics.alert.inventory.threshold/alerts/rule/bulkDisable", + "alerting:metrics.alert.inventory.threshold/alerts/rule/unsnooze", + "alerting:metrics.alert.inventory.threshold/alerts/rule/runSoon", + "alerting:metrics.alert.inventory.threshold/alerts/rule/scheduleBackfill", + "alerting:metrics.alert.inventory.threshold/alerts/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.tls/observability/rule/get", + "alerting:xpack.uptime.alerts.tls/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.tls/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tls/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tls/observability/rule/find", + "alerting:xpack.uptime.alerts.tls/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tls/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.tls/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.tls/observability/rule/create", + "alerting:xpack.uptime.alerts.tls/observability/rule/delete", + "alerting:xpack.uptime.alerts.tls/observability/rule/update", + "alerting:xpack.uptime.alerts.tls/observability/rule/updateApiKey", + "alerting:xpack.uptime.alerts.tls/observability/rule/enable", + "alerting:xpack.uptime.alerts.tls/observability/rule/disable", + "alerting:xpack.uptime.alerts.tls/observability/rule/muteAll", + "alerting:xpack.uptime.alerts.tls/observability/rule/unmuteAll", + "alerting:xpack.uptime.alerts.tls/observability/rule/muteAlert", + "alerting:xpack.uptime.alerts.tls/observability/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.tls/observability/rule/snooze", + "alerting:xpack.uptime.alerts.tls/observability/rule/bulkEdit", + "alerting:xpack.uptime.alerts.tls/observability/rule/bulkDelete", + "alerting:xpack.uptime.alerts.tls/observability/rule/bulkEnable", + "alerting:xpack.uptime.alerts.tls/observability/rule/bulkDisable", + "alerting:xpack.uptime.alerts.tls/observability/rule/unsnooze", + "alerting:xpack.uptime.alerts.tls/observability/rule/runSoon", + "alerting:xpack.uptime.alerts.tls/observability/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.tls/observability/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.tls/alerts/rule/get", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tls/alerts/rule/find", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.tls/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.tls/alerts/rule/create", + "alerting:xpack.uptime.alerts.tls/alerts/rule/delete", + "alerting:xpack.uptime.alerts.tls/alerts/rule/update", + "alerting:xpack.uptime.alerts.tls/alerts/rule/updateApiKey", + "alerting:xpack.uptime.alerts.tls/alerts/rule/enable", + "alerting:xpack.uptime.alerts.tls/alerts/rule/disable", + "alerting:xpack.uptime.alerts.tls/alerts/rule/muteAll", + "alerting:xpack.uptime.alerts.tls/alerts/rule/unmuteAll", + "alerting:xpack.uptime.alerts.tls/alerts/rule/muteAlert", + "alerting:xpack.uptime.alerts.tls/alerts/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.tls/alerts/rule/snooze", + "alerting:xpack.uptime.alerts.tls/alerts/rule/bulkEdit", + "alerting:xpack.uptime.alerts.tls/alerts/rule/bulkDelete", + "alerting:xpack.uptime.alerts.tls/alerts/rule/bulkEnable", + "alerting:xpack.uptime.alerts.tls/alerts/rule/bulkDisable", + "alerting:xpack.uptime.alerts.tls/alerts/rule/unsnooze", + "alerting:xpack.uptime.alerts.tls/alerts/rule/runSoon", + "alerting:xpack.uptime.alerts.tls/alerts/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.tls/alerts/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/get", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/find", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/create", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/delete", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/update", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/updateApiKey", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/enable", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/disable", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/muteAll", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/unmuteAll", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/muteAlert", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/snooze", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/bulkEdit", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/bulkDelete", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/bulkEnable", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/bulkDisable", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/unsnooze", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/runSoon", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/get", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/find", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/create", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/delete", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/update", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/updateApiKey", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/enable", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/disable", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/muteAll", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/unmuteAll", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/muteAlert", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/snooze", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/bulkEdit", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/bulkDelete", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/bulkEnable", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/bulkDisable", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/unsnooze", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/runSoon", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/get", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/find", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/create", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/delete", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/update", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/updateApiKey", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/enable", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/disable", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/muteAll", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/unmuteAll", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/muteAlert", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/snooze", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/bulkEdit", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/bulkDelete", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/bulkEnable", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/bulkDisable", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/unsnooze", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/runSoon", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/get", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/find", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/create", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/delete", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/update", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/updateApiKey", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/enable", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/disable", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/muteAll", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/unmuteAll", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/muteAlert", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/snooze", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/bulkEdit", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/bulkDelete", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/bulkEnable", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/bulkDisable", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/unsnooze", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/runSoon", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/get", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/find", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/create", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/delete", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/update", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/updateApiKey", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/enable", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/disable", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/muteAll", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/unmuteAll", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/muteAlert", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/snooze", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/bulkEdit", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/bulkDelete", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/bulkEnable", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/bulkDisable", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/unsnooze", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/runSoon", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/get", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/find", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/create", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/delete", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/update", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/updateApiKey", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/enable", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/disable", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/muteAll", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/unmuteAll", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/muteAlert", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/snooze", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/bulkEdit", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/bulkDelete", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/bulkEnable", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/bulkDisable", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/unsnooze", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/runSoon", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/deleteBackfill", + "alerting:logs.alert.document.count/observability/rule/get", + "alerting:logs.alert.document.count/observability/rule/getRuleState", + "alerting:logs.alert.document.count/observability/rule/getAlertSummary", + "alerting:logs.alert.document.count/observability/rule/getExecutionLog", + "alerting:logs.alert.document.count/observability/rule/getActionErrorLog", + "alerting:logs.alert.document.count/observability/rule/find", + "alerting:logs.alert.document.count/observability/rule/getRuleExecutionKPI", + "alerting:logs.alert.document.count/observability/rule/getBackfill", + "alerting:logs.alert.document.count/observability/rule/findBackfill", + "alerting:logs.alert.document.count/observability/rule/create", + "alerting:logs.alert.document.count/observability/rule/delete", + "alerting:logs.alert.document.count/observability/rule/update", + "alerting:logs.alert.document.count/observability/rule/updateApiKey", + "alerting:logs.alert.document.count/observability/rule/enable", + "alerting:logs.alert.document.count/observability/rule/disable", + "alerting:logs.alert.document.count/observability/rule/muteAll", + "alerting:logs.alert.document.count/observability/rule/unmuteAll", + "alerting:logs.alert.document.count/observability/rule/muteAlert", + "alerting:logs.alert.document.count/observability/rule/unmuteAlert", + "alerting:logs.alert.document.count/observability/rule/snooze", + "alerting:logs.alert.document.count/observability/rule/bulkEdit", + "alerting:logs.alert.document.count/observability/rule/bulkDelete", + "alerting:logs.alert.document.count/observability/rule/bulkEnable", + "alerting:logs.alert.document.count/observability/rule/bulkDisable", + "alerting:logs.alert.document.count/observability/rule/unsnooze", + "alerting:logs.alert.document.count/observability/rule/runSoon", + "alerting:logs.alert.document.count/observability/rule/scheduleBackfill", + "alerting:logs.alert.document.count/observability/rule/deleteBackfill", + "alerting:slo.rules.burnRate/observability/rule/get", + "alerting:slo.rules.burnRate/observability/rule/getRuleState", + "alerting:slo.rules.burnRate/observability/rule/getAlertSummary", + "alerting:slo.rules.burnRate/observability/rule/getExecutionLog", + "alerting:slo.rules.burnRate/observability/rule/getActionErrorLog", + "alerting:slo.rules.burnRate/observability/rule/find", + "alerting:slo.rules.burnRate/observability/rule/getRuleExecutionKPI", + "alerting:slo.rules.burnRate/observability/rule/getBackfill", + "alerting:slo.rules.burnRate/observability/rule/findBackfill", + "alerting:slo.rules.burnRate/observability/rule/create", + "alerting:slo.rules.burnRate/observability/rule/delete", + "alerting:slo.rules.burnRate/observability/rule/update", + "alerting:slo.rules.burnRate/observability/rule/updateApiKey", + "alerting:slo.rules.burnRate/observability/rule/enable", + "alerting:slo.rules.burnRate/observability/rule/disable", + "alerting:slo.rules.burnRate/observability/rule/muteAll", + "alerting:slo.rules.burnRate/observability/rule/unmuteAll", + "alerting:slo.rules.burnRate/observability/rule/muteAlert", + "alerting:slo.rules.burnRate/observability/rule/unmuteAlert", + "alerting:slo.rules.burnRate/observability/rule/snooze", + "alerting:slo.rules.burnRate/observability/rule/bulkEdit", + "alerting:slo.rules.burnRate/observability/rule/bulkDelete", + "alerting:slo.rules.burnRate/observability/rule/bulkEnable", + "alerting:slo.rules.burnRate/observability/rule/bulkDisable", + "alerting:slo.rules.burnRate/observability/rule/unsnooze", + "alerting:slo.rules.burnRate/observability/rule/runSoon", + "alerting:slo.rules.burnRate/observability/rule/scheduleBackfill", + "alerting:slo.rules.burnRate/observability/rule/deleteBackfill", + "alerting:slo.rules.burnRate/alerts/rule/get", + "alerting:slo.rules.burnRate/alerts/rule/getRuleState", + "alerting:slo.rules.burnRate/alerts/rule/getAlertSummary", + "alerting:slo.rules.burnRate/alerts/rule/getExecutionLog", + "alerting:slo.rules.burnRate/alerts/rule/getActionErrorLog", + "alerting:slo.rules.burnRate/alerts/rule/find", + "alerting:slo.rules.burnRate/alerts/rule/getRuleExecutionKPI", + "alerting:slo.rules.burnRate/alerts/rule/getBackfill", + "alerting:slo.rules.burnRate/alerts/rule/findBackfill", + "alerting:slo.rules.burnRate/alerts/rule/create", + "alerting:slo.rules.burnRate/alerts/rule/delete", + "alerting:slo.rules.burnRate/alerts/rule/update", + "alerting:slo.rules.burnRate/alerts/rule/updateApiKey", + "alerting:slo.rules.burnRate/alerts/rule/enable", + "alerting:slo.rules.burnRate/alerts/rule/disable", + "alerting:slo.rules.burnRate/alerts/rule/muteAll", + "alerting:slo.rules.burnRate/alerts/rule/unmuteAll", + "alerting:slo.rules.burnRate/alerts/rule/muteAlert", + "alerting:slo.rules.burnRate/alerts/rule/unmuteAlert", + "alerting:slo.rules.burnRate/alerts/rule/snooze", + "alerting:slo.rules.burnRate/alerts/rule/bulkEdit", + "alerting:slo.rules.burnRate/alerts/rule/bulkDelete", + "alerting:slo.rules.burnRate/alerts/rule/bulkEnable", + "alerting:slo.rules.burnRate/alerts/rule/bulkDisable", + "alerting:slo.rules.burnRate/alerts/rule/unsnooze", + "alerting:slo.rules.burnRate/alerts/rule/runSoon", + "alerting:slo.rules.burnRate/alerts/rule/scheduleBackfill", + "alerting:slo.rules.burnRate/alerts/rule/deleteBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/get", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleState", + "alerting:observability.rules.custom_threshold/observability/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/observability/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/observability/rule/find", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/observability/rule/getBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/findBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/create", + "alerting:observability.rules.custom_threshold/observability/rule/delete", + "alerting:observability.rules.custom_threshold/observability/rule/update", + "alerting:observability.rules.custom_threshold/observability/rule/updateApiKey", + "alerting:observability.rules.custom_threshold/observability/rule/enable", + "alerting:observability.rules.custom_threshold/observability/rule/disable", + "alerting:observability.rules.custom_threshold/observability/rule/muteAll", + "alerting:observability.rules.custom_threshold/observability/rule/unmuteAll", + "alerting:observability.rules.custom_threshold/observability/rule/muteAlert", + "alerting:observability.rules.custom_threshold/observability/rule/unmuteAlert", + "alerting:observability.rules.custom_threshold/observability/rule/snooze", + "alerting:observability.rules.custom_threshold/observability/rule/bulkEdit", + "alerting:observability.rules.custom_threshold/observability/rule/bulkDelete", + "alerting:observability.rules.custom_threshold/observability/rule/bulkEnable", + "alerting:observability.rules.custom_threshold/observability/rule/bulkDisable", + "alerting:observability.rules.custom_threshold/observability/rule/unsnooze", + "alerting:observability.rules.custom_threshold/observability/rule/runSoon", + "alerting:observability.rules.custom_threshold/observability/rule/scheduleBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/deleteBackfill", + "alerting:.es-query/observability/rule/get", + "alerting:.es-query/observability/rule/getRuleState", + "alerting:.es-query/observability/rule/getAlertSummary", + "alerting:.es-query/observability/rule/getExecutionLog", + "alerting:.es-query/observability/rule/getActionErrorLog", + "alerting:.es-query/observability/rule/find", + "alerting:.es-query/observability/rule/getRuleExecutionKPI", + "alerting:.es-query/observability/rule/getBackfill", + "alerting:.es-query/observability/rule/findBackfill", + "alerting:.es-query/observability/rule/create", + "alerting:.es-query/observability/rule/delete", + "alerting:.es-query/observability/rule/update", + "alerting:.es-query/observability/rule/updateApiKey", + "alerting:.es-query/observability/rule/enable", + "alerting:.es-query/observability/rule/disable", + "alerting:.es-query/observability/rule/muteAll", + "alerting:.es-query/observability/rule/unmuteAll", + "alerting:.es-query/observability/rule/muteAlert", + "alerting:.es-query/observability/rule/unmuteAlert", + "alerting:.es-query/observability/rule/snooze", + "alerting:.es-query/observability/rule/bulkEdit", + "alerting:.es-query/observability/rule/bulkDelete", + "alerting:.es-query/observability/rule/bulkEnable", + "alerting:.es-query/observability/rule/bulkDisable", + "alerting:.es-query/observability/rule/unsnooze", + "alerting:.es-query/observability/rule/runSoon", + "alerting:.es-query/observability/rule/scheduleBackfill", + "alerting:.es-query/observability/rule/deleteBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/create", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/delete", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/update", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/updateApiKey", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/enable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/disable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/muteAll", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unmuteAll", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/muteAlert", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unmuteAlert", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/snooze", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkEdit", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkDelete", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkEnable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkDisable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unsnooze", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/runSoon", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/scheduleBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/deleteBackfill", + "alerting:apm.error_rate/observability/alert/get", + "alerting:apm.error_rate/observability/alert/find", + "alerting:apm.error_rate/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.error_rate/observability/alert/getAlertSummary", + "alerting:apm.error_rate/observability/alert/update", + "alerting:apm.transaction_error_rate/observability/alert/get", + "alerting:apm.transaction_error_rate/observability/alert/find", + "alerting:apm.transaction_error_rate/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_error_rate/observability/alert/getAlertSummary", + "alerting:apm.transaction_error_rate/observability/alert/update", + "alerting:apm.transaction_duration/observability/alert/get", + "alerting:apm.transaction_duration/observability/alert/find", + "alerting:apm.transaction_duration/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_duration/observability/alert/getAlertSummary", + "alerting:apm.transaction_duration/observability/alert/update", + "alerting:apm.anomaly/observability/alert/get", + "alerting:apm.anomaly/observability/alert/find", + "alerting:apm.anomaly/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.anomaly/observability/alert/getAlertSummary", + "alerting:apm.anomaly/observability/alert/update", + "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/get", + "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/find", + "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/getAlertSummary", + "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/update", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/get", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/find", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/getAlertSummary", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/update", + "alerting:xpack.synthetics.alerts.tls/observability/alert/get", + "alerting:xpack.synthetics.alerts.tls/observability/alert/find", + "alerting:xpack.synthetics.alerts.tls/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.synthetics.alerts.tls/observability/alert/getAlertSummary", + "alerting:xpack.synthetics.alerts.tls/observability/alert/update", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/get", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/find", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/getAlertSummary", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/update", + "alerting:metrics.alert.threshold/observability/alert/get", + "alerting:metrics.alert.threshold/observability/alert/find", + "alerting:metrics.alert.threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.threshold/observability/alert/getAlertSummary", + "alerting:metrics.alert.threshold/observability/alert/update", + "alerting:metrics.alert.threshold/alerts/alert/get", + "alerting:metrics.alert.threshold/alerts/alert/find", + "alerting:metrics.alert.threshold/alerts/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.threshold/alerts/alert/getAlertSummary", + "alerting:metrics.alert.threshold/alerts/alert/update", + "alerting:metrics.alert.inventory.threshold/observability/alert/get", + "alerting:metrics.alert.inventory.threshold/observability/alert/find", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/alert/update", + "alerting:metrics.alert.inventory.threshold/alerts/alert/get", + "alerting:metrics.alert.inventory.threshold/alerts/alert/find", + "alerting:metrics.alert.inventory.threshold/alerts/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.inventory.threshold/alerts/alert/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/alerts/alert/update", + "alerting:xpack.uptime.alerts.tls/observability/alert/get", + "alerting:xpack.uptime.alerts.tls/observability/alert/find", + "alerting:xpack.uptime.alerts.tls/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tls/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/observability/alert/update", + "alerting:xpack.uptime.alerts.tls/alerts/alert/get", + "alerting:xpack.uptime.alerts.tls/alerts/alert/find", + "alerting:xpack.uptime.alerts.tls/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tls/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/alerts/alert/update", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/get", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/find", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/update", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/get", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/find", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/update", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/get", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/find", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/update", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/get", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/find", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/update", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/get", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/find", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/update", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/get", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/find", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/update", + "alerting:logs.alert.document.count/observability/alert/get", + "alerting:logs.alert.document.count/observability/alert/find", + "alerting:logs.alert.document.count/observability/alert/getAuthorizedAlertsIndices", + "alerting:logs.alert.document.count/observability/alert/getAlertSummary", + "alerting:logs.alert.document.count/observability/alert/update", + "alerting:slo.rules.burnRate/observability/alert/get", + "alerting:slo.rules.burnRate/observability/alert/find", + "alerting:slo.rules.burnRate/observability/alert/getAuthorizedAlertsIndices", + "alerting:slo.rules.burnRate/observability/alert/getAlertSummary", + "alerting:slo.rules.burnRate/observability/alert/update", + "alerting:slo.rules.burnRate/alerts/alert/get", + "alerting:slo.rules.burnRate/alerts/alert/find", + "alerting:slo.rules.burnRate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:slo.rules.burnRate/alerts/alert/getAlertSummary", + "alerting:slo.rules.burnRate/alerts/alert/update", + "alerting:observability.rules.custom_threshold/observability/alert/get", + "alerting:observability.rules.custom_threshold/observability/alert/find", + "alerting:observability.rules.custom_threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/observability/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/alert/update", + "alerting:.es-query/observability/alert/get", + "alerting:.es-query/observability/alert/find", + "alerting:.es-query/observability/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/observability/alert/getAlertSummary", + "alerting:.es-query/observability/alert/update", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/update", + ], + "minimal_all": Array [ + "login:", + "api:apm", + "api:apm_write", + "api:rac", + "app:apm", + "app:ux", + "app:kibana", + "ui:catalogue/apm", + "ui:management/insightsAndAlerting/triggersActions", + "ui:navLinks/apm", + "ui:navLinks/ux", + "ui:navLinks/kibana", + "saved_object:telemetry/bulk_get", + "saved_object:telemetry/get", + "saved_object:telemetry/find", + "saved_object:telemetry/open_point_in_time", + "saved_object:telemetry/close_point_in_time", + "saved_object:telemetry/create", + "saved_object:telemetry/bulk_create", + "saved_object:telemetry/update", + "saved_object:telemetry/bulk_update", + "saved_object:telemetry/delete", + "saved_object:telemetry/bulk_delete", + "saved_object:telemetry/share_to_space", + "saved_object:apm-indices/bulk_get", + "saved_object:apm-indices/get", + "saved_object:apm-indices/find", + "saved_object:apm-indices/open_point_in_time", + "saved_object:apm-indices/close_point_in_time", + "saved_object:config/bulk_get", + "saved_object:config/get", + "saved_object:config/find", + "saved_object:config/open_point_in_time", + "saved_object:config/close_point_in_time", + "saved_object:config-global/bulk_get", + "saved_object:config-global/get", + "saved_object:config-global/find", + "saved_object:config-global/open_point_in_time", + "saved_object:config-global/close_point_in_time", + "saved_object:url/bulk_get", + "saved_object:url/get", + "saved_object:url/find", + "saved_object:url/open_point_in_time", + "saved_object:url/close_point_in_time", + "ui:apm/show", + "ui:apm/save", + "ui:apm/alerting:show", + "ui:apm/alerting:save", + "alerting:apm.error_rate/apm/rule/get", + "alerting:apm.error_rate/apm/rule/getRuleState", + "alerting:apm.error_rate/apm/rule/getAlertSummary", + "alerting:apm.error_rate/apm/rule/getExecutionLog", + "alerting:apm.error_rate/apm/rule/getActionErrorLog", + "alerting:apm.error_rate/apm/rule/find", + "alerting:apm.error_rate/apm/rule/getRuleExecutionKPI", + "alerting:apm.error_rate/apm/rule/getBackfill", + "alerting:apm.error_rate/apm/rule/findBackfill", + "alerting:apm.error_rate/apm/rule/create", "alerting:apm.error_rate/apm/rule/delete", "alerting:apm.error_rate/apm/rule/update", "alerting:apm.error_rate/apm/rule/updateApiKey", @@ -844,6 +1604,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.error_rate/apm/rule/runSoon", "alerting:apm.error_rate/apm/rule/scheduleBackfill", "alerting:apm.error_rate/apm/rule/deleteBackfill", + "alerting:apm.error_rate/alerts/rule/get", + "alerting:apm.error_rate/alerts/rule/getRuleState", + "alerting:apm.error_rate/alerts/rule/getAlertSummary", + "alerting:apm.error_rate/alerts/rule/getExecutionLog", + "alerting:apm.error_rate/alerts/rule/getActionErrorLog", + "alerting:apm.error_rate/alerts/rule/find", + "alerting:apm.error_rate/alerts/rule/getRuleExecutionKPI", + "alerting:apm.error_rate/alerts/rule/getBackfill", + "alerting:apm.error_rate/alerts/rule/findBackfill", + "alerting:apm.error_rate/alerts/rule/create", + "alerting:apm.error_rate/alerts/rule/delete", + "alerting:apm.error_rate/alerts/rule/update", + "alerting:apm.error_rate/alerts/rule/updateApiKey", + "alerting:apm.error_rate/alerts/rule/enable", + "alerting:apm.error_rate/alerts/rule/disable", + "alerting:apm.error_rate/alerts/rule/muteAll", + "alerting:apm.error_rate/alerts/rule/unmuteAll", + "alerting:apm.error_rate/alerts/rule/muteAlert", + "alerting:apm.error_rate/alerts/rule/unmuteAlert", + "alerting:apm.error_rate/alerts/rule/snooze", + "alerting:apm.error_rate/alerts/rule/bulkEdit", + "alerting:apm.error_rate/alerts/rule/bulkDelete", + "alerting:apm.error_rate/alerts/rule/bulkEnable", + "alerting:apm.error_rate/alerts/rule/bulkDisable", + "alerting:apm.error_rate/alerts/rule/unsnooze", + "alerting:apm.error_rate/alerts/rule/runSoon", + "alerting:apm.error_rate/alerts/rule/scheduleBackfill", + "alerting:apm.error_rate/alerts/rule/deleteBackfill", "alerting:apm.transaction_error_rate/apm/rule/get", "alerting:apm.transaction_error_rate/apm/rule/getRuleState", "alerting:apm.transaction_error_rate/apm/rule/getAlertSummary", @@ -872,6 +1660,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.transaction_error_rate/apm/rule/runSoon", "alerting:apm.transaction_error_rate/apm/rule/scheduleBackfill", "alerting:apm.transaction_error_rate/apm/rule/deleteBackfill", + "alerting:apm.transaction_error_rate/alerts/rule/get", + "alerting:apm.transaction_error_rate/alerts/rule/getRuleState", + "alerting:apm.transaction_error_rate/alerts/rule/getAlertSummary", + "alerting:apm.transaction_error_rate/alerts/rule/getExecutionLog", + "alerting:apm.transaction_error_rate/alerts/rule/getActionErrorLog", + "alerting:apm.transaction_error_rate/alerts/rule/find", + "alerting:apm.transaction_error_rate/alerts/rule/getRuleExecutionKPI", + "alerting:apm.transaction_error_rate/alerts/rule/getBackfill", + "alerting:apm.transaction_error_rate/alerts/rule/findBackfill", + "alerting:apm.transaction_error_rate/alerts/rule/create", + "alerting:apm.transaction_error_rate/alerts/rule/delete", + "alerting:apm.transaction_error_rate/alerts/rule/update", + "alerting:apm.transaction_error_rate/alerts/rule/updateApiKey", + "alerting:apm.transaction_error_rate/alerts/rule/enable", + "alerting:apm.transaction_error_rate/alerts/rule/disable", + "alerting:apm.transaction_error_rate/alerts/rule/muteAll", + "alerting:apm.transaction_error_rate/alerts/rule/unmuteAll", + "alerting:apm.transaction_error_rate/alerts/rule/muteAlert", + "alerting:apm.transaction_error_rate/alerts/rule/unmuteAlert", + "alerting:apm.transaction_error_rate/alerts/rule/snooze", + "alerting:apm.transaction_error_rate/alerts/rule/bulkEdit", + "alerting:apm.transaction_error_rate/alerts/rule/bulkDelete", + "alerting:apm.transaction_error_rate/alerts/rule/bulkEnable", + "alerting:apm.transaction_error_rate/alerts/rule/bulkDisable", + "alerting:apm.transaction_error_rate/alerts/rule/unsnooze", + "alerting:apm.transaction_error_rate/alerts/rule/runSoon", + "alerting:apm.transaction_error_rate/alerts/rule/scheduleBackfill", + "alerting:apm.transaction_error_rate/alerts/rule/deleteBackfill", "alerting:apm.transaction_duration/apm/rule/get", "alerting:apm.transaction_duration/apm/rule/getRuleState", "alerting:apm.transaction_duration/apm/rule/getAlertSummary", @@ -900,6 +1716,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.transaction_duration/apm/rule/runSoon", "alerting:apm.transaction_duration/apm/rule/scheduleBackfill", "alerting:apm.transaction_duration/apm/rule/deleteBackfill", + "alerting:apm.transaction_duration/alerts/rule/get", + "alerting:apm.transaction_duration/alerts/rule/getRuleState", + "alerting:apm.transaction_duration/alerts/rule/getAlertSummary", + "alerting:apm.transaction_duration/alerts/rule/getExecutionLog", + "alerting:apm.transaction_duration/alerts/rule/getActionErrorLog", + "alerting:apm.transaction_duration/alerts/rule/find", + "alerting:apm.transaction_duration/alerts/rule/getRuleExecutionKPI", + "alerting:apm.transaction_duration/alerts/rule/getBackfill", + "alerting:apm.transaction_duration/alerts/rule/findBackfill", + "alerting:apm.transaction_duration/alerts/rule/create", + "alerting:apm.transaction_duration/alerts/rule/delete", + "alerting:apm.transaction_duration/alerts/rule/update", + "alerting:apm.transaction_duration/alerts/rule/updateApiKey", + "alerting:apm.transaction_duration/alerts/rule/enable", + "alerting:apm.transaction_duration/alerts/rule/disable", + "alerting:apm.transaction_duration/alerts/rule/muteAll", + "alerting:apm.transaction_duration/alerts/rule/unmuteAll", + "alerting:apm.transaction_duration/alerts/rule/muteAlert", + "alerting:apm.transaction_duration/alerts/rule/unmuteAlert", + "alerting:apm.transaction_duration/alerts/rule/snooze", + "alerting:apm.transaction_duration/alerts/rule/bulkEdit", + "alerting:apm.transaction_duration/alerts/rule/bulkDelete", + "alerting:apm.transaction_duration/alerts/rule/bulkEnable", + "alerting:apm.transaction_duration/alerts/rule/bulkDisable", + "alerting:apm.transaction_duration/alerts/rule/unsnooze", + "alerting:apm.transaction_duration/alerts/rule/runSoon", + "alerting:apm.transaction_duration/alerts/rule/scheduleBackfill", + "alerting:apm.transaction_duration/alerts/rule/deleteBackfill", "alerting:apm.anomaly/apm/rule/get", "alerting:apm.anomaly/apm/rule/getRuleState", "alerting:apm.anomaly/apm/rule/getAlertSummary", @@ -928,26 +1772,74 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.anomaly/apm/rule/runSoon", "alerting:apm.anomaly/apm/rule/scheduleBackfill", "alerting:apm.anomaly/apm/rule/deleteBackfill", + "alerting:apm.anomaly/alerts/rule/get", + "alerting:apm.anomaly/alerts/rule/getRuleState", + "alerting:apm.anomaly/alerts/rule/getAlertSummary", + "alerting:apm.anomaly/alerts/rule/getExecutionLog", + "alerting:apm.anomaly/alerts/rule/getActionErrorLog", + "alerting:apm.anomaly/alerts/rule/find", + "alerting:apm.anomaly/alerts/rule/getRuleExecutionKPI", + "alerting:apm.anomaly/alerts/rule/getBackfill", + "alerting:apm.anomaly/alerts/rule/findBackfill", + "alerting:apm.anomaly/alerts/rule/create", + "alerting:apm.anomaly/alerts/rule/delete", + "alerting:apm.anomaly/alerts/rule/update", + "alerting:apm.anomaly/alerts/rule/updateApiKey", + "alerting:apm.anomaly/alerts/rule/enable", + "alerting:apm.anomaly/alerts/rule/disable", + "alerting:apm.anomaly/alerts/rule/muteAll", + "alerting:apm.anomaly/alerts/rule/unmuteAll", + "alerting:apm.anomaly/alerts/rule/muteAlert", + "alerting:apm.anomaly/alerts/rule/unmuteAlert", + "alerting:apm.anomaly/alerts/rule/snooze", + "alerting:apm.anomaly/alerts/rule/bulkEdit", + "alerting:apm.anomaly/alerts/rule/bulkDelete", + "alerting:apm.anomaly/alerts/rule/bulkEnable", + "alerting:apm.anomaly/alerts/rule/bulkDisable", + "alerting:apm.anomaly/alerts/rule/unsnooze", + "alerting:apm.anomaly/alerts/rule/runSoon", + "alerting:apm.anomaly/alerts/rule/scheduleBackfill", + "alerting:apm.anomaly/alerts/rule/deleteBackfill", "alerting:apm.error_rate/apm/alert/get", "alerting:apm.error_rate/apm/alert/find", "alerting:apm.error_rate/apm/alert/getAuthorizedAlertsIndices", "alerting:apm.error_rate/apm/alert/getAlertSummary", "alerting:apm.error_rate/apm/alert/update", + "alerting:apm.error_rate/alerts/alert/get", + "alerting:apm.error_rate/alerts/alert/find", + "alerting:apm.error_rate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.error_rate/alerts/alert/getAlertSummary", + "alerting:apm.error_rate/alerts/alert/update", "alerting:apm.transaction_error_rate/apm/alert/get", "alerting:apm.transaction_error_rate/apm/alert/find", "alerting:apm.transaction_error_rate/apm/alert/getAuthorizedAlertsIndices", "alerting:apm.transaction_error_rate/apm/alert/getAlertSummary", "alerting:apm.transaction_error_rate/apm/alert/update", + "alerting:apm.transaction_error_rate/alerts/alert/get", + "alerting:apm.transaction_error_rate/alerts/alert/find", + "alerting:apm.transaction_error_rate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_error_rate/alerts/alert/getAlertSummary", + "alerting:apm.transaction_error_rate/alerts/alert/update", "alerting:apm.transaction_duration/apm/alert/get", "alerting:apm.transaction_duration/apm/alert/find", "alerting:apm.transaction_duration/apm/alert/getAuthorizedAlertsIndices", "alerting:apm.transaction_duration/apm/alert/getAlertSummary", "alerting:apm.transaction_duration/apm/alert/update", + "alerting:apm.transaction_duration/alerts/alert/get", + "alerting:apm.transaction_duration/alerts/alert/find", + "alerting:apm.transaction_duration/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_duration/alerts/alert/getAlertSummary", + "alerting:apm.transaction_duration/alerts/alert/update", "alerting:apm.anomaly/apm/alert/get", "alerting:apm.anomaly/apm/alert/find", "alerting:apm.anomaly/apm/alert/getAuthorizedAlertsIndices", "alerting:apm.anomaly/apm/alert/getAlertSummary", "alerting:apm.anomaly/apm/alert/update", + "alerting:apm.anomaly/alerts/alert/get", + "alerting:apm.anomaly/alerts/alert/find", + "alerting:apm.anomaly/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.anomaly/alerts/alert/getAlertSummary", + "alerting:apm.anomaly/alerts/alert/update", "api:infra", "app:infra", "app:logs", @@ -1012,6 +1904,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:logs.alert.document.count/logs/rule/runSoon", "alerting:logs.alert.document.count/logs/rule/scheduleBackfill", "alerting:logs.alert.document.count/logs/rule/deleteBackfill", + "alerting:logs.alert.document.count/alerts/rule/get", + "alerting:logs.alert.document.count/alerts/rule/getRuleState", + "alerting:logs.alert.document.count/alerts/rule/getAlertSummary", + "alerting:logs.alert.document.count/alerts/rule/getExecutionLog", + "alerting:logs.alert.document.count/alerts/rule/getActionErrorLog", + "alerting:logs.alert.document.count/alerts/rule/find", + "alerting:logs.alert.document.count/alerts/rule/getRuleExecutionKPI", + "alerting:logs.alert.document.count/alerts/rule/getBackfill", + "alerting:logs.alert.document.count/alerts/rule/findBackfill", + "alerting:logs.alert.document.count/alerts/rule/create", + "alerting:logs.alert.document.count/alerts/rule/delete", + "alerting:logs.alert.document.count/alerts/rule/update", + "alerting:logs.alert.document.count/alerts/rule/updateApiKey", + "alerting:logs.alert.document.count/alerts/rule/enable", + "alerting:logs.alert.document.count/alerts/rule/disable", + "alerting:logs.alert.document.count/alerts/rule/muteAll", + "alerting:logs.alert.document.count/alerts/rule/unmuteAll", + "alerting:logs.alert.document.count/alerts/rule/muteAlert", + "alerting:logs.alert.document.count/alerts/rule/unmuteAlert", + "alerting:logs.alert.document.count/alerts/rule/snooze", + "alerting:logs.alert.document.count/alerts/rule/bulkEdit", + "alerting:logs.alert.document.count/alerts/rule/bulkDelete", + "alerting:logs.alert.document.count/alerts/rule/bulkEnable", + "alerting:logs.alert.document.count/alerts/rule/bulkDisable", + "alerting:logs.alert.document.count/alerts/rule/unsnooze", + "alerting:logs.alert.document.count/alerts/rule/runSoon", + "alerting:logs.alert.document.count/alerts/rule/scheduleBackfill", + "alerting:logs.alert.document.count/alerts/rule/deleteBackfill", "alerting:.es-query/logs/rule/get", "alerting:.es-query/logs/rule/getRuleState", "alerting:.es-query/logs/rule/getAlertSummary", @@ -1040,6 +1960,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:.es-query/logs/rule/runSoon", "alerting:.es-query/logs/rule/scheduleBackfill", "alerting:.es-query/logs/rule/deleteBackfill", + "alerting:.es-query/alerts/rule/get", + "alerting:.es-query/alerts/rule/getRuleState", + "alerting:.es-query/alerts/rule/getAlertSummary", + "alerting:.es-query/alerts/rule/getExecutionLog", + "alerting:.es-query/alerts/rule/getActionErrorLog", + "alerting:.es-query/alerts/rule/find", + "alerting:.es-query/alerts/rule/getRuleExecutionKPI", + "alerting:.es-query/alerts/rule/getBackfill", + "alerting:.es-query/alerts/rule/findBackfill", + "alerting:.es-query/alerts/rule/create", + "alerting:.es-query/alerts/rule/delete", + "alerting:.es-query/alerts/rule/update", + "alerting:.es-query/alerts/rule/updateApiKey", + "alerting:.es-query/alerts/rule/enable", + "alerting:.es-query/alerts/rule/disable", + "alerting:.es-query/alerts/rule/muteAll", + "alerting:.es-query/alerts/rule/unmuteAll", + "alerting:.es-query/alerts/rule/muteAlert", + "alerting:.es-query/alerts/rule/unmuteAlert", + "alerting:.es-query/alerts/rule/snooze", + "alerting:.es-query/alerts/rule/bulkEdit", + "alerting:.es-query/alerts/rule/bulkDelete", + "alerting:.es-query/alerts/rule/bulkEnable", + "alerting:.es-query/alerts/rule/bulkDisable", + "alerting:.es-query/alerts/rule/unsnooze", + "alerting:.es-query/alerts/rule/runSoon", + "alerting:.es-query/alerts/rule/scheduleBackfill", + "alerting:.es-query/alerts/rule/deleteBackfill", "alerting:observability.rules.custom_threshold/logs/rule/get", "alerting:observability.rules.custom_threshold/logs/rule/getRuleState", "alerting:observability.rules.custom_threshold/logs/rule/getAlertSummary", @@ -1068,6 +2016,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:observability.rules.custom_threshold/logs/rule/runSoon", "alerting:observability.rules.custom_threshold/logs/rule/scheduleBackfill", "alerting:observability.rules.custom_threshold/logs/rule/deleteBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/get", + "alerting:observability.rules.custom_threshold/alerts/rule/getRuleState", + "alerting:observability.rules.custom_threshold/alerts/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/alerts/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/alerts/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/alerts/rule/find", + "alerting:observability.rules.custom_threshold/alerts/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/alerts/rule/getBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/findBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/create", + "alerting:observability.rules.custom_threshold/alerts/rule/delete", + "alerting:observability.rules.custom_threshold/alerts/rule/update", + "alerting:observability.rules.custom_threshold/alerts/rule/updateApiKey", + "alerting:observability.rules.custom_threshold/alerts/rule/enable", + "alerting:observability.rules.custom_threshold/alerts/rule/disable", + "alerting:observability.rules.custom_threshold/alerts/rule/muteAll", + "alerting:observability.rules.custom_threshold/alerts/rule/unmuteAll", + "alerting:observability.rules.custom_threshold/alerts/rule/muteAlert", + "alerting:observability.rules.custom_threshold/alerts/rule/unmuteAlert", + "alerting:observability.rules.custom_threshold/alerts/rule/snooze", + "alerting:observability.rules.custom_threshold/alerts/rule/bulkEdit", + "alerting:observability.rules.custom_threshold/alerts/rule/bulkDelete", + "alerting:observability.rules.custom_threshold/alerts/rule/bulkEnable", + "alerting:observability.rules.custom_threshold/alerts/rule/bulkDisable", + "alerting:observability.rules.custom_threshold/alerts/rule/unsnooze", + "alerting:observability.rules.custom_threshold/alerts/rule/runSoon", + "alerting:observability.rules.custom_threshold/alerts/rule/scheduleBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/deleteBackfill", "alerting:xpack.ml.anomaly_detection_alert/logs/rule/get", "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getRuleState", "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getAlertSummary", @@ -1096,171 +2072,79 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.ml.anomaly_detection_alert/logs/rule/runSoon", "alerting:xpack.ml.anomaly_detection_alert/logs/rule/scheduleBackfill", "alerting:xpack.ml.anomaly_detection_alert/logs/rule/deleteBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/create", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/delete", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/update", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/updateApiKey", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/enable", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/disable", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/muteAll", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/unmuteAll", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/muteAlert", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/unmuteAlert", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/snooze", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/bulkEdit", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/bulkDelete", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/bulkEnable", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/bulkDisable", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/unsnooze", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/runSoon", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/scheduleBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/deleteBackfill", "alerting:logs.alert.document.count/logs/alert/get", "alerting:logs.alert.document.count/logs/alert/find", "alerting:logs.alert.document.count/logs/alert/getAuthorizedAlertsIndices", "alerting:logs.alert.document.count/logs/alert/getAlertSummary", "alerting:logs.alert.document.count/logs/alert/update", + "alerting:logs.alert.document.count/alerts/alert/get", + "alerting:logs.alert.document.count/alerts/alert/find", + "alerting:logs.alert.document.count/alerts/alert/getAuthorizedAlertsIndices", + "alerting:logs.alert.document.count/alerts/alert/getAlertSummary", + "alerting:logs.alert.document.count/alerts/alert/update", "alerting:.es-query/logs/alert/get", "alerting:.es-query/logs/alert/find", "alerting:.es-query/logs/alert/getAuthorizedAlertsIndices", "alerting:.es-query/logs/alert/getAlertSummary", "alerting:.es-query/logs/alert/update", + "alerting:.es-query/alerts/alert/get", + "alerting:.es-query/alerts/alert/find", + "alerting:.es-query/alerts/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/alerts/alert/getAlertSummary", + "alerting:.es-query/alerts/alert/update", "alerting:observability.rules.custom_threshold/logs/alert/get", "alerting:observability.rules.custom_threshold/logs/alert/find", "alerting:observability.rules.custom_threshold/logs/alert/getAuthorizedAlertsIndices", "alerting:observability.rules.custom_threshold/logs/alert/getAlertSummary", "alerting:observability.rules.custom_threshold/logs/alert/update", + "alerting:observability.rules.custom_threshold/alerts/alert/get", + "alerting:observability.rules.custom_threshold/alerts/alert/find", + "alerting:observability.rules.custom_threshold/alerts/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/alerts/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/alerts/alert/update", "alerting:xpack.ml.anomaly_detection_alert/logs/alert/get", "alerting:xpack.ml.anomaly_detection_alert/logs/alert/find", "alerting:xpack.ml.anomaly_detection_alert/logs/alert/getAuthorizedAlertsIndices", "alerting:xpack.ml.anomaly_detection_alert/logs/alert/getAlertSummary", "alerting:xpack.ml.anomaly_detection_alert/logs/alert/update", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/update", "app:observability", "ui:catalogue/observability", "ui:navLinks/observability", "ui:observability/read", "ui:observability/write", - "alerting:slo.rules.burnRate/observability/rule/get", - "alerting:slo.rules.burnRate/observability/rule/getRuleState", - "alerting:slo.rules.burnRate/observability/rule/getAlertSummary", - "alerting:slo.rules.burnRate/observability/rule/getExecutionLog", - "alerting:slo.rules.burnRate/observability/rule/getActionErrorLog", - "alerting:slo.rules.burnRate/observability/rule/find", - "alerting:slo.rules.burnRate/observability/rule/getRuleExecutionKPI", - "alerting:slo.rules.burnRate/observability/rule/getBackfill", - "alerting:slo.rules.burnRate/observability/rule/findBackfill", - "alerting:slo.rules.burnRate/observability/rule/create", - "alerting:slo.rules.burnRate/observability/rule/delete", - "alerting:slo.rules.burnRate/observability/rule/update", - "alerting:slo.rules.burnRate/observability/rule/updateApiKey", - "alerting:slo.rules.burnRate/observability/rule/enable", - "alerting:slo.rules.burnRate/observability/rule/disable", - "alerting:slo.rules.burnRate/observability/rule/muteAll", - "alerting:slo.rules.burnRate/observability/rule/unmuteAll", - "alerting:slo.rules.burnRate/observability/rule/muteAlert", - "alerting:slo.rules.burnRate/observability/rule/unmuteAlert", - "alerting:slo.rules.burnRate/observability/rule/snooze", - "alerting:slo.rules.burnRate/observability/rule/bulkEdit", - "alerting:slo.rules.burnRate/observability/rule/bulkDelete", - "alerting:slo.rules.burnRate/observability/rule/bulkEnable", - "alerting:slo.rules.burnRate/observability/rule/bulkDisable", - "alerting:slo.rules.burnRate/observability/rule/unsnooze", - "alerting:slo.rules.burnRate/observability/rule/runSoon", - "alerting:slo.rules.burnRate/observability/rule/scheduleBackfill", - "alerting:slo.rules.burnRate/observability/rule/deleteBackfill", - "alerting:observability.rules.custom_threshold/observability/rule/get", - "alerting:observability.rules.custom_threshold/observability/rule/getRuleState", - "alerting:observability.rules.custom_threshold/observability/rule/getAlertSummary", - "alerting:observability.rules.custom_threshold/observability/rule/getExecutionLog", - "alerting:observability.rules.custom_threshold/observability/rule/getActionErrorLog", - "alerting:observability.rules.custom_threshold/observability/rule/find", - "alerting:observability.rules.custom_threshold/observability/rule/getRuleExecutionKPI", - "alerting:observability.rules.custom_threshold/observability/rule/getBackfill", - "alerting:observability.rules.custom_threshold/observability/rule/findBackfill", - "alerting:observability.rules.custom_threshold/observability/rule/create", - "alerting:observability.rules.custom_threshold/observability/rule/delete", - "alerting:observability.rules.custom_threshold/observability/rule/update", - "alerting:observability.rules.custom_threshold/observability/rule/updateApiKey", - "alerting:observability.rules.custom_threshold/observability/rule/enable", - "alerting:observability.rules.custom_threshold/observability/rule/disable", - "alerting:observability.rules.custom_threshold/observability/rule/muteAll", - "alerting:observability.rules.custom_threshold/observability/rule/unmuteAll", - "alerting:observability.rules.custom_threshold/observability/rule/muteAlert", - "alerting:observability.rules.custom_threshold/observability/rule/unmuteAlert", - "alerting:observability.rules.custom_threshold/observability/rule/snooze", - "alerting:observability.rules.custom_threshold/observability/rule/bulkEdit", - "alerting:observability.rules.custom_threshold/observability/rule/bulkDelete", - "alerting:observability.rules.custom_threshold/observability/rule/bulkEnable", - "alerting:observability.rules.custom_threshold/observability/rule/bulkDisable", - "alerting:observability.rules.custom_threshold/observability/rule/unsnooze", - "alerting:observability.rules.custom_threshold/observability/rule/runSoon", - "alerting:observability.rules.custom_threshold/observability/rule/scheduleBackfill", - "alerting:observability.rules.custom_threshold/observability/rule/deleteBackfill", - "alerting:.es-query/observability/rule/get", - "alerting:.es-query/observability/rule/getRuleState", - "alerting:.es-query/observability/rule/getAlertSummary", - "alerting:.es-query/observability/rule/getExecutionLog", - "alerting:.es-query/observability/rule/getActionErrorLog", - "alerting:.es-query/observability/rule/find", - "alerting:.es-query/observability/rule/getRuleExecutionKPI", - "alerting:.es-query/observability/rule/getBackfill", - "alerting:.es-query/observability/rule/findBackfill", - "alerting:.es-query/observability/rule/create", - "alerting:.es-query/observability/rule/delete", - "alerting:.es-query/observability/rule/update", - "alerting:.es-query/observability/rule/updateApiKey", - "alerting:.es-query/observability/rule/enable", - "alerting:.es-query/observability/rule/disable", - "alerting:.es-query/observability/rule/muteAll", - "alerting:.es-query/observability/rule/unmuteAll", - "alerting:.es-query/observability/rule/muteAlert", - "alerting:.es-query/observability/rule/unmuteAlert", - "alerting:.es-query/observability/rule/snooze", - "alerting:.es-query/observability/rule/bulkEdit", - "alerting:.es-query/observability/rule/bulkDelete", - "alerting:.es-query/observability/rule/bulkEnable", - "alerting:.es-query/observability/rule/bulkDisable", - "alerting:.es-query/observability/rule/unsnooze", - "alerting:.es-query/observability/rule/runSoon", - "alerting:.es-query/observability/rule/scheduleBackfill", - "alerting:.es-query/observability/rule/deleteBackfill", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/get", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleState", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getAlertSummary", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getExecutionLog", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getActionErrorLog", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/find", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleExecutionKPI", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getBackfill", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/findBackfill", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/create", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/delete", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/update", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/updateApiKey", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/enable", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/disable", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/muteAll", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unmuteAll", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/muteAlert", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unmuteAlert", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/snooze", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkEdit", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkDelete", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkEnable", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkDisable", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unsnooze", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/runSoon", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/scheduleBackfill", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/deleteBackfill", - "alerting:metrics.alert.inventory.threshold/observability/rule/get", - "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleState", - "alerting:metrics.alert.inventory.threshold/observability/rule/getAlertSummary", - "alerting:metrics.alert.inventory.threshold/observability/rule/getExecutionLog", - "alerting:metrics.alert.inventory.threshold/observability/rule/getActionErrorLog", - "alerting:metrics.alert.inventory.threshold/observability/rule/find", - "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleExecutionKPI", - "alerting:metrics.alert.inventory.threshold/observability/rule/getBackfill", - "alerting:metrics.alert.inventory.threshold/observability/rule/findBackfill", - "alerting:metrics.alert.inventory.threshold/observability/rule/create", - "alerting:metrics.alert.inventory.threshold/observability/rule/delete", - "alerting:metrics.alert.inventory.threshold/observability/rule/update", - "alerting:metrics.alert.inventory.threshold/observability/rule/updateApiKey", - "alerting:metrics.alert.inventory.threshold/observability/rule/enable", - "alerting:metrics.alert.inventory.threshold/observability/rule/disable", - "alerting:metrics.alert.inventory.threshold/observability/rule/muteAll", - "alerting:metrics.alert.inventory.threshold/observability/rule/unmuteAll", - "alerting:metrics.alert.inventory.threshold/observability/rule/muteAlert", - "alerting:metrics.alert.inventory.threshold/observability/rule/unmuteAlert", - "alerting:metrics.alert.inventory.threshold/observability/rule/snooze", - "alerting:metrics.alert.inventory.threshold/observability/rule/bulkEdit", - "alerting:metrics.alert.inventory.threshold/observability/rule/bulkDelete", - "alerting:metrics.alert.inventory.threshold/observability/rule/bulkEnable", - "alerting:metrics.alert.inventory.threshold/observability/rule/bulkDisable", - "alerting:metrics.alert.inventory.threshold/observability/rule/unsnooze", - "alerting:metrics.alert.inventory.threshold/observability/rule/runSoon", - "alerting:metrics.alert.inventory.threshold/observability/rule/scheduleBackfill", - "alerting:metrics.alert.inventory.threshold/observability/rule/deleteBackfill", "alerting:apm.error_rate/observability/rule/get", "alerting:apm.error_rate/observability/rule/getRuleState", "alerting:apm.error_rate/observability/rule/getAlertSummary", @@ -1401,6 +2285,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/runSoon", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/scheduleBackfill", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/deleteBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/get", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getRuleState", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getAlertSummary", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getExecutionLog", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getActionErrorLog", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/find", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/findBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/create", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/delete", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/update", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/updateApiKey", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/enable", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/disable", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/muteAll", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/unmuteAll", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/muteAlert", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/unmuteAlert", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/snooze", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/bulkEdit", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/bulkDelete", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/bulkEnable", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/bulkDisable", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/unsnooze", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/runSoon", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/scheduleBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/deleteBackfill", "alerting:xpack.synthetics.alerts.tls/observability/rule/get", "alerting:xpack.synthetics.alerts.tls/observability/rule/getRuleState", "alerting:xpack.synthetics.alerts.tls/observability/rule/getAlertSummary", @@ -1429,128 +2341,762 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.synthetics.alerts.tls/observability/rule/runSoon", "alerting:xpack.synthetics.alerts.tls/observability/rule/scheduleBackfill", "alerting:xpack.synthetics.alerts.tls/observability/rule/deleteBackfill", - "alerting:slo.rules.burnRate/observability/alert/get", - "alerting:slo.rules.burnRate/observability/alert/find", - "alerting:slo.rules.burnRate/observability/alert/getAuthorizedAlertsIndices", - "alerting:slo.rules.burnRate/observability/alert/getAlertSummary", - "alerting:slo.rules.burnRate/observability/alert/update", - "alerting:observability.rules.custom_threshold/observability/alert/get", - "alerting:observability.rules.custom_threshold/observability/alert/find", - "alerting:observability.rules.custom_threshold/observability/alert/getAuthorizedAlertsIndices", - "alerting:observability.rules.custom_threshold/observability/alert/getAlertSummary", - "alerting:observability.rules.custom_threshold/observability/alert/update", - "alerting:.es-query/observability/alert/get", - "alerting:.es-query/observability/alert/find", - "alerting:.es-query/observability/alert/getAuthorizedAlertsIndices", - "alerting:.es-query/observability/alert/getAlertSummary", - "alerting:.es-query/observability/alert/update", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/get", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/find", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAuthorizedAlertsIndices", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAlertSummary", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/update", - "alerting:metrics.alert.inventory.threshold/observability/alert/get", - "alerting:metrics.alert.inventory.threshold/observability/alert/find", - "alerting:metrics.alert.inventory.threshold/observability/alert/getAuthorizedAlertsIndices", - "alerting:metrics.alert.inventory.threshold/observability/alert/getAlertSummary", - "alerting:metrics.alert.inventory.threshold/observability/alert/update", - "alerting:apm.error_rate/observability/alert/get", - "alerting:apm.error_rate/observability/alert/find", - "alerting:apm.error_rate/observability/alert/getAuthorizedAlertsIndices", - "alerting:apm.error_rate/observability/alert/getAlertSummary", - "alerting:apm.error_rate/observability/alert/update", - "alerting:apm.transaction_error_rate/observability/alert/get", - "alerting:apm.transaction_error_rate/observability/alert/find", - "alerting:apm.transaction_error_rate/observability/alert/getAuthorizedAlertsIndices", - "alerting:apm.transaction_error_rate/observability/alert/getAlertSummary", - "alerting:apm.transaction_error_rate/observability/alert/update", - "alerting:apm.transaction_duration/observability/alert/get", - "alerting:apm.transaction_duration/observability/alert/find", - "alerting:apm.transaction_duration/observability/alert/getAuthorizedAlertsIndices", - "alerting:apm.transaction_duration/observability/alert/getAlertSummary", - "alerting:apm.transaction_duration/observability/alert/update", - "alerting:apm.anomaly/observability/alert/get", - "alerting:apm.anomaly/observability/alert/find", - "alerting:apm.anomaly/observability/alert/getAuthorizedAlertsIndices", - "alerting:apm.anomaly/observability/alert/getAlertSummary", - "alerting:apm.anomaly/observability/alert/update", - "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/get", - "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/find", - "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/getAuthorizedAlertsIndices", - "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/getAlertSummary", - "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/update", - "alerting:xpack.synthetics.alerts.tls/observability/alert/get", - "alerting:xpack.synthetics.alerts.tls/observability/alert/find", - "alerting:xpack.synthetics.alerts.tls/observability/alert/getAuthorizedAlertsIndices", - "alerting:xpack.synthetics.alerts.tls/observability/alert/getAlertSummary", - "alerting:xpack.synthetics.alerts.tls/observability/alert/update", - ], - "minimal_read": Array [ - "login:", - "api:apm", - "api:rac", - "app:apm", - "app:ux", - "app:kibana", - "ui:catalogue/apm", - "ui:management/insightsAndAlerting/triggersActions", - "ui:navLinks/apm", - "ui:navLinks/ux", - "ui:navLinks/kibana", - "saved_object:apm-indices/bulk_get", - "saved_object:apm-indices/get", - "saved_object:apm-indices/find", - "saved_object:apm-indices/open_point_in_time", - "saved_object:apm-indices/close_point_in_time", - "saved_object:config/bulk_get", - "saved_object:config/get", - "saved_object:config/find", - "saved_object:config/open_point_in_time", - "saved_object:config/close_point_in_time", - "saved_object:config-global/bulk_get", - "saved_object:config-global/get", - "saved_object:config-global/find", - "saved_object:config-global/open_point_in_time", - "saved_object:config-global/close_point_in_time", - "saved_object:telemetry/bulk_get", - "saved_object:telemetry/get", - "saved_object:telemetry/find", - "saved_object:telemetry/open_point_in_time", - "saved_object:telemetry/close_point_in_time", - "saved_object:url/bulk_get", - "saved_object:url/get", - "saved_object:url/find", - "saved_object:url/open_point_in_time", - "saved_object:url/close_point_in_time", - "ui:apm/show", - "ui:apm/alerting:show", - "alerting:apm.error_rate/apm/rule/get", - "alerting:apm.error_rate/apm/rule/getRuleState", - "alerting:apm.error_rate/apm/rule/getAlertSummary", - "alerting:apm.error_rate/apm/rule/getExecutionLog", - "alerting:apm.error_rate/apm/rule/getActionErrorLog", - "alerting:apm.error_rate/apm/rule/find", - "alerting:apm.error_rate/apm/rule/getRuleExecutionKPI", - "alerting:apm.error_rate/apm/rule/getBackfill", - "alerting:apm.error_rate/apm/rule/findBackfill", - "alerting:apm.transaction_error_rate/apm/rule/get", - "alerting:apm.transaction_error_rate/apm/rule/getRuleState", - "alerting:apm.transaction_error_rate/apm/rule/getAlertSummary", - "alerting:apm.transaction_error_rate/apm/rule/getExecutionLog", - "alerting:apm.transaction_error_rate/apm/rule/getActionErrorLog", - "alerting:apm.transaction_error_rate/apm/rule/find", - "alerting:apm.transaction_error_rate/apm/rule/getRuleExecutionKPI", - "alerting:apm.transaction_error_rate/apm/rule/getBackfill", - "alerting:apm.transaction_error_rate/apm/rule/findBackfill", - "alerting:apm.transaction_duration/apm/rule/get", - "alerting:apm.transaction_duration/apm/rule/getRuleState", - "alerting:apm.transaction_duration/apm/rule/getAlertSummary", - "alerting:apm.transaction_duration/apm/rule/getExecutionLog", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/get", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getRuleState", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getAlertSummary", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getExecutionLog", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getActionErrorLog", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/find", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getBackfill", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/findBackfill", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/create", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/delete", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/update", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/updateApiKey", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/enable", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/disable", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/muteAll", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/unmuteAll", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/muteAlert", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/unmuteAlert", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/snooze", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/bulkEdit", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/bulkDelete", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/bulkEnable", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/bulkDisable", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/unsnooze", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/runSoon", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/scheduleBackfill", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/deleteBackfill", + "alerting:metrics.alert.threshold/observability/rule/get", + "alerting:metrics.alert.threshold/observability/rule/getRuleState", + "alerting:metrics.alert.threshold/observability/rule/getAlertSummary", + "alerting:metrics.alert.threshold/observability/rule/getExecutionLog", + "alerting:metrics.alert.threshold/observability/rule/getActionErrorLog", + "alerting:metrics.alert.threshold/observability/rule/find", + "alerting:metrics.alert.threshold/observability/rule/getRuleExecutionKPI", + "alerting:metrics.alert.threshold/observability/rule/getBackfill", + "alerting:metrics.alert.threshold/observability/rule/findBackfill", + "alerting:metrics.alert.threshold/observability/rule/create", + "alerting:metrics.alert.threshold/observability/rule/delete", + "alerting:metrics.alert.threshold/observability/rule/update", + "alerting:metrics.alert.threshold/observability/rule/updateApiKey", + "alerting:metrics.alert.threshold/observability/rule/enable", + "alerting:metrics.alert.threshold/observability/rule/disable", + "alerting:metrics.alert.threshold/observability/rule/muteAll", + "alerting:metrics.alert.threshold/observability/rule/unmuteAll", + "alerting:metrics.alert.threshold/observability/rule/muteAlert", + "alerting:metrics.alert.threshold/observability/rule/unmuteAlert", + "alerting:metrics.alert.threshold/observability/rule/snooze", + "alerting:metrics.alert.threshold/observability/rule/bulkEdit", + "alerting:metrics.alert.threshold/observability/rule/bulkDelete", + "alerting:metrics.alert.threshold/observability/rule/bulkEnable", + "alerting:metrics.alert.threshold/observability/rule/bulkDisable", + "alerting:metrics.alert.threshold/observability/rule/unsnooze", + "alerting:metrics.alert.threshold/observability/rule/runSoon", + "alerting:metrics.alert.threshold/observability/rule/scheduleBackfill", + "alerting:metrics.alert.threshold/observability/rule/deleteBackfill", + "alerting:metrics.alert.threshold/alerts/rule/get", + "alerting:metrics.alert.threshold/alerts/rule/getRuleState", + "alerting:metrics.alert.threshold/alerts/rule/getAlertSummary", + "alerting:metrics.alert.threshold/alerts/rule/getExecutionLog", + "alerting:metrics.alert.threshold/alerts/rule/getActionErrorLog", + "alerting:metrics.alert.threshold/alerts/rule/find", + "alerting:metrics.alert.threshold/alerts/rule/getRuleExecutionKPI", + "alerting:metrics.alert.threshold/alerts/rule/getBackfill", + "alerting:metrics.alert.threshold/alerts/rule/findBackfill", + "alerting:metrics.alert.threshold/alerts/rule/create", + "alerting:metrics.alert.threshold/alerts/rule/delete", + "alerting:metrics.alert.threshold/alerts/rule/update", + "alerting:metrics.alert.threshold/alerts/rule/updateApiKey", + "alerting:metrics.alert.threshold/alerts/rule/enable", + "alerting:metrics.alert.threshold/alerts/rule/disable", + "alerting:metrics.alert.threshold/alerts/rule/muteAll", + "alerting:metrics.alert.threshold/alerts/rule/unmuteAll", + "alerting:metrics.alert.threshold/alerts/rule/muteAlert", + "alerting:metrics.alert.threshold/alerts/rule/unmuteAlert", + "alerting:metrics.alert.threshold/alerts/rule/snooze", + "alerting:metrics.alert.threshold/alerts/rule/bulkEdit", + "alerting:metrics.alert.threshold/alerts/rule/bulkDelete", + "alerting:metrics.alert.threshold/alerts/rule/bulkEnable", + "alerting:metrics.alert.threshold/alerts/rule/bulkDisable", + "alerting:metrics.alert.threshold/alerts/rule/unsnooze", + "alerting:metrics.alert.threshold/alerts/rule/runSoon", + "alerting:metrics.alert.threshold/alerts/rule/scheduleBackfill", + "alerting:metrics.alert.threshold/alerts/rule/deleteBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/get", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleState", + "alerting:metrics.alert.inventory.threshold/observability/rule/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/rule/getExecutionLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/getActionErrorLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/find", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleExecutionKPI", + "alerting:metrics.alert.inventory.threshold/observability/rule/getBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/findBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/create", + "alerting:metrics.alert.inventory.threshold/observability/rule/delete", + "alerting:metrics.alert.inventory.threshold/observability/rule/update", + "alerting:metrics.alert.inventory.threshold/observability/rule/updateApiKey", + "alerting:metrics.alert.inventory.threshold/observability/rule/enable", + "alerting:metrics.alert.inventory.threshold/observability/rule/disable", + "alerting:metrics.alert.inventory.threshold/observability/rule/muteAll", + "alerting:metrics.alert.inventory.threshold/observability/rule/unmuteAll", + "alerting:metrics.alert.inventory.threshold/observability/rule/muteAlert", + "alerting:metrics.alert.inventory.threshold/observability/rule/unmuteAlert", + "alerting:metrics.alert.inventory.threshold/observability/rule/snooze", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkEdit", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkDelete", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkEnable", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkDisable", + "alerting:metrics.alert.inventory.threshold/observability/rule/unsnooze", + "alerting:metrics.alert.inventory.threshold/observability/rule/runSoon", + "alerting:metrics.alert.inventory.threshold/observability/rule/scheduleBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/deleteBackfill", + "alerting:metrics.alert.inventory.threshold/alerts/rule/get", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getRuleState", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getExecutionLog", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getActionErrorLog", + "alerting:metrics.alert.inventory.threshold/alerts/rule/find", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getRuleExecutionKPI", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getBackfill", + "alerting:metrics.alert.inventory.threshold/alerts/rule/findBackfill", + "alerting:metrics.alert.inventory.threshold/alerts/rule/create", + "alerting:metrics.alert.inventory.threshold/alerts/rule/delete", + "alerting:metrics.alert.inventory.threshold/alerts/rule/update", + "alerting:metrics.alert.inventory.threshold/alerts/rule/updateApiKey", + "alerting:metrics.alert.inventory.threshold/alerts/rule/enable", + "alerting:metrics.alert.inventory.threshold/alerts/rule/disable", + "alerting:metrics.alert.inventory.threshold/alerts/rule/muteAll", + "alerting:metrics.alert.inventory.threshold/alerts/rule/unmuteAll", + "alerting:metrics.alert.inventory.threshold/alerts/rule/muteAlert", + "alerting:metrics.alert.inventory.threshold/alerts/rule/unmuteAlert", + "alerting:metrics.alert.inventory.threshold/alerts/rule/snooze", + "alerting:metrics.alert.inventory.threshold/alerts/rule/bulkEdit", + "alerting:metrics.alert.inventory.threshold/alerts/rule/bulkDelete", + "alerting:metrics.alert.inventory.threshold/alerts/rule/bulkEnable", + "alerting:metrics.alert.inventory.threshold/alerts/rule/bulkDisable", + "alerting:metrics.alert.inventory.threshold/alerts/rule/unsnooze", + "alerting:metrics.alert.inventory.threshold/alerts/rule/runSoon", + "alerting:metrics.alert.inventory.threshold/alerts/rule/scheduleBackfill", + "alerting:metrics.alert.inventory.threshold/alerts/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.tls/observability/rule/get", + "alerting:xpack.uptime.alerts.tls/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.tls/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tls/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tls/observability/rule/find", + "alerting:xpack.uptime.alerts.tls/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tls/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.tls/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.tls/observability/rule/create", + "alerting:xpack.uptime.alerts.tls/observability/rule/delete", + "alerting:xpack.uptime.alerts.tls/observability/rule/update", + "alerting:xpack.uptime.alerts.tls/observability/rule/updateApiKey", + "alerting:xpack.uptime.alerts.tls/observability/rule/enable", + "alerting:xpack.uptime.alerts.tls/observability/rule/disable", + "alerting:xpack.uptime.alerts.tls/observability/rule/muteAll", + "alerting:xpack.uptime.alerts.tls/observability/rule/unmuteAll", + "alerting:xpack.uptime.alerts.tls/observability/rule/muteAlert", + "alerting:xpack.uptime.alerts.tls/observability/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.tls/observability/rule/snooze", + "alerting:xpack.uptime.alerts.tls/observability/rule/bulkEdit", + "alerting:xpack.uptime.alerts.tls/observability/rule/bulkDelete", + "alerting:xpack.uptime.alerts.tls/observability/rule/bulkEnable", + "alerting:xpack.uptime.alerts.tls/observability/rule/bulkDisable", + "alerting:xpack.uptime.alerts.tls/observability/rule/unsnooze", + "alerting:xpack.uptime.alerts.tls/observability/rule/runSoon", + "alerting:xpack.uptime.alerts.tls/observability/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.tls/observability/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.tls/alerts/rule/get", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tls/alerts/rule/find", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.tls/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.tls/alerts/rule/create", + "alerting:xpack.uptime.alerts.tls/alerts/rule/delete", + "alerting:xpack.uptime.alerts.tls/alerts/rule/update", + "alerting:xpack.uptime.alerts.tls/alerts/rule/updateApiKey", + "alerting:xpack.uptime.alerts.tls/alerts/rule/enable", + "alerting:xpack.uptime.alerts.tls/alerts/rule/disable", + "alerting:xpack.uptime.alerts.tls/alerts/rule/muteAll", + "alerting:xpack.uptime.alerts.tls/alerts/rule/unmuteAll", + "alerting:xpack.uptime.alerts.tls/alerts/rule/muteAlert", + "alerting:xpack.uptime.alerts.tls/alerts/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.tls/alerts/rule/snooze", + "alerting:xpack.uptime.alerts.tls/alerts/rule/bulkEdit", + "alerting:xpack.uptime.alerts.tls/alerts/rule/bulkDelete", + "alerting:xpack.uptime.alerts.tls/alerts/rule/bulkEnable", + "alerting:xpack.uptime.alerts.tls/alerts/rule/bulkDisable", + "alerting:xpack.uptime.alerts.tls/alerts/rule/unsnooze", + "alerting:xpack.uptime.alerts.tls/alerts/rule/runSoon", + "alerting:xpack.uptime.alerts.tls/alerts/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.tls/alerts/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/get", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/find", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/create", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/delete", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/update", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/updateApiKey", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/enable", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/disable", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/muteAll", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/unmuteAll", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/muteAlert", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/snooze", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/bulkEdit", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/bulkDelete", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/bulkEnable", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/bulkDisable", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/unsnooze", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/runSoon", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/get", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/find", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/create", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/delete", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/update", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/updateApiKey", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/enable", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/disable", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/muteAll", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/unmuteAll", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/muteAlert", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/snooze", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/bulkEdit", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/bulkDelete", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/bulkEnable", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/bulkDisable", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/unsnooze", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/runSoon", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/get", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/find", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/create", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/delete", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/update", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/updateApiKey", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/enable", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/disable", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/muteAll", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/unmuteAll", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/muteAlert", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/snooze", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/bulkEdit", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/bulkDelete", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/bulkEnable", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/bulkDisable", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/unsnooze", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/runSoon", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/get", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/find", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/create", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/delete", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/update", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/updateApiKey", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/enable", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/disable", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/muteAll", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/unmuteAll", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/muteAlert", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/snooze", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/bulkEdit", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/bulkDelete", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/bulkEnable", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/bulkDisable", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/unsnooze", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/runSoon", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/get", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/find", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/create", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/delete", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/update", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/updateApiKey", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/enable", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/disable", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/muteAll", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/unmuteAll", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/muteAlert", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/snooze", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/bulkEdit", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/bulkDelete", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/bulkEnable", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/bulkDisable", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/unsnooze", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/runSoon", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/get", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/find", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/create", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/delete", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/update", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/updateApiKey", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/enable", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/disable", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/muteAll", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/unmuteAll", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/muteAlert", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/snooze", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/bulkEdit", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/bulkDelete", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/bulkEnable", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/bulkDisable", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/unsnooze", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/runSoon", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/deleteBackfill", + "alerting:logs.alert.document.count/observability/rule/get", + "alerting:logs.alert.document.count/observability/rule/getRuleState", + "alerting:logs.alert.document.count/observability/rule/getAlertSummary", + "alerting:logs.alert.document.count/observability/rule/getExecutionLog", + "alerting:logs.alert.document.count/observability/rule/getActionErrorLog", + "alerting:logs.alert.document.count/observability/rule/find", + "alerting:logs.alert.document.count/observability/rule/getRuleExecutionKPI", + "alerting:logs.alert.document.count/observability/rule/getBackfill", + "alerting:logs.alert.document.count/observability/rule/findBackfill", + "alerting:logs.alert.document.count/observability/rule/create", + "alerting:logs.alert.document.count/observability/rule/delete", + "alerting:logs.alert.document.count/observability/rule/update", + "alerting:logs.alert.document.count/observability/rule/updateApiKey", + "alerting:logs.alert.document.count/observability/rule/enable", + "alerting:logs.alert.document.count/observability/rule/disable", + "alerting:logs.alert.document.count/observability/rule/muteAll", + "alerting:logs.alert.document.count/observability/rule/unmuteAll", + "alerting:logs.alert.document.count/observability/rule/muteAlert", + "alerting:logs.alert.document.count/observability/rule/unmuteAlert", + "alerting:logs.alert.document.count/observability/rule/snooze", + "alerting:logs.alert.document.count/observability/rule/bulkEdit", + "alerting:logs.alert.document.count/observability/rule/bulkDelete", + "alerting:logs.alert.document.count/observability/rule/bulkEnable", + "alerting:logs.alert.document.count/observability/rule/bulkDisable", + "alerting:logs.alert.document.count/observability/rule/unsnooze", + "alerting:logs.alert.document.count/observability/rule/runSoon", + "alerting:logs.alert.document.count/observability/rule/scheduleBackfill", + "alerting:logs.alert.document.count/observability/rule/deleteBackfill", + "alerting:slo.rules.burnRate/observability/rule/get", + "alerting:slo.rules.burnRate/observability/rule/getRuleState", + "alerting:slo.rules.burnRate/observability/rule/getAlertSummary", + "alerting:slo.rules.burnRate/observability/rule/getExecutionLog", + "alerting:slo.rules.burnRate/observability/rule/getActionErrorLog", + "alerting:slo.rules.burnRate/observability/rule/find", + "alerting:slo.rules.burnRate/observability/rule/getRuleExecutionKPI", + "alerting:slo.rules.burnRate/observability/rule/getBackfill", + "alerting:slo.rules.burnRate/observability/rule/findBackfill", + "alerting:slo.rules.burnRate/observability/rule/create", + "alerting:slo.rules.burnRate/observability/rule/delete", + "alerting:slo.rules.burnRate/observability/rule/update", + "alerting:slo.rules.burnRate/observability/rule/updateApiKey", + "alerting:slo.rules.burnRate/observability/rule/enable", + "alerting:slo.rules.burnRate/observability/rule/disable", + "alerting:slo.rules.burnRate/observability/rule/muteAll", + "alerting:slo.rules.burnRate/observability/rule/unmuteAll", + "alerting:slo.rules.burnRate/observability/rule/muteAlert", + "alerting:slo.rules.burnRate/observability/rule/unmuteAlert", + "alerting:slo.rules.burnRate/observability/rule/snooze", + "alerting:slo.rules.burnRate/observability/rule/bulkEdit", + "alerting:slo.rules.burnRate/observability/rule/bulkDelete", + "alerting:slo.rules.burnRate/observability/rule/bulkEnable", + "alerting:slo.rules.burnRate/observability/rule/bulkDisable", + "alerting:slo.rules.burnRate/observability/rule/unsnooze", + "alerting:slo.rules.burnRate/observability/rule/runSoon", + "alerting:slo.rules.burnRate/observability/rule/scheduleBackfill", + "alerting:slo.rules.burnRate/observability/rule/deleteBackfill", + "alerting:slo.rules.burnRate/alerts/rule/get", + "alerting:slo.rules.burnRate/alerts/rule/getRuleState", + "alerting:slo.rules.burnRate/alerts/rule/getAlertSummary", + "alerting:slo.rules.burnRate/alerts/rule/getExecutionLog", + "alerting:slo.rules.burnRate/alerts/rule/getActionErrorLog", + "alerting:slo.rules.burnRate/alerts/rule/find", + "alerting:slo.rules.burnRate/alerts/rule/getRuleExecutionKPI", + "alerting:slo.rules.burnRate/alerts/rule/getBackfill", + "alerting:slo.rules.burnRate/alerts/rule/findBackfill", + "alerting:slo.rules.burnRate/alerts/rule/create", + "alerting:slo.rules.burnRate/alerts/rule/delete", + "alerting:slo.rules.burnRate/alerts/rule/update", + "alerting:slo.rules.burnRate/alerts/rule/updateApiKey", + "alerting:slo.rules.burnRate/alerts/rule/enable", + "alerting:slo.rules.burnRate/alerts/rule/disable", + "alerting:slo.rules.burnRate/alerts/rule/muteAll", + "alerting:slo.rules.burnRate/alerts/rule/unmuteAll", + "alerting:slo.rules.burnRate/alerts/rule/muteAlert", + "alerting:slo.rules.burnRate/alerts/rule/unmuteAlert", + "alerting:slo.rules.burnRate/alerts/rule/snooze", + "alerting:slo.rules.burnRate/alerts/rule/bulkEdit", + "alerting:slo.rules.burnRate/alerts/rule/bulkDelete", + "alerting:slo.rules.burnRate/alerts/rule/bulkEnable", + "alerting:slo.rules.burnRate/alerts/rule/bulkDisable", + "alerting:slo.rules.burnRate/alerts/rule/unsnooze", + "alerting:slo.rules.burnRate/alerts/rule/runSoon", + "alerting:slo.rules.burnRate/alerts/rule/scheduleBackfill", + "alerting:slo.rules.burnRate/alerts/rule/deleteBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/get", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleState", + "alerting:observability.rules.custom_threshold/observability/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/observability/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/observability/rule/find", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/observability/rule/getBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/findBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/create", + "alerting:observability.rules.custom_threshold/observability/rule/delete", + "alerting:observability.rules.custom_threshold/observability/rule/update", + "alerting:observability.rules.custom_threshold/observability/rule/updateApiKey", + "alerting:observability.rules.custom_threshold/observability/rule/enable", + "alerting:observability.rules.custom_threshold/observability/rule/disable", + "alerting:observability.rules.custom_threshold/observability/rule/muteAll", + "alerting:observability.rules.custom_threshold/observability/rule/unmuteAll", + "alerting:observability.rules.custom_threshold/observability/rule/muteAlert", + "alerting:observability.rules.custom_threshold/observability/rule/unmuteAlert", + "alerting:observability.rules.custom_threshold/observability/rule/snooze", + "alerting:observability.rules.custom_threshold/observability/rule/bulkEdit", + "alerting:observability.rules.custom_threshold/observability/rule/bulkDelete", + "alerting:observability.rules.custom_threshold/observability/rule/bulkEnable", + "alerting:observability.rules.custom_threshold/observability/rule/bulkDisable", + "alerting:observability.rules.custom_threshold/observability/rule/unsnooze", + "alerting:observability.rules.custom_threshold/observability/rule/runSoon", + "alerting:observability.rules.custom_threshold/observability/rule/scheduleBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/deleteBackfill", + "alerting:.es-query/observability/rule/get", + "alerting:.es-query/observability/rule/getRuleState", + "alerting:.es-query/observability/rule/getAlertSummary", + "alerting:.es-query/observability/rule/getExecutionLog", + "alerting:.es-query/observability/rule/getActionErrorLog", + "alerting:.es-query/observability/rule/find", + "alerting:.es-query/observability/rule/getRuleExecutionKPI", + "alerting:.es-query/observability/rule/getBackfill", + "alerting:.es-query/observability/rule/findBackfill", + "alerting:.es-query/observability/rule/create", + "alerting:.es-query/observability/rule/delete", + "alerting:.es-query/observability/rule/update", + "alerting:.es-query/observability/rule/updateApiKey", + "alerting:.es-query/observability/rule/enable", + "alerting:.es-query/observability/rule/disable", + "alerting:.es-query/observability/rule/muteAll", + "alerting:.es-query/observability/rule/unmuteAll", + "alerting:.es-query/observability/rule/muteAlert", + "alerting:.es-query/observability/rule/unmuteAlert", + "alerting:.es-query/observability/rule/snooze", + "alerting:.es-query/observability/rule/bulkEdit", + "alerting:.es-query/observability/rule/bulkDelete", + "alerting:.es-query/observability/rule/bulkEnable", + "alerting:.es-query/observability/rule/bulkDisable", + "alerting:.es-query/observability/rule/unsnooze", + "alerting:.es-query/observability/rule/runSoon", + "alerting:.es-query/observability/rule/scheduleBackfill", + "alerting:.es-query/observability/rule/deleteBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/create", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/delete", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/update", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/updateApiKey", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/enable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/disable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/muteAll", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unmuteAll", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/muteAlert", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unmuteAlert", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/snooze", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkEdit", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkDelete", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkEnable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkDisable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unsnooze", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/runSoon", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/scheduleBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/deleteBackfill", + "alerting:apm.error_rate/observability/alert/get", + "alerting:apm.error_rate/observability/alert/find", + "alerting:apm.error_rate/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.error_rate/observability/alert/getAlertSummary", + "alerting:apm.error_rate/observability/alert/update", + "alerting:apm.transaction_error_rate/observability/alert/get", + "alerting:apm.transaction_error_rate/observability/alert/find", + "alerting:apm.transaction_error_rate/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_error_rate/observability/alert/getAlertSummary", + "alerting:apm.transaction_error_rate/observability/alert/update", + "alerting:apm.transaction_duration/observability/alert/get", + "alerting:apm.transaction_duration/observability/alert/find", + "alerting:apm.transaction_duration/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_duration/observability/alert/getAlertSummary", + "alerting:apm.transaction_duration/observability/alert/update", + "alerting:apm.anomaly/observability/alert/get", + "alerting:apm.anomaly/observability/alert/find", + "alerting:apm.anomaly/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.anomaly/observability/alert/getAlertSummary", + "alerting:apm.anomaly/observability/alert/update", + "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/get", + "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/find", + "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/getAlertSummary", + "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/update", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/get", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/find", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/getAlertSummary", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/update", + "alerting:xpack.synthetics.alerts.tls/observability/alert/get", + "alerting:xpack.synthetics.alerts.tls/observability/alert/find", + "alerting:xpack.synthetics.alerts.tls/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.synthetics.alerts.tls/observability/alert/getAlertSummary", + "alerting:xpack.synthetics.alerts.tls/observability/alert/update", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/get", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/find", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/getAlertSummary", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/update", + "alerting:metrics.alert.threshold/observability/alert/get", + "alerting:metrics.alert.threshold/observability/alert/find", + "alerting:metrics.alert.threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.threshold/observability/alert/getAlertSummary", + "alerting:metrics.alert.threshold/observability/alert/update", + "alerting:metrics.alert.threshold/alerts/alert/get", + "alerting:metrics.alert.threshold/alerts/alert/find", + "alerting:metrics.alert.threshold/alerts/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.threshold/alerts/alert/getAlertSummary", + "alerting:metrics.alert.threshold/alerts/alert/update", + "alerting:metrics.alert.inventory.threshold/observability/alert/get", + "alerting:metrics.alert.inventory.threshold/observability/alert/find", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/alert/update", + "alerting:metrics.alert.inventory.threshold/alerts/alert/get", + "alerting:metrics.alert.inventory.threshold/alerts/alert/find", + "alerting:metrics.alert.inventory.threshold/alerts/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.inventory.threshold/alerts/alert/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/alerts/alert/update", + "alerting:xpack.uptime.alerts.tls/observability/alert/get", + "alerting:xpack.uptime.alerts.tls/observability/alert/find", + "alerting:xpack.uptime.alerts.tls/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tls/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/observability/alert/update", + "alerting:xpack.uptime.alerts.tls/alerts/alert/get", + "alerting:xpack.uptime.alerts.tls/alerts/alert/find", + "alerting:xpack.uptime.alerts.tls/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tls/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/alerts/alert/update", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/get", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/find", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/update", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/get", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/find", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/update", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/get", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/find", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/update", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/get", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/find", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/update", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/get", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/find", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/update", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/get", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/find", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/update", + "alerting:logs.alert.document.count/observability/alert/get", + "alerting:logs.alert.document.count/observability/alert/find", + "alerting:logs.alert.document.count/observability/alert/getAuthorizedAlertsIndices", + "alerting:logs.alert.document.count/observability/alert/getAlertSummary", + "alerting:logs.alert.document.count/observability/alert/update", + "alerting:slo.rules.burnRate/observability/alert/get", + "alerting:slo.rules.burnRate/observability/alert/find", + "alerting:slo.rules.burnRate/observability/alert/getAuthorizedAlertsIndices", + "alerting:slo.rules.burnRate/observability/alert/getAlertSummary", + "alerting:slo.rules.burnRate/observability/alert/update", + "alerting:slo.rules.burnRate/alerts/alert/get", + "alerting:slo.rules.burnRate/alerts/alert/find", + "alerting:slo.rules.burnRate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:slo.rules.burnRate/alerts/alert/getAlertSummary", + "alerting:slo.rules.burnRate/alerts/alert/update", + "alerting:observability.rules.custom_threshold/observability/alert/get", + "alerting:observability.rules.custom_threshold/observability/alert/find", + "alerting:observability.rules.custom_threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/observability/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/alert/update", + "alerting:.es-query/observability/alert/get", + "alerting:.es-query/observability/alert/find", + "alerting:.es-query/observability/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/observability/alert/getAlertSummary", + "alerting:.es-query/observability/alert/update", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/update", + ], + "minimal_read": Array [ + "login:", + "api:apm", + "api:rac", + "app:apm", + "app:ux", + "app:kibana", + "ui:catalogue/apm", + "ui:management/insightsAndAlerting/triggersActions", + "ui:navLinks/apm", + "ui:navLinks/ux", + "ui:navLinks/kibana", + "saved_object:apm-indices/bulk_get", + "saved_object:apm-indices/get", + "saved_object:apm-indices/find", + "saved_object:apm-indices/open_point_in_time", + "saved_object:apm-indices/close_point_in_time", + "saved_object:config/bulk_get", + "saved_object:config/get", + "saved_object:config/find", + "saved_object:config/open_point_in_time", + "saved_object:config/close_point_in_time", + "saved_object:config-global/bulk_get", + "saved_object:config-global/get", + "saved_object:config-global/find", + "saved_object:config-global/open_point_in_time", + "saved_object:config-global/close_point_in_time", + "saved_object:telemetry/bulk_get", + "saved_object:telemetry/get", + "saved_object:telemetry/find", + "saved_object:telemetry/open_point_in_time", + "saved_object:telemetry/close_point_in_time", + "saved_object:url/bulk_get", + "saved_object:url/get", + "saved_object:url/find", + "saved_object:url/open_point_in_time", + "saved_object:url/close_point_in_time", + "ui:apm/show", + "ui:apm/alerting:show", + "alerting:apm.error_rate/apm/rule/get", + "alerting:apm.error_rate/apm/rule/getRuleState", + "alerting:apm.error_rate/apm/rule/getAlertSummary", + "alerting:apm.error_rate/apm/rule/getExecutionLog", + "alerting:apm.error_rate/apm/rule/getActionErrorLog", + "alerting:apm.error_rate/apm/rule/find", + "alerting:apm.error_rate/apm/rule/getRuleExecutionKPI", + "alerting:apm.error_rate/apm/rule/getBackfill", + "alerting:apm.error_rate/apm/rule/findBackfill", + "alerting:apm.error_rate/alerts/rule/get", + "alerting:apm.error_rate/alerts/rule/getRuleState", + "alerting:apm.error_rate/alerts/rule/getAlertSummary", + "alerting:apm.error_rate/alerts/rule/getExecutionLog", + "alerting:apm.error_rate/alerts/rule/getActionErrorLog", + "alerting:apm.error_rate/alerts/rule/find", + "alerting:apm.error_rate/alerts/rule/getRuleExecutionKPI", + "alerting:apm.error_rate/alerts/rule/getBackfill", + "alerting:apm.error_rate/alerts/rule/findBackfill", + "alerting:apm.transaction_error_rate/apm/rule/get", + "alerting:apm.transaction_error_rate/apm/rule/getRuleState", + "alerting:apm.transaction_error_rate/apm/rule/getAlertSummary", + "alerting:apm.transaction_error_rate/apm/rule/getExecutionLog", + "alerting:apm.transaction_error_rate/apm/rule/getActionErrorLog", + "alerting:apm.transaction_error_rate/apm/rule/find", + "alerting:apm.transaction_error_rate/apm/rule/getRuleExecutionKPI", + "alerting:apm.transaction_error_rate/apm/rule/getBackfill", + "alerting:apm.transaction_error_rate/apm/rule/findBackfill", + "alerting:apm.transaction_error_rate/alerts/rule/get", + "alerting:apm.transaction_error_rate/alerts/rule/getRuleState", + "alerting:apm.transaction_error_rate/alerts/rule/getAlertSummary", + "alerting:apm.transaction_error_rate/alerts/rule/getExecutionLog", + "alerting:apm.transaction_error_rate/alerts/rule/getActionErrorLog", + "alerting:apm.transaction_error_rate/alerts/rule/find", + "alerting:apm.transaction_error_rate/alerts/rule/getRuleExecutionKPI", + "alerting:apm.transaction_error_rate/alerts/rule/getBackfill", + "alerting:apm.transaction_error_rate/alerts/rule/findBackfill", + "alerting:apm.transaction_duration/apm/rule/get", + "alerting:apm.transaction_duration/apm/rule/getRuleState", + "alerting:apm.transaction_duration/apm/rule/getAlertSummary", + "alerting:apm.transaction_duration/apm/rule/getExecutionLog", "alerting:apm.transaction_duration/apm/rule/getActionErrorLog", "alerting:apm.transaction_duration/apm/rule/find", "alerting:apm.transaction_duration/apm/rule/getRuleExecutionKPI", "alerting:apm.transaction_duration/apm/rule/getBackfill", "alerting:apm.transaction_duration/apm/rule/findBackfill", + "alerting:apm.transaction_duration/alerts/rule/get", + "alerting:apm.transaction_duration/alerts/rule/getRuleState", + "alerting:apm.transaction_duration/alerts/rule/getAlertSummary", + "alerting:apm.transaction_duration/alerts/rule/getExecutionLog", + "alerting:apm.transaction_duration/alerts/rule/getActionErrorLog", + "alerting:apm.transaction_duration/alerts/rule/find", + "alerting:apm.transaction_duration/alerts/rule/getRuleExecutionKPI", + "alerting:apm.transaction_duration/alerts/rule/getBackfill", + "alerting:apm.transaction_duration/alerts/rule/findBackfill", "alerting:apm.anomaly/apm/rule/get", "alerting:apm.anomaly/apm/rule/getRuleState", "alerting:apm.anomaly/apm/rule/getAlertSummary", @@ -1560,22 +3106,47 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.anomaly/apm/rule/getRuleExecutionKPI", "alerting:apm.anomaly/apm/rule/getBackfill", "alerting:apm.anomaly/apm/rule/findBackfill", + "alerting:apm.anomaly/alerts/rule/get", + "alerting:apm.anomaly/alerts/rule/getRuleState", + "alerting:apm.anomaly/alerts/rule/getAlertSummary", + "alerting:apm.anomaly/alerts/rule/getExecutionLog", + "alerting:apm.anomaly/alerts/rule/getActionErrorLog", + "alerting:apm.anomaly/alerts/rule/find", + "alerting:apm.anomaly/alerts/rule/getRuleExecutionKPI", + "alerting:apm.anomaly/alerts/rule/getBackfill", + "alerting:apm.anomaly/alerts/rule/findBackfill", "alerting:apm.error_rate/apm/alert/get", "alerting:apm.error_rate/apm/alert/find", "alerting:apm.error_rate/apm/alert/getAuthorizedAlertsIndices", "alerting:apm.error_rate/apm/alert/getAlertSummary", + "alerting:apm.error_rate/alerts/alert/get", + "alerting:apm.error_rate/alerts/alert/find", + "alerting:apm.error_rate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.error_rate/alerts/alert/getAlertSummary", "alerting:apm.transaction_error_rate/apm/alert/get", "alerting:apm.transaction_error_rate/apm/alert/find", "alerting:apm.transaction_error_rate/apm/alert/getAuthorizedAlertsIndices", "alerting:apm.transaction_error_rate/apm/alert/getAlertSummary", + "alerting:apm.transaction_error_rate/alerts/alert/get", + "alerting:apm.transaction_error_rate/alerts/alert/find", + "alerting:apm.transaction_error_rate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_error_rate/alerts/alert/getAlertSummary", "alerting:apm.transaction_duration/apm/alert/get", "alerting:apm.transaction_duration/apm/alert/find", "alerting:apm.transaction_duration/apm/alert/getAuthorizedAlertsIndices", "alerting:apm.transaction_duration/apm/alert/getAlertSummary", + "alerting:apm.transaction_duration/alerts/alert/get", + "alerting:apm.transaction_duration/alerts/alert/find", + "alerting:apm.transaction_duration/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_duration/alerts/alert/getAlertSummary", "alerting:apm.anomaly/apm/alert/get", "alerting:apm.anomaly/apm/alert/find", "alerting:apm.anomaly/apm/alert/getAuthorizedAlertsIndices", "alerting:apm.anomaly/apm/alert/getAlertSummary", + "alerting:apm.anomaly/alerts/alert/get", + "alerting:apm.anomaly/alerts/alert/find", + "alerting:apm.anomaly/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.anomaly/alerts/alert/getAlertSummary", "api:infra", "app:infra", "app:logs", @@ -1605,6 +3176,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:logs.alert.document.count/logs/rule/getRuleExecutionKPI", "alerting:logs.alert.document.count/logs/rule/getBackfill", "alerting:logs.alert.document.count/logs/rule/findBackfill", + "alerting:logs.alert.document.count/alerts/rule/get", + "alerting:logs.alert.document.count/alerts/rule/getRuleState", + "alerting:logs.alert.document.count/alerts/rule/getAlertSummary", + "alerting:logs.alert.document.count/alerts/rule/getExecutionLog", + "alerting:logs.alert.document.count/alerts/rule/getActionErrorLog", + "alerting:logs.alert.document.count/alerts/rule/find", + "alerting:logs.alert.document.count/alerts/rule/getRuleExecutionKPI", + "alerting:logs.alert.document.count/alerts/rule/getBackfill", + "alerting:logs.alert.document.count/alerts/rule/findBackfill", "alerting:.es-query/logs/rule/get", "alerting:.es-query/logs/rule/getRuleState", "alerting:.es-query/logs/rule/getAlertSummary", @@ -1614,6 +3194,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:.es-query/logs/rule/getRuleExecutionKPI", "alerting:.es-query/logs/rule/getBackfill", "alerting:.es-query/logs/rule/findBackfill", + "alerting:.es-query/alerts/rule/get", + "alerting:.es-query/alerts/rule/getRuleState", + "alerting:.es-query/alerts/rule/getAlertSummary", + "alerting:.es-query/alerts/rule/getExecutionLog", + "alerting:.es-query/alerts/rule/getActionErrorLog", + "alerting:.es-query/alerts/rule/find", + "alerting:.es-query/alerts/rule/getRuleExecutionKPI", + "alerting:.es-query/alerts/rule/getBackfill", + "alerting:.es-query/alerts/rule/findBackfill", "alerting:observability.rules.custom_threshold/logs/rule/get", "alerting:observability.rules.custom_threshold/logs/rule/getRuleState", "alerting:observability.rules.custom_threshold/logs/rule/getAlertSummary", @@ -1623,6 +3212,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:observability.rules.custom_threshold/logs/rule/getRuleExecutionKPI", "alerting:observability.rules.custom_threshold/logs/rule/getBackfill", "alerting:observability.rules.custom_threshold/logs/rule/findBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/get", + "alerting:observability.rules.custom_threshold/alerts/rule/getRuleState", + "alerting:observability.rules.custom_threshold/alerts/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/alerts/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/alerts/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/alerts/rule/find", + "alerting:observability.rules.custom_threshold/alerts/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/alerts/rule/getBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/findBackfill", "alerting:xpack.ml.anomaly_detection_alert/logs/rule/get", "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getRuleState", "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getAlertSummary", @@ -1632,71 +3230,51 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getRuleExecutionKPI", "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getBackfill", "alerting:xpack.ml.anomaly_detection_alert/logs/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/findBackfill", "alerting:logs.alert.document.count/logs/alert/get", "alerting:logs.alert.document.count/logs/alert/find", "alerting:logs.alert.document.count/logs/alert/getAuthorizedAlertsIndices", "alerting:logs.alert.document.count/logs/alert/getAlertSummary", + "alerting:logs.alert.document.count/alerts/alert/get", + "alerting:logs.alert.document.count/alerts/alert/find", + "alerting:logs.alert.document.count/alerts/alert/getAuthorizedAlertsIndices", + "alerting:logs.alert.document.count/alerts/alert/getAlertSummary", "alerting:.es-query/logs/alert/get", "alerting:.es-query/logs/alert/find", "alerting:.es-query/logs/alert/getAuthorizedAlertsIndices", "alerting:.es-query/logs/alert/getAlertSummary", + "alerting:.es-query/alerts/alert/get", + "alerting:.es-query/alerts/alert/find", + "alerting:.es-query/alerts/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/alerts/alert/getAlertSummary", "alerting:observability.rules.custom_threshold/logs/alert/get", "alerting:observability.rules.custom_threshold/logs/alert/find", "alerting:observability.rules.custom_threshold/logs/alert/getAuthorizedAlertsIndices", "alerting:observability.rules.custom_threshold/logs/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/alerts/alert/get", + "alerting:observability.rules.custom_threshold/alerts/alert/find", + "alerting:observability.rules.custom_threshold/alerts/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/alerts/alert/getAlertSummary", "alerting:xpack.ml.anomaly_detection_alert/logs/alert/get", "alerting:xpack.ml.anomaly_detection_alert/logs/alert/find", "alerting:xpack.ml.anomaly_detection_alert/logs/alert/getAuthorizedAlertsIndices", "alerting:xpack.ml.anomaly_detection_alert/logs/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/getAlertSummary", "app:observability", "ui:catalogue/observability", "ui:navLinks/observability", "ui:observability/read", - "alerting:slo.rules.burnRate/observability/rule/get", - "alerting:slo.rules.burnRate/observability/rule/getRuleState", - "alerting:slo.rules.burnRate/observability/rule/getAlertSummary", - "alerting:slo.rules.burnRate/observability/rule/getExecutionLog", - "alerting:slo.rules.burnRate/observability/rule/getActionErrorLog", - "alerting:slo.rules.burnRate/observability/rule/find", - "alerting:slo.rules.burnRate/observability/rule/getRuleExecutionKPI", - "alerting:slo.rules.burnRate/observability/rule/getBackfill", - "alerting:slo.rules.burnRate/observability/rule/findBackfill", - "alerting:observability.rules.custom_threshold/observability/rule/get", - "alerting:observability.rules.custom_threshold/observability/rule/getRuleState", - "alerting:observability.rules.custom_threshold/observability/rule/getAlertSummary", - "alerting:observability.rules.custom_threshold/observability/rule/getExecutionLog", - "alerting:observability.rules.custom_threshold/observability/rule/getActionErrorLog", - "alerting:observability.rules.custom_threshold/observability/rule/find", - "alerting:observability.rules.custom_threshold/observability/rule/getRuleExecutionKPI", - "alerting:observability.rules.custom_threshold/observability/rule/getBackfill", - "alerting:observability.rules.custom_threshold/observability/rule/findBackfill", - "alerting:.es-query/observability/rule/get", - "alerting:.es-query/observability/rule/getRuleState", - "alerting:.es-query/observability/rule/getAlertSummary", - "alerting:.es-query/observability/rule/getExecutionLog", - "alerting:.es-query/observability/rule/getActionErrorLog", - "alerting:.es-query/observability/rule/find", - "alerting:.es-query/observability/rule/getRuleExecutionKPI", - "alerting:.es-query/observability/rule/getBackfill", - "alerting:.es-query/observability/rule/findBackfill", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/get", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleState", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getAlertSummary", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getExecutionLog", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getActionErrorLog", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/find", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleExecutionKPI", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getBackfill", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/findBackfill", - "alerting:metrics.alert.inventory.threshold/observability/rule/get", - "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleState", - "alerting:metrics.alert.inventory.threshold/observability/rule/getAlertSummary", - "alerting:metrics.alert.inventory.threshold/observability/rule/getExecutionLog", - "alerting:metrics.alert.inventory.threshold/observability/rule/getActionErrorLog", - "alerting:metrics.alert.inventory.threshold/observability/rule/find", - "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleExecutionKPI", - "alerting:metrics.alert.inventory.threshold/observability/rule/getBackfill", - "alerting:metrics.alert.inventory.threshold/observability/rule/findBackfill", "alerting:apm.error_rate/observability/rule/get", "alerting:apm.error_rate/observability/rule/getRuleState", "alerting:apm.error_rate/observability/rule/getAlertSummary", @@ -1742,6 +3320,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/getRuleExecutionKPI", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/getBackfill", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/findBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/get", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getRuleState", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getAlertSummary", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getExecutionLog", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getActionErrorLog", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/find", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/findBackfill", "alerting:xpack.synthetics.alerts.tls/observability/rule/get", "alerting:xpack.synthetics.alerts.tls/observability/rule/getRuleState", "alerting:xpack.synthetics.alerts.tls/observability/rule/getAlertSummary", @@ -1751,26 +3338,177 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.synthetics.alerts.tls/observability/rule/getRuleExecutionKPI", "alerting:xpack.synthetics.alerts.tls/observability/rule/getBackfill", "alerting:xpack.synthetics.alerts.tls/observability/rule/findBackfill", - "alerting:slo.rules.burnRate/observability/alert/get", - "alerting:slo.rules.burnRate/observability/alert/find", - "alerting:slo.rules.burnRate/observability/alert/getAuthorizedAlertsIndices", - "alerting:slo.rules.burnRate/observability/alert/getAlertSummary", - "alerting:observability.rules.custom_threshold/observability/alert/get", - "alerting:observability.rules.custom_threshold/observability/alert/find", - "alerting:observability.rules.custom_threshold/observability/alert/getAuthorizedAlertsIndices", - "alerting:observability.rules.custom_threshold/observability/alert/getAlertSummary", - "alerting:.es-query/observability/alert/get", - "alerting:.es-query/observability/alert/find", - "alerting:.es-query/observability/alert/getAuthorizedAlertsIndices", - "alerting:.es-query/observability/alert/getAlertSummary", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/get", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/find", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAuthorizedAlertsIndices", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAlertSummary", - "alerting:metrics.alert.inventory.threshold/observability/alert/get", - "alerting:metrics.alert.inventory.threshold/observability/alert/find", - "alerting:metrics.alert.inventory.threshold/observability/alert/getAuthorizedAlertsIndices", - "alerting:metrics.alert.inventory.threshold/observability/alert/getAlertSummary", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/get", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getRuleState", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getAlertSummary", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getExecutionLog", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getActionErrorLog", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/find", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getBackfill", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/findBackfill", + "alerting:metrics.alert.threshold/observability/rule/get", + "alerting:metrics.alert.threshold/observability/rule/getRuleState", + "alerting:metrics.alert.threshold/observability/rule/getAlertSummary", + "alerting:metrics.alert.threshold/observability/rule/getExecutionLog", + "alerting:metrics.alert.threshold/observability/rule/getActionErrorLog", + "alerting:metrics.alert.threshold/observability/rule/find", + "alerting:metrics.alert.threshold/observability/rule/getRuleExecutionKPI", + "alerting:metrics.alert.threshold/observability/rule/getBackfill", + "alerting:metrics.alert.threshold/observability/rule/findBackfill", + "alerting:metrics.alert.threshold/alerts/rule/get", + "alerting:metrics.alert.threshold/alerts/rule/getRuleState", + "alerting:metrics.alert.threshold/alerts/rule/getAlertSummary", + "alerting:metrics.alert.threshold/alerts/rule/getExecutionLog", + "alerting:metrics.alert.threshold/alerts/rule/getActionErrorLog", + "alerting:metrics.alert.threshold/alerts/rule/find", + "alerting:metrics.alert.threshold/alerts/rule/getRuleExecutionKPI", + "alerting:metrics.alert.threshold/alerts/rule/getBackfill", + "alerting:metrics.alert.threshold/alerts/rule/findBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/get", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleState", + "alerting:metrics.alert.inventory.threshold/observability/rule/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/rule/getExecutionLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/getActionErrorLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/find", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleExecutionKPI", + "alerting:metrics.alert.inventory.threshold/observability/rule/getBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/findBackfill", + "alerting:metrics.alert.inventory.threshold/alerts/rule/get", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getRuleState", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getExecutionLog", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getActionErrorLog", + "alerting:metrics.alert.inventory.threshold/alerts/rule/find", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getRuleExecutionKPI", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getBackfill", + "alerting:metrics.alert.inventory.threshold/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.tls/observability/rule/get", + "alerting:xpack.uptime.alerts.tls/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.tls/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tls/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tls/observability/rule/find", + "alerting:xpack.uptime.alerts.tls/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tls/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.tls/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.tls/alerts/rule/get", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tls/alerts/rule/find", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.tls/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/get", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/find", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/get", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/find", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/get", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/find", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/get", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/find", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/get", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/find", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/get", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/find", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/findBackfill", + "alerting:logs.alert.document.count/observability/rule/get", + "alerting:logs.alert.document.count/observability/rule/getRuleState", + "alerting:logs.alert.document.count/observability/rule/getAlertSummary", + "alerting:logs.alert.document.count/observability/rule/getExecutionLog", + "alerting:logs.alert.document.count/observability/rule/getActionErrorLog", + "alerting:logs.alert.document.count/observability/rule/find", + "alerting:logs.alert.document.count/observability/rule/getRuleExecutionKPI", + "alerting:logs.alert.document.count/observability/rule/getBackfill", + "alerting:logs.alert.document.count/observability/rule/findBackfill", + "alerting:slo.rules.burnRate/observability/rule/get", + "alerting:slo.rules.burnRate/observability/rule/getRuleState", + "alerting:slo.rules.burnRate/observability/rule/getAlertSummary", + "alerting:slo.rules.burnRate/observability/rule/getExecutionLog", + "alerting:slo.rules.burnRate/observability/rule/getActionErrorLog", + "alerting:slo.rules.burnRate/observability/rule/find", + "alerting:slo.rules.burnRate/observability/rule/getRuleExecutionKPI", + "alerting:slo.rules.burnRate/observability/rule/getBackfill", + "alerting:slo.rules.burnRate/observability/rule/findBackfill", + "alerting:slo.rules.burnRate/alerts/rule/get", + "alerting:slo.rules.burnRate/alerts/rule/getRuleState", + "alerting:slo.rules.burnRate/alerts/rule/getAlertSummary", + "alerting:slo.rules.burnRate/alerts/rule/getExecutionLog", + "alerting:slo.rules.burnRate/alerts/rule/getActionErrorLog", + "alerting:slo.rules.burnRate/alerts/rule/find", + "alerting:slo.rules.burnRate/alerts/rule/getRuleExecutionKPI", + "alerting:slo.rules.burnRate/alerts/rule/getBackfill", + "alerting:slo.rules.burnRate/alerts/rule/findBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/get", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleState", + "alerting:observability.rules.custom_threshold/observability/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/observability/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/observability/rule/find", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/observability/rule/getBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/findBackfill", + "alerting:.es-query/observability/rule/get", + "alerting:.es-query/observability/rule/getRuleState", + "alerting:.es-query/observability/rule/getAlertSummary", + "alerting:.es-query/observability/rule/getExecutionLog", + "alerting:.es-query/observability/rule/getActionErrorLog", + "alerting:.es-query/observability/rule/find", + "alerting:.es-query/observability/rule/getRuleExecutionKPI", + "alerting:.es-query/observability/rule/getBackfill", + "alerting:.es-query/observability/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/findBackfill", "alerting:apm.error_rate/observability/alert/get", "alerting:apm.error_rate/observability/alert/find", "alerting:apm.error_rate/observability/alert/getAuthorizedAlertsIndices", @@ -1791,10 +3529,90 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/find", "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/getAuthorizedAlertsIndices", "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/getAlertSummary", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/get", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/find", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/getAlertSummary", "alerting:xpack.synthetics.alerts.tls/observability/alert/get", "alerting:xpack.synthetics.alerts.tls/observability/alert/find", "alerting:xpack.synthetics.alerts.tls/observability/alert/getAuthorizedAlertsIndices", "alerting:xpack.synthetics.alerts.tls/observability/alert/getAlertSummary", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/get", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/find", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/getAlertSummary", + "alerting:metrics.alert.threshold/observability/alert/get", + "alerting:metrics.alert.threshold/observability/alert/find", + "alerting:metrics.alert.threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.threshold/observability/alert/getAlertSummary", + "alerting:metrics.alert.threshold/alerts/alert/get", + "alerting:metrics.alert.threshold/alerts/alert/find", + "alerting:metrics.alert.threshold/alerts/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.threshold/alerts/alert/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/alert/get", + "alerting:metrics.alert.inventory.threshold/observability/alert/find", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/alerts/alert/get", + "alerting:metrics.alert.inventory.threshold/alerts/alert/find", + "alerting:metrics.alert.inventory.threshold/alerts/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.inventory.threshold/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/observability/alert/get", + "alerting:xpack.uptime.alerts.tls/observability/alert/find", + "alerting:xpack.uptime.alerts.tls/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tls/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/alerts/alert/get", + "alerting:xpack.uptime.alerts.tls/alerts/alert/find", + "alerting:xpack.uptime.alerts.tls/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tls/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/get", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/find", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/get", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/find", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/get", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/find", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/get", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/find", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/get", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/find", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/get", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/find", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/getAlertSummary", + "alerting:logs.alert.document.count/observability/alert/get", + "alerting:logs.alert.document.count/observability/alert/find", + "alerting:logs.alert.document.count/observability/alert/getAuthorizedAlertsIndices", + "alerting:logs.alert.document.count/observability/alert/getAlertSummary", + "alerting:slo.rules.burnRate/observability/alert/get", + "alerting:slo.rules.burnRate/observability/alert/find", + "alerting:slo.rules.burnRate/observability/alert/getAuthorizedAlertsIndices", + "alerting:slo.rules.burnRate/observability/alert/getAlertSummary", + "alerting:slo.rules.burnRate/alerts/alert/get", + "alerting:slo.rules.burnRate/alerts/alert/find", + "alerting:slo.rules.burnRate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:slo.rules.burnRate/alerts/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/alert/get", + "alerting:observability.rules.custom_threshold/observability/alert/find", + "alerting:observability.rules.custom_threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/observability/alert/getAlertSummary", + "alerting:.es-query/observability/alert/get", + "alerting:.es-query/observability/alert/find", + "alerting:.es-query/observability/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/observability/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAlertSummary", ], "read": Array [ "login:", @@ -1844,6 +3662,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.error_rate/apm/rule/getRuleExecutionKPI", "alerting:apm.error_rate/apm/rule/getBackfill", "alerting:apm.error_rate/apm/rule/findBackfill", + "alerting:apm.error_rate/alerts/rule/get", + "alerting:apm.error_rate/alerts/rule/getRuleState", + "alerting:apm.error_rate/alerts/rule/getAlertSummary", + "alerting:apm.error_rate/alerts/rule/getExecutionLog", + "alerting:apm.error_rate/alerts/rule/getActionErrorLog", + "alerting:apm.error_rate/alerts/rule/find", + "alerting:apm.error_rate/alerts/rule/getRuleExecutionKPI", + "alerting:apm.error_rate/alerts/rule/getBackfill", + "alerting:apm.error_rate/alerts/rule/findBackfill", "alerting:apm.transaction_error_rate/apm/rule/get", "alerting:apm.transaction_error_rate/apm/rule/getRuleState", "alerting:apm.transaction_error_rate/apm/rule/getAlertSummary", @@ -1853,6 +3680,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.transaction_error_rate/apm/rule/getRuleExecutionKPI", "alerting:apm.transaction_error_rate/apm/rule/getBackfill", "alerting:apm.transaction_error_rate/apm/rule/findBackfill", + "alerting:apm.transaction_error_rate/alerts/rule/get", + "alerting:apm.transaction_error_rate/alerts/rule/getRuleState", + "alerting:apm.transaction_error_rate/alerts/rule/getAlertSummary", + "alerting:apm.transaction_error_rate/alerts/rule/getExecutionLog", + "alerting:apm.transaction_error_rate/alerts/rule/getActionErrorLog", + "alerting:apm.transaction_error_rate/alerts/rule/find", + "alerting:apm.transaction_error_rate/alerts/rule/getRuleExecutionKPI", + "alerting:apm.transaction_error_rate/alerts/rule/getBackfill", + "alerting:apm.transaction_error_rate/alerts/rule/findBackfill", "alerting:apm.transaction_duration/apm/rule/get", "alerting:apm.transaction_duration/apm/rule/getRuleState", "alerting:apm.transaction_duration/apm/rule/getAlertSummary", @@ -1862,6 +3698,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.transaction_duration/apm/rule/getRuleExecutionKPI", "alerting:apm.transaction_duration/apm/rule/getBackfill", "alerting:apm.transaction_duration/apm/rule/findBackfill", + "alerting:apm.transaction_duration/alerts/rule/get", + "alerting:apm.transaction_duration/alerts/rule/getRuleState", + "alerting:apm.transaction_duration/alerts/rule/getAlertSummary", + "alerting:apm.transaction_duration/alerts/rule/getExecutionLog", + "alerting:apm.transaction_duration/alerts/rule/getActionErrorLog", + "alerting:apm.transaction_duration/alerts/rule/find", + "alerting:apm.transaction_duration/alerts/rule/getRuleExecutionKPI", + "alerting:apm.transaction_duration/alerts/rule/getBackfill", + "alerting:apm.transaction_duration/alerts/rule/findBackfill", "alerting:apm.anomaly/apm/rule/get", "alerting:apm.anomaly/apm/rule/getRuleState", "alerting:apm.anomaly/apm/rule/getAlertSummary", @@ -1871,22 +3716,47 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.anomaly/apm/rule/getRuleExecutionKPI", "alerting:apm.anomaly/apm/rule/getBackfill", "alerting:apm.anomaly/apm/rule/findBackfill", + "alerting:apm.anomaly/alerts/rule/get", + "alerting:apm.anomaly/alerts/rule/getRuleState", + "alerting:apm.anomaly/alerts/rule/getAlertSummary", + "alerting:apm.anomaly/alerts/rule/getExecutionLog", + "alerting:apm.anomaly/alerts/rule/getActionErrorLog", + "alerting:apm.anomaly/alerts/rule/find", + "alerting:apm.anomaly/alerts/rule/getRuleExecutionKPI", + "alerting:apm.anomaly/alerts/rule/getBackfill", + "alerting:apm.anomaly/alerts/rule/findBackfill", "alerting:apm.error_rate/apm/alert/get", "alerting:apm.error_rate/apm/alert/find", "alerting:apm.error_rate/apm/alert/getAuthorizedAlertsIndices", "alerting:apm.error_rate/apm/alert/getAlertSummary", + "alerting:apm.error_rate/alerts/alert/get", + "alerting:apm.error_rate/alerts/alert/find", + "alerting:apm.error_rate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.error_rate/alerts/alert/getAlertSummary", "alerting:apm.transaction_error_rate/apm/alert/get", "alerting:apm.transaction_error_rate/apm/alert/find", "alerting:apm.transaction_error_rate/apm/alert/getAuthorizedAlertsIndices", "alerting:apm.transaction_error_rate/apm/alert/getAlertSummary", + "alerting:apm.transaction_error_rate/alerts/alert/get", + "alerting:apm.transaction_error_rate/alerts/alert/find", + "alerting:apm.transaction_error_rate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_error_rate/alerts/alert/getAlertSummary", "alerting:apm.transaction_duration/apm/alert/get", "alerting:apm.transaction_duration/apm/alert/find", "alerting:apm.transaction_duration/apm/alert/getAuthorizedAlertsIndices", "alerting:apm.transaction_duration/apm/alert/getAlertSummary", + "alerting:apm.transaction_duration/alerts/alert/get", + "alerting:apm.transaction_duration/alerts/alert/find", + "alerting:apm.transaction_duration/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_duration/alerts/alert/getAlertSummary", "alerting:apm.anomaly/apm/alert/get", "alerting:apm.anomaly/apm/alert/find", "alerting:apm.anomaly/apm/alert/getAuthorizedAlertsIndices", "alerting:apm.anomaly/apm/alert/getAlertSummary", + "alerting:apm.anomaly/alerts/alert/get", + "alerting:apm.anomaly/alerts/alert/find", + "alerting:apm.anomaly/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.anomaly/alerts/alert/getAlertSummary", "api:infra", "app:infra", "app:logs", @@ -1916,6 +3786,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:logs.alert.document.count/logs/rule/getRuleExecutionKPI", "alerting:logs.alert.document.count/logs/rule/getBackfill", "alerting:logs.alert.document.count/logs/rule/findBackfill", + "alerting:logs.alert.document.count/alerts/rule/get", + "alerting:logs.alert.document.count/alerts/rule/getRuleState", + "alerting:logs.alert.document.count/alerts/rule/getAlertSummary", + "alerting:logs.alert.document.count/alerts/rule/getExecutionLog", + "alerting:logs.alert.document.count/alerts/rule/getActionErrorLog", + "alerting:logs.alert.document.count/alerts/rule/find", + "alerting:logs.alert.document.count/alerts/rule/getRuleExecutionKPI", + "alerting:logs.alert.document.count/alerts/rule/getBackfill", + "alerting:logs.alert.document.count/alerts/rule/findBackfill", "alerting:.es-query/logs/rule/get", "alerting:.es-query/logs/rule/getRuleState", "alerting:.es-query/logs/rule/getAlertSummary", @@ -1925,6 +3804,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:.es-query/logs/rule/getRuleExecutionKPI", "alerting:.es-query/logs/rule/getBackfill", "alerting:.es-query/logs/rule/findBackfill", + "alerting:.es-query/alerts/rule/get", + "alerting:.es-query/alerts/rule/getRuleState", + "alerting:.es-query/alerts/rule/getAlertSummary", + "alerting:.es-query/alerts/rule/getExecutionLog", + "alerting:.es-query/alerts/rule/getActionErrorLog", + "alerting:.es-query/alerts/rule/find", + "alerting:.es-query/alerts/rule/getRuleExecutionKPI", + "alerting:.es-query/alerts/rule/getBackfill", + "alerting:.es-query/alerts/rule/findBackfill", "alerting:observability.rules.custom_threshold/logs/rule/get", "alerting:observability.rules.custom_threshold/logs/rule/getRuleState", "alerting:observability.rules.custom_threshold/logs/rule/getAlertSummary", @@ -1934,6 +3822,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:observability.rules.custom_threshold/logs/rule/getRuleExecutionKPI", "alerting:observability.rules.custom_threshold/logs/rule/getBackfill", "alerting:observability.rules.custom_threshold/logs/rule/findBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/get", + "alerting:observability.rules.custom_threshold/alerts/rule/getRuleState", + "alerting:observability.rules.custom_threshold/alerts/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/alerts/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/alerts/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/alerts/rule/find", + "alerting:observability.rules.custom_threshold/alerts/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/alerts/rule/getBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/findBackfill", "alerting:xpack.ml.anomaly_detection_alert/logs/rule/get", "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getRuleState", "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getAlertSummary", @@ -1943,71 +3840,51 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getRuleExecutionKPI", "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getBackfill", "alerting:xpack.ml.anomaly_detection_alert/logs/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/findBackfill", "alerting:logs.alert.document.count/logs/alert/get", "alerting:logs.alert.document.count/logs/alert/find", "alerting:logs.alert.document.count/logs/alert/getAuthorizedAlertsIndices", "alerting:logs.alert.document.count/logs/alert/getAlertSummary", + "alerting:logs.alert.document.count/alerts/alert/get", + "alerting:logs.alert.document.count/alerts/alert/find", + "alerting:logs.alert.document.count/alerts/alert/getAuthorizedAlertsIndices", + "alerting:logs.alert.document.count/alerts/alert/getAlertSummary", "alerting:.es-query/logs/alert/get", "alerting:.es-query/logs/alert/find", "alerting:.es-query/logs/alert/getAuthorizedAlertsIndices", "alerting:.es-query/logs/alert/getAlertSummary", + "alerting:.es-query/alerts/alert/get", + "alerting:.es-query/alerts/alert/find", + "alerting:.es-query/alerts/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/alerts/alert/getAlertSummary", "alerting:observability.rules.custom_threshold/logs/alert/get", "alerting:observability.rules.custom_threshold/logs/alert/find", "alerting:observability.rules.custom_threshold/logs/alert/getAuthorizedAlertsIndices", "alerting:observability.rules.custom_threshold/logs/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/alerts/alert/get", + "alerting:observability.rules.custom_threshold/alerts/alert/find", + "alerting:observability.rules.custom_threshold/alerts/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/alerts/alert/getAlertSummary", "alerting:xpack.ml.anomaly_detection_alert/logs/alert/get", "alerting:xpack.ml.anomaly_detection_alert/logs/alert/find", "alerting:xpack.ml.anomaly_detection_alert/logs/alert/getAuthorizedAlertsIndices", - "alerting:xpack.ml.anomaly_detection_alert/logs/alert/getAlertSummary", - "app:observability", - "ui:catalogue/observability", - "ui:navLinks/observability", - "ui:observability/read", - "alerting:slo.rules.burnRate/observability/rule/get", - "alerting:slo.rules.burnRate/observability/rule/getRuleState", - "alerting:slo.rules.burnRate/observability/rule/getAlertSummary", - "alerting:slo.rules.burnRate/observability/rule/getExecutionLog", - "alerting:slo.rules.burnRate/observability/rule/getActionErrorLog", - "alerting:slo.rules.burnRate/observability/rule/find", - "alerting:slo.rules.burnRate/observability/rule/getRuleExecutionKPI", - "alerting:slo.rules.burnRate/observability/rule/getBackfill", - "alerting:slo.rules.burnRate/observability/rule/findBackfill", - "alerting:observability.rules.custom_threshold/observability/rule/get", - "alerting:observability.rules.custom_threshold/observability/rule/getRuleState", - "alerting:observability.rules.custom_threshold/observability/rule/getAlertSummary", - "alerting:observability.rules.custom_threshold/observability/rule/getExecutionLog", - "alerting:observability.rules.custom_threshold/observability/rule/getActionErrorLog", - "alerting:observability.rules.custom_threshold/observability/rule/find", - "alerting:observability.rules.custom_threshold/observability/rule/getRuleExecutionKPI", - "alerting:observability.rules.custom_threshold/observability/rule/getBackfill", - "alerting:observability.rules.custom_threshold/observability/rule/findBackfill", - "alerting:.es-query/observability/rule/get", - "alerting:.es-query/observability/rule/getRuleState", - "alerting:.es-query/observability/rule/getAlertSummary", - "alerting:.es-query/observability/rule/getExecutionLog", - "alerting:.es-query/observability/rule/getActionErrorLog", - "alerting:.es-query/observability/rule/find", - "alerting:.es-query/observability/rule/getRuleExecutionKPI", - "alerting:.es-query/observability/rule/getBackfill", - "alerting:.es-query/observability/rule/findBackfill", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/get", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleState", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getAlertSummary", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getExecutionLog", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getActionErrorLog", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/find", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleExecutionKPI", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getBackfill", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/findBackfill", - "alerting:metrics.alert.inventory.threshold/observability/rule/get", - "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleState", - "alerting:metrics.alert.inventory.threshold/observability/rule/getAlertSummary", - "alerting:metrics.alert.inventory.threshold/observability/rule/getExecutionLog", - "alerting:metrics.alert.inventory.threshold/observability/rule/getActionErrorLog", - "alerting:metrics.alert.inventory.threshold/observability/rule/find", - "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleExecutionKPI", - "alerting:metrics.alert.inventory.threshold/observability/rule/getBackfill", - "alerting:metrics.alert.inventory.threshold/observability/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/logs/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/getAlertSummary", + "app:observability", + "ui:catalogue/observability", + "ui:navLinks/observability", + "ui:observability/read", "alerting:apm.error_rate/observability/rule/get", "alerting:apm.error_rate/observability/rule/getRuleState", "alerting:apm.error_rate/observability/rule/getAlertSummary", @@ -2053,6 +3930,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/getRuleExecutionKPI", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/getBackfill", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/findBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/get", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getRuleState", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getAlertSummary", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getExecutionLog", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getActionErrorLog", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/find", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/findBackfill", "alerting:xpack.synthetics.alerts.tls/observability/rule/get", "alerting:xpack.synthetics.alerts.tls/observability/rule/getRuleState", "alerting:xpack.synthetics.alerts.tls/observability/rule/getAlertSummary", @@ -2062,26 +3948,177 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.synthetics.alerts.tls/observability/rule/getRuleExecutionKPI", "alerting:xpack.synthetics.alerts.tls/observability/rule/getBackfill", "alerting:xpack.synthetics.alerts.tls/observability/rule/findBackfill", - "alerting:slo.rules.burnRate/observability/alert/get", - "alerting:slo.rules.burnRate/observability/alert/find", - "alerting:slo.rules.burnRate/observability/alert/getAuthorizedAlertsIndices", - "alerting:slo.rules.burnRate/observability/alert/getAlertSummary", - "alerting:observability.rules.custom_threshold/observability/alert/get", - "alerting:observability.rules.custom_threshold/observability/alert/find", - "alerting:observability.rules.custom_threshold/observability/alert/getAuthorizedAlertsIndices", - "alerting:observability.rules.custom_threshold/observability/alert/getAlertSummary", - "alerting:.es-query/observability/alert/get", - "alerting:.es-query/observability/alert/find", - "alerting:.es-query/observability/alert/getAuthorizedAlertsIndices", - "alerting:.es-query/observability/alert/getAlertSummary", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/get", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/find", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAuthorizedAlertsIndices", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAlertSummary", - "alerting:metrics.alert.inventory.threshold/observability/alert/get", - "alerting:metrics.alert.inventory.threshold/observability/alert/find", - "alerting:metrics.alert.inventory.threshold/observability/alert/getAuthorizedAlertsIndices", - "alerting:metrics.alert.inventory.threshold/observability/alert/getAlertSummary", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/get", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getRuleState", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getAlertSummary", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getExecutionLog", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getActionErrorLog", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/find", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getBackfill", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/findBackfill", + "alerting:metrics.alert.threshold/observability/rule/get", + "alerting:metrics.alert.threshold/observability/rule/getRuleState", + "alerting:metrics.alert.threshold/observability/rule/getAlertSummary", + "alerting:metrics.alert.threshold/observability/rule/getExecutionLog", + "alerting:metrics.alert.threshold/observability/rule/getActionErrorLog", + "alerting:metrics.alert.threshold/observability/rule/find", + "alerting:metrics.alert.threshold/observability/rule/getRuleExecutionKPI", + "alerting:metrics.alert.threshold/observability/rule/getBackfill", + "alerting:metrics.alert.threshold/observability/rule/findBackfill", + "alerting:metrics.alert.threshold/alerts/rule/get", + "alerting:metrics.alert.threshold/alerts/rule/getRuleState", + "alerting:metrics.alert.threshold/alerts/rule/getAlertSummary", + "alerting:metrics.alert.threshold/alerts/rule/getExecutionLog", + "alerting:metrics.alert.threshold/alerts/rule/getActionErrorLog", + "alerting:metrics.alert.threshold/alerts/rule/find", + "alerting:metrics.alert.threshold/alerts/rule/getRuleExecutionKPI", + "alerting:metrics.alert.threshold/alerts/rule/getBackfill", + "alerting:metrics.alert.threshold/alerts/rule/findBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/get", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleState", + "alerting:metrics.alert.inventory.threshold/observability/rule/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/rule/getExecutionLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/getActionErrorLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/find", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleExecutionKPI", + "alerting:metrics.alert.inventory.threshold/observability/rule/getBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/findBackfill", + "alerting:metrics.alert.inventory.threshold/alerts/rule/get", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getRuleState", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getExecutionLog", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getActionErrorLog", + "alerting:metrics.alert.inventory.threshold/alerts/rule/find", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getRuleExecutionKPI", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getBackfill", + "alerting:metrics.alert.inventory.threshold/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.tls/observability/rule/get", + "alerting:xpack.uptime.alerts.tls/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.tls/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tls/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tls/observability/rule/find", + "alerting:xpack.uptime.alerts.tls/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tls/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.tls/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.tls/alerts/rule/get", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tls/alerts/rule/find", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.tls/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/get", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/find", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/get", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/find", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/get", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/find", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/get", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/find", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/get", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/find", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/get", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/find", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/findBackfill", + "alerting:logs.alert.document.count/observability/rule/get", + "alerting:logs.alert.document.count/observability/rule/getRuleState", + "alerting:logs.alert.document.count/observability/rule/getAlertSummary", + "alerting:logs.alert.document.count/observability/rule/getExecutionLog", + "alerting:logs.alert.document.count/observability/rule/getActionErrorLog", + "alerting:logs.alert.document.count/observability/rule/find", + "alerting:logs.alert.document.count/observability/rule/getRuleExecutionKPI", + "alerting:logs.alert.document.count/observability/rule/getBackfill", + "alerting:logs.alert.document.count/observability/rule/findBackfill", + "alerting:slo.rules.burnRate/observability/rule/get", + "alerting:slo.rules.burnRate/observability/rule/getRuleState", + "alerting:slo.rules.burnRate/observability/rule/getAlertSummary", + "alerting:slo.rules.burnRate/observability/rule/getExecutionLog", + "alerting:slo.rules.burnRate/observability/rule/getActionErrorLog", + "alerting:slo.rules.burnRate/observability/rule/find", + "alerting:slo.rules.burnRate/observability/rule/getRuleExecutionKPI", + "alerting:slo.rules.burnRate/observability/rule/getBackfill", + "alerting:slo.rules.burnRate/observability/rule/findBackfill", + "alerting:slo.rules.burnRate/alerts/rule/get", + "alerting:slo.rules.burnRate/alerts/rule/getRuleState", + "alerting:slo.rules.burnRate/alerts/rule/getAlertSummary", + "alerting:slo.rules.burnRate/alerts/rule/getExecutionLog", + "alerting:slo.rules.burnRate/alerts/rule/getActionErrorLog", + "alerting:slo.rules.burnRate/alerts/rule/find", + "alerting:slo.rules.burnRate/alerts/rule/getRuleExecutionKPI", + "alerting:slo.rules.burnRate/alerts/rule/getBackfill", + "alerting:slo.rules.burnRate/alerts/rule/findBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/get", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleState", + "alerting:observability.rules.custom_threshold/observability/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/observability/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/observability/rule/find", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/observability/rule/getBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/findBackfill", + "alerting:.es-query/observability/rule/get", + "alerting:.es-query/observability/rule/getRuleState", + "alerting:.es-query/observability/rule/getAlertSummary", + "alerting:.es-query/observability/rule/getExecutionLog", + "alerting:.es-query/observability/rule/getActionErrorLog", + "alerting:.es-query/observability/rule/find", + "alerting:.es-query/observability/rule/getRuleExecutionKPI", + "alerting:.es-query/observability/rule/getBackfill", + "alerting:.es-query/observability/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/findBackfill", "alerting:apm.error_rate/observability/alert/get", "alerting:apm.error_rate/observability/alert/find", "alerting:apm.error_rate/observability/alert/getAuthorizedAlertsIndices", @@ -2102,10 +4139,90 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/find", "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/getAuthorizedAlertsIndices", "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/getAlertSummary", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/get", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/find", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/getAlertSummary", "alerting:xpack.synthetics.alerts.tls/observability/alert/get", "alerting:xpack.synthetics.alerts.tls/observability/alert/find", "alerting:xpack.synthetics.alerts.tls/observability/alert/getAuthorizedAlertsIndices", "alerting:xpack.synthetics.alerts.tls/observability/alert/getAlertSummary", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/get", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/find", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/getAlertSummary", + "alerting:metrics.alert.threshold/observability/alert/get", + "alerting:metrics.alert.threshold/observability/alert/find", + "alerting:metrics.alert.threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.threshold/observability/alert/getAlertSummary", + "alerting:metrics.alert.threshold/alerts/alert/get", + "alerting:metrics.alert.threshold/alerts/alert/find", + "alerting:metrics.alert.threshold/alerts/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.threshold/alerts/alert/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/alert/get", + "alerting:metrics.alert.inventory.threshold/observability/alert/find", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/alerts/alert/get", + "alerting:metrics.alert.inventory.threshold/alerts/alert/find", + "alerting:metrics.alert.inventory.threshold/alerts/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.inventory.threshold/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/observability/alert/get", + "alerting:xpack.uptime.alerts.tls/observability/alert/find", + "alerting:xpack.uptime.alerts.tls/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tls/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/alerts/alert/get", + "alerting:xpack.uptime.alerts.tls/alerts/alert/find", + "alerting:xpack.uptime.alerts.tls/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tls/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/get", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/find", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/get", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/find", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/get", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/find", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/get", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/find", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/get", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/find", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/get", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/find", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/getAlertSummary", + "alerting:logs.alert.document.count/observability/alert/get", + "alerting:logs.alert.document.count/observability/alert/find", + "alerting:logs.alert.document.count/observability/alert/getAuthorizedAlertsIndices", + "alerting:logs.alert.document.count/observability/alert/getAlertSummary", + "alerting:slo.rules.burnRate/observability/alert/get", + "alerting:slo.rules.burnRate/observability/alert/find", + "alerting:slo.rules.burnRate/observability/alert/getAuthorizedAlertsIndices", + "alerting:slo.rules.burnRate/observability/alert/getAlertSummary", + "alerting:slo.rules.burnRate/alerts/alert/get", + "alerting:slo.rules.burnRate/alerts/alert/find", + "alerting:slo.rules.burnRate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:slo.rules.burnRate/alerts/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/alert/get", + "alerting:observability.rules.custom_threshold/observability/alert/find", + "alerting:observability.rules.custom_threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/observability/alert/getAlertSummary", + "alerting:.es-query/observability/alert/get", + "alerting:.es-query/observability/alert/find", + "alerting:.es-query/observability/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/observability/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAlertSummary", ], "settings_save": Array [ "login:", @@ -2757,172 +4874,32 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:search-session/bulk_delete", "saved_object:search-session/share_to_space", "saved_object:index-pattern/bulk_get", - "saved_object:index-pattern/get", - "saved_object:index-pattern/find", - "saved_object:index-pattern/open_point_in_time", - "saved_object:index-pattern/close_point_in_time", - "saved_object:config/bulk_get", - "saved_object:config/get", - "saved_object:config/find", - "saved_object:config/open_point_in_time", - "saved_object:config/close_point_in_time", - "saved_object:config-global/bulk_get", - "saved_object:config-global/get", - "saved_object:config-global/find", - "saved_object:config-global/open_point_in_time", - "saved_object:config-global/close_point_in_time", - "ui:discover/show", - "ui:discover/save", - "ui:discover/saveQuery", - "ui:discover/createShortUrl", - "ui:discover/storeSearchSession", - "ui:discover/generateCsv", - "api:rac", - "app:observability", - "ui:catalogue/observability", - "ui:navLinks/observability", - "ui:observability/read", - "ui:observability/write", - "alerting:slo.rules.burnRate/observability/rule/get", - "alerting:slo.rules.burnRate/observability/rule/getRuleState", - "alerting:slo.rules.burnRate/observability/rule/getAlertSummary", - "alerting:slo.rules.burnRate/observability/rule/getExecutionLog", - "alerting:slo.rules.burnRate/observability/rule/getActionErrorLog", - "alerting:slo.rules.burnRate/observability/rule/find", - "alerting:slo.rules.burnRate/observability/rule/getRuleExecutionKPI", - "alerting:slo.rules.burnRate/observability/rule/getBackfill", - "alerting:slo.rules.burnRate/observability/rule/findBackfill", - "alerting:slo.rules.burnRate/observability/rule/create", - "alerting:slo.rules.burnRate/observability/rule/delete", - "alerting:slo.rules.burnRate/observability/rule/update", - "alerting:slo.rules.burnRate/observability/rule/updateApiKey", - "alerting:slo.rules.burnRate/observability/rule/enable", - "alerting:slo.rules.burnRate/observability/rule/disable", - "alerting:slo.rules.burnRate/observability/rule/muteAll", - "alerting:slo.rules.burnRate/observability/rule/unmuteAll", - "alerting:slo.rules.burnRate/observability/rule/muteAlert", - "alerting:slo.rules.burnRate/observability/rule/unmuteAlert", - "alerting:slo.rules.burnRate/observability/rule/snooze", - "alerting:slo.rules.burnRate/observability/rule/bulkEdit", - "alerting:slo.rules.burnRate/observability/rule/bulkDelete", - "alerting:slo.rules.burnRate/observability/rule/bulkEnable", - "alerting:slo.rules.burnRate/observability/rule/bulkDisable", - "alerting:slo.rules.burnRate/observability/rule/unsnooze", - "alerting:slo.rules.burnRate/observability/rule/runSoon", - "alerting:slo.rules.burnRate/observability/rule/scheduleBackfill", - "alerting:slo.rules.burnRate/observability/rule/deleteBackfill", - "alerting:observability.rules.custom_threshold/observability/rule/get", - "alerting:observability.rules.custom_threshold/observability/rule/getRuleState", - "alerting:observability.rules.custom_threshold/observability/rule/getAlertSummary", - "alerting:observability.rules.custom_threshold/observability/rule/getExecutionLog", - "alerting:observability.rules.custom_threshold/observability/rule/getActionErrorLog", - "alerting:observability.rules.custom_threshold/observability/rule/find", - "alerting:observability.rules.custom_threshold/observability/rule/getRuleExecutionKPI", - "alerting:observability.rules.custom_threshold/observability/rule/getBackfill", - "alerting:observability.rules.custom_threshold/observability/rule/findBackfill", - "alerting:observability.rules.custom_threshold/observability/rule/create", - "alerting:observability.rules.custom_threshold/observability/rule/delete", - "alerting:observability.rules.custom_threshold/observability/rule/update", - "alerting:observability.rules.custom_threshold/observability/rule/updateApiKey", - "alerting:observability.rules.custom_threshold/observability/rule/enable", - "alerting:observability.rules.custom_threshold/observability/rule/disable", - "alerting:observability.rules.custom_threshold/observability/rule/muteAll", - "alerting:observability.rules.custom_threshold/observability/rule/unmuteAll", - "alerting:observability.rules.custom_threshold/observability/rule/muteAlert", - "alerting:observability.rules.custom_threshold/observability/rule/unmuteAlert", - "alerting:observability.rules.custom_threshold/observability/rule/snooze", - "alerting:observability.rules.custom_threshold/observability/rule/bulkEdit", - "alerting:observability.rules.custom_threshold/observability/rule/bulkDelete", - "alerting:observability.rules.custom_threshold/observability/rule/bulkEnable", - "alerting:observability.rules.custom_threshold/observability/rule/bulkDisable", - "alerting:observability.rules.custom_threshold/observability/rule/unsnooze", - "alerting:observability.rules.custom_threshold/observability/rule/runSoon", - "alerting:observability.rules.custom_threshold/observability/rule/scheduleBackfill", - "alerting:observability.rules.custom_threshold/observability/rule/deleteBackfill", - "alerting:.es-query/observability/rule/get", - "alerting:.es-query/observability/rule/getRuleState", - "alerting:.es-query/observability/rule/getAlertSummary", - "alerting:.es-query/observability/rule/getExecutionLog", - "alerting:.es-query/observability/rule/getActionErrorLog", - "alerting:.es-query/observability/rule/find", - "alerting:.es-query/observability/rule/getRuleExecutionKPI", - "alerting:.es-query/observability/rule/getBackfill", - "alerting:.es-query/observability/rule/findBackfill", - "alerting:.es-query/observability/rule/create", - "alerting:.es-query/observability/rule/delete", - "alerting:.es-query/observability/rule/update", - "alerting:.es-query/observability/rule/updateApiKey", - "alerting:.es-query/observability/rule/enable", - "alerting:.es-query/observability/rule/disable", - "alerting:.es-query/observability/rule/muteAll", - "alerting:.es-query/observability/rule/unmuteAll", - "alerting:.es-query/observability/rule/muteAlert", - "alerting:.es-query/observability/rule/unmuteAlert", - "alerting:.es-query/observability/rule/snooze", - "alerting:.es-query/observability/rule/bulkEdit", - "alerting:.es-query/observability/rule/bulkDelete", - "alerting:.es-query/observability/rule/bulkEnable", - "alerting:.es-query/observability/rule/bulkDisable", - "alerting:.es-query/observability/rule/unsnooze", - "alerting:.es-query/observability/rule/runSoon", - "alerting:.es-query/observability/rule/scheduleBackfill", - "alerting:.es-query/observability/rule/deleteBackfill", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/get", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleState", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getAlertSummary", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getExecutionLog", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getActionErrorLog", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/find", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleExecutionKPI", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getBackfill", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/findBackfill", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/create", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/delete", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/update", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/updateApiKey", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/enable", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/disable", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/muteAll", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unmuteAll", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/muteAlert", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unmuteAlert", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/snooze", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkEdit", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkDelete", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkEnable", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkDisable", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unsnooze", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/runSoon", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/scheduleBackfill", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/deleteBackfill", - "alerting:metrics.alert.inventory.threshold/observability/rule/get", - "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleState", - "alerting:metrics.alert.inventory.threshold/observability/rule/getAlertSummary", - "alerting:metrics.alert.inventory.threshold/observability/rule/getExecutionLog", - "alerting:metrics.alert.inventory.threshold/observability/rule/getActionErrorLog", - "alerting:metrics.alert.inventory.threshold/observability/rule/find", - "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleExecutionKPI", - "alerting:metrics.alert.inventory.threshold/observability/rule/getBackfill", - "alerting:metrics.alert.inventory.threshold/observability/rule/findBackfill", - "alerting:metrics.alert.inventory.threshold/observability/rule/create", - "alerting:metrics.alert.inventory.threshold/observability/rule/delete", - "alerting:metrics.alert.inventory.threshold/observability/rule/update", - "alerting:metrics.alert.inventory.threshold/observability/rule/updateApiKey", - "alerting:metrics.alert.inventory.threshold/observability/rule/enable", - "alerting:metrics.alert.inventory.threshold/observability/rule/disable", - "alerting:metrics.alert.inventory.threshold/observability/rule/muteAll", - "alerting:metrics.alert.inventory.threshold/observability/rule/unmuteAll", - "alerting:metrics.alert.inventory.threshold/observability/rule/muteAlert", - "alerting:metrics.alert.inventory.threshold/observability/rule/unmuteAlert", - "alerting:metrics.alert.inventory.threshold/observability/rule/snooze", - "alerting:metrics.alert.inventory.threshold/observability/rule/bulkEdit", - "alerting:metrics.alert.inventory.threshold/observability/rule/bulkDelete", - "alerting:metrics.alert.inventory.threshold/observability/rule/bulkEnable", - "alerting:metrics.alert.inventory.threshold/observability/rule/bulkDisable", - "alerting:metrics.alert.inventory.threshold/observability/rule/unsnooze", - "alerting:metrics.alert.inventory.threshold/observability/rule/runSoon", - "alerting:metrics.alert.inventory.threshold/observability/rule/scheduleBackfill", - "alerting:metrics.alert.inventory.threshold/observability/rule/deleteBackfill", + "saved_object:index-pattern/get", + "saved_object:index-pattern/find", + "saved_object:index-pattern/open_point_in_time", + "saved_object:index-pattern/close_point_in_time", + "saved_object:config/bulk_get", + "saved_object:config/get", + "saved_object:config/find", + "saved_object:config/open_point_in_time", + "saved_object:config/close_point_in_time", + "saved_object:config-global/bulk_get", + "saved_object:config-global/get", + "saved_object:config-global/find", + "saved_object:config-global/open_point_in_time", + "saved_object:config-global/close_point_in_time", + "ui:discover/show", + "ui:discover/save", + "ui:discover/saveQuery", + "ui:discover/createShortUrl", + "ui:discover/storeSearchSession", + "ui:discover/generateCsv", + "api:rac", + "app:observability", + "ui:catalogue/observability", + "ui:navLinks/observability", + "ui:observability/read", + "ui:observability/write", "alerting:apm.error_rate/observability/rule/get", "alerting:apm.error_rate/observability/rule/getRuleState", "alerting:apm.error_rate/observability/rule/getAlertSummary", @@ -2951,6 +4928,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.error_rate/observability/rule/runSoon", "alerting:apm.error_rate/observability/rule/scheduleBackfill", "alerting:apm.error_rate/observability/rule/deleteBackfill", + "alerting:apm.error_rate/alerts/rule/get", + "alerting:apm.error_rate/alerts/rule/getRuleState", + "alerting:apm.error_rate/alerts/rule/getAlertSummary", + "alerting:apm.error_rate/alerts/rule/getExecutionLog", + "alerting:apm.error_rate/alerts/rule/getActionErrorLog", + "alerting:apm.error_rate/alerts/rule/find", + "alerting:apm.error_rate/alerts/rule/getRuleExecutionKPI", + "alerting:apm.error_rate/alerts/rule/getBackfill", + "alerting:apm.error_rate/alerts/rule/findBackfill", + "alerting:apm.error_rate/alerts/rule/create", + "alerting:apm.error_rate/alerts/rule/delete", + "alerting:apm.error_rate/alerts/rule/update", + "alerting:apm.error_rate/alerts/rule/updateApiKey", + "alerting:apm.error_rate/alerts/rule/enable", + "alerting:apm.error_rate/alerts/rule/disable", + "alerting:apm.error_rate/alerts/rule/muteAll", + "alerting:apm.error_rate/alerts/rule/unmuteAll", + "alerting:apm.error_rate/alerts/rule/muteAlert", + "alerting:apm.error_rate/alerts/rule/unmuteAlert", + "alerting:apm.error_rate/alerts/rule/snooze", + "alerting:apm.error_rate/alerts/rule/bulkEdit", + "alerting:apm.error_rate/alerts/rule/bulkDelete", + "alerting:apm.error_rate/alerts/rule/bulkEnable", + "alerting:apm.error_rate/alerts/rule/bulkDisable", + "alerting:apm.error_rate/alerts/rule/unsnooze", + "alerting:apm.error_rate/alerts/rule/runSoon", + "alerting:apm.error_rate/alerts/rule/scheduleBackfill", + "alerting:apm.error_rate/alerts/rule/deleteBackfill", "alerting:apm.transaction_error_rate/observability/rule/get", "alerting:apm.transaction_error_rate/observability/rule/getRuleState", "alerting:apm.transaction_error_rate/observability/rule/getAlertSummary", @@ -2979,6 +4984,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.transaction_error_rate/observability/rule/runSoon", "alerting:apm.transaction_error_rate/observability/rule/scheduleBackfill", "alerting:apm.transaction_error_rate/observability/rule/deleteBackfill", + "alerting:apm.transaction_error_rate/alerts/rule/get", + "alerting:apm.transaction_error_rate/alerts/rule/getRuleState", + "alerting:apm.transaction_error_rate/alerts/rule/getAlertSummary", + "alerting:apm.transaction_error_rate/alerts/rule/getExecutionLog", + "alerting:apm.transaction_error_rate/alerts/rule/getActionErrorLog", + "alerting:apm.transaction_error_rate/alerts/rule/find", + "alerting:apm.transaction_error_rate/alerts/rule/getRuleExecutionKPI", + "alerting:apm.transaction_error_rate/alerts/rule/getBackfill", + "alerting:apm.transaction_error_rate/alerts/rule/findBackfill", + "alerting:apm.transaction_error_rate/alerts/rule/create", + "alerting:apm.transaction_error_rate/alerts/rule/delete", + "alerting:apm.transaction_error_rate/alerts/rule/update", + "alerting:apm.transaction_error_rate/alerts/rule/updateApiKey", + "alerting:apm.transaction_error_rate/alerts/rule/enable", + "alerting:apm.transaction_error_rate/alerts/rule/disable", + "alerting:apm.transaction_error_rate/alerts/rule/muteAll", + "alerting:apm.transaction_error_rate/alerts/rule/unmuteAll", + "alerting:apm.transaction_error_rate/alerts/rule/muteAlert", + "alerting:apm.transaction_error_rate/alerts/rule/unmuteAlert", + "alerting:apm.transaction_error_rate/alerts/rule/snooze", + "alerting:apm.transaction_error_rate/alerts/rule/bulkEdit", + "alerting:apm.transaction_error_rate/alerts/rule/bulkDelete", + "alerting:apm.transaction_error_rate/alerts/rule/bulkEnable", + "alerting:apm.transaction_error_rate/alerts/rule/bulkDisable", + "alerting:apm.transaction_error_rate/alerts/rule/unsnooze", + "alerting:apm.transaction_error_rate/alerts/rule/runSoon", + "alerting:apm.transaction_error_rate/alerts/rule/scheduleBackfill", + "alerting:apm.transaction_error_rate/alerts/rule/deleteBackfill", "alerting:apm.transaction_duration/observability/rule/get", "alerting:apm.transaction_duration/observability/rule/getRuleState", "alerting:apm.transaction_duration/observability/rule/getAlertSummary", @@ -3007,6 +5040,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.transaction_duration/observability/rule/runSoon", "alerting:apm.transaction_duration/observability/rule/scheduleBackfill", "alerting:apm.transaction_duration/observability/rule/deleteBackfill", + "alerting:apm.transaction_duration/alerts/rule/get", + "alerting:apm.transaction_duration/alerts/rule/getRuleState", + "alerting:apm.transaction_duration/alerts/rule/getAlertSummary", + "alerting:apm.transaction_duration/alerts/rule/getExecutionLog", + "alerting:apm.transaction_duration/alerts/rule/getActionErrorLog", + "alerting:apm.transaction_duration/alerts/rule/find", + "alerting:apm.transaction_duration/alerts/rule/getRuleExecutionKPI", + "alerting:apm.transaction_duration/alerts/rule/getBackfill", + "alerting:apm.transaction_duration/alerts/rule/findBackfill", + "alerting:apm.transaction_duration/alerts/rule/create", + "alerting:apm.transaction_duration/alerts/rule/delete", + "alerting:apm.transaction_duration/alerts/rule/update", + "alerting:apm.transaction_duration/alerts/rule/updateApiKey", + "alerting:apm.transaction_duration/alerts/rule/enable", + "alerting:apm.transaction_duration/alerts/rule/disable", + "alerting:apm.transaction_duration/alerts/rule/muteAll", + "alerting:apm.transaction_duration/alerts/rule/unmuteAll", + "alerting:apm.transaction_duration/alerts/rule/muteAlert", + "alerting:apm.transaction_duration/alerts/rule/unmuteAlert", + "alerting:apm.transaction_duration/alerts/rule/snooze", + "alerting:apm.transaction_duration/alerts/rule/bulkEdit", + "alerting:apm.transaction_duration/alerts/rule/bulkDelete", + "alerting:apm.transaction_duration/alerts/rule/bulkEnable", + "alerting:apm.transaction_duration/alerts/rule/bulkDisable", + "alerting:apm.transaction_duration/alerts/rule/unsnooze", + "alerting:apm.transaction_duration/alerts/rule/runSoon", + "alerting:apm.transaction_duration/alerts/rule/scheduleBackfill", + "alerting:apm.transaction_duration/alerts/rule/deleteBackfill", "alerting:apm.anomaly/observability/rule/get", "alerting:apm.anomaly/observability/rule/getRuleState", "alerting:apm.anomaly/observability/rule/getAlertSummary", @@ -3035,6 +5096,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.anomaly/observability/rule/runSoon", "alerting:apm.anomaly/observability/rule/scheduleBackfill", "alerting:apm.anomaly/observability/rule/deleteBackfill", + "alerting:apm.anomaly/alerts/rule/get", + "alerting:apm.anomaly/alerts/rule/getRuleState", + "alerting:apm.anomaly/alerts/rule/getAlertSummary", + "alerting:apm.anomaly/alerts/rule/getExecutionLog", + "alerting:apm.anomaly/alerts/rule/getActionErrorLog", + "alerting:apm.anomaly/alerts/rule/find", + "alerting:apm.anomaly/alerts/rule/getRuleExecutionKPI", + "alerting:apm.anomaly/alerts/rule/getBackfill", + "alerting:apm.anomaly/alerts/rule/findBackfill", + "alerting:apm.anomaly/alerts/rule/create", + "alerting:apm.anomaly/alerts/rule/delete", + "alerting:apm.anomaly/alerts/rule/update", + "alerting:apm.anomaly/alerts/rule/updateApiKey", + "alerting:apm.anomaly/alerts/rule/enable", + "alerting:apm.anomaly/alerts/rule/disable", + "alerting:apm.anomaly/alerts/rule/muteAll", + "alerting:apm.anomaly/alerts/rule/unmuteAll", + "alerting:apm.anomaly/alerts/rule/muteAlert", + "alerting:apm.anomaly/alerts/rule/unmuteAlert", + "alerting:apm.anomaly/alerts/rule/snooze", + "alerting:apm.anomaly/alerts/rule/bulkEdit", + "alerting:apm.anomaly/alerts/rule/bulkDelete", + "alerting:apm.anomaly/alerts/rule/bulkEnable", + "alerting:apm.anomaly/alerts/rule/bulkDisable", + "alerting:apm.anomaly/alerts/rule/unsnooze", + "alerting:apm.anomaly/alerts/rule/runSoon", + "alerting:apm.anomaly/alerts/rule/scheduleBackfill", + "alerting:apm.anomaly/alerts/rule/deleteBackfill", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/get", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/getRuleState", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/getAlertSummary", @@ -3063,6 +5152,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/runSoon", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/scheduleBackfill", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/deleteBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/get", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getRuleState", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getAlertSummary", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getExecutionLog", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getActionErrorLog", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/find", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/findBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/create", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/delete", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/update", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/updateApiKey", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/enable", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/disable", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/muteAll", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/unmuteAll", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/muteAlert", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/unmuteAlert", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/snooze", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/bulkEdit", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/bulkDelete", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/bulkEnable", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/bulkDisable", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/unsnooze", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/runSoon", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/scheduleBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/deleteBackfill", "alerting:xpack.synthetics.alerts.tls/observability/rule/get", "alerting:xpack.synthetics.alerts.tls/observability/rule/getRuleState", "alerting:xpack.synthetics.alerts.tls/observability/rule/getAlertSummary", @@ -3091,141 +5208,426 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.synthetics.alerts.tls/observability/rule/runSoon", "alerting:xpack.synthetics.alerts.tls/observability/rule/scheduleBackfill", "alerting:xpack.synthetics.alerts.tls/observability/rule/deleteBackfill", - "alerting:slo.rules.burnRate/observability/alert/get", - "alerting:slo.rules.burnRate/observability/alert/find", - "alerting:slo.rules.burnRate/observability/alert/getAuthorizedAlertsIndices", - "alerting:slo.rules.burnRate/observability/alert/getAlertSummary", - "alerting:slo.rules.burnRate/observability/alert/update", - "alerting:observability.rules.custom_threshold/observability/alert/get", - "alerting:observability.rules.custom_threshold/observability/alert/find", - "alerting:observability.rules.custom_threshold/observability/alert/getAuthorizedAlertsIndices", - "alerting:observability.rules.custom_threshold/observability/alert/getAlertSummary", - "alerting:observability.rules.custom_threshold/observability/alert/update", - "alerting:.es-query/observability/alert/get", - "alerting:.es-query/observability/alert/find", - "alerting:.es-query/observability/alert/getAuthorizedAlertsIndices", - "alerting:.es-query/observability/alert/getAlertSummary", - "alerting:.es-query/observability/alert/update", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/get", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/find", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAuthorizedAlertsIndices", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAlertSummary", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/update", - "alerting:metrics.alert.inventory.threshold/observability/alert/get", - "alerting:metrics.alert.inventory.threshold/observability/alert/find", - "alerting:metrics.alert.inventory.threshold/observability/alert/getAuthorizedAlertsIndices", - "alerting:metrics.alert.inventory.threshold/observability/alert/getAlertSummary", - "alerting:metrics.alert.inventory.threshold/observability/alert/update", - "alerting:apm.error_rate/observability/alert/get", - "alerting:apm.error_rate/observability/alert/find", - "alerting:apm.error_rate/observability/alert/getAuthorizedAlertsIndices", - "alerting:apm.error_rate/observability/alert/getAlertSummary", - "alerting:apm.error_rate/observability/alert/update", - "alerting:apm.transaction_error_rate/observability/alert/get", - "alerting:apm.transaction_error_rate/observability/alert/find", - "alerting:apm.transaction_error_rate/observability/alert/getAuthorizedAlertsIndices", - "alerting:apm.transaction_error_rate/observability/alert/getAlertSummary", - "alerting:apm.transaction_error_rate/observability/alert/update", - "alerting:apm.transaction_duration/observability/alert/get", - "alerting:apm.transaction_duration/observability/alert/find", - "alerting:apm.transaction_duration/observability/alert/getAuthorizedAlertsIndices", - "alerting:apm.transaction_duration/observability/alert/getAlertSummary", - "alerting:apm.transaction_duration/observability/alert/update", - "alerting:apm.anomaly/observability/alert/get", - "alerting:apm.anomaly/observability/alert/find", - "alerting:apm.anomaly/observability/alert/getAuthorizedAlertsIndices", - "alerting:apm.anomaly/observability/alert/getAlertSummary", - "alerting:apm.anomaly/observability/alert/update", - "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/get", - "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/find", - "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/getAuthorizedAlertsIndices", - "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/getAlertSummary", - "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/update", - "alerting:xpack.synthetics.alerts.tls/observability/alert/get", - "alerting:xpack.synthetics.alerts.tls/observability/alert/find", - "alerting:xpack.synthetics.alerts.tls/observability/alert/getAuthorizedAlertsIndices", - "alerting:xpack.synthetics.alerts.tls/observability/alert/getAlertSummary", - "alerting:xpack.synthetics.alerts.tls/observability/alert/update", - ], - "generate_report": Array [ - "login:", - "api:generateReport", - "ui:management/insightsAndAlerting/reporting", - "ui:discover/generateCsv", - ], - "minimal_all": Array [ - "login:", - "api:fileUpload:analyzeFile", - "app:discover", - "app:kibana", - "ui:catalogue/discover", - "ui:navLinks/discover", - "ui:navLinks/kibana", - "saved_object:search/bulk_get", - "saved_object:search/get", - "saved_object:search/find", - "saved_object:search/open_point_in_time", - "saved_object:search/close_point_in_time", - "saved_object:search/create", - "saved_object:search/bulk_create", - "saved_object:search/update", - "saved_object:search/bulk_update", - "saved_object:search/delete", - "saved_object:search/bulk_delete", - "saved_object:search/share_to_space", - "saved_object:query/bulk_get", - "saved_object:query/get", - "saved_object:query/find", - "saved_object:query/open_point_in_time", - "saved_object:query/close_point_in_time", - "saved_object:query/create", - "saved_object:query/bulk_create", - "saved_object:query/update", - "saved_object:query/bulk_update", - "saved_object:query/delete", - "saved_object:query/bulk_delete", - "saved_object:query/share_to_space", - "saved_object:telemetry/bulk_get", - "saved_object:telemetry/get", - "saved_object:telemetry/find", - "saved_object:telemetry/open_point_in_time", - "saved_object:telemetry/close_point_in_time", - "saved_object:telemetry/create", - "saved_object:telemetry/bulk_create", - "saved_object:telemetry/update", - "saved_object:telemetry/bulk_update", - "saved_object:telemetry/delete", - "saved_object:telemetry/bulk_delete", - "saved_object:telemetry/share_to_space", - "saved_object:index-pattern/bulk_get", - "saved_object:index-pattern/get", - "saved_object:index-pattern/find", - "saved_object:index-pattern/open_point_in_time", - "saved_object:index-pattern/close_point_in_time", - "saved_object:config/bulk_get", - "saved_object:config/get", - "saved_object:config/find", - "saved_object:config/open_point_in_time", - "saved_object:config/close_point_in_time", - "saved_object:config-global/bulk_get", - "saved_object:config-global/get", - "saved_object:config-global/find", - "saved_object:config-global/open_point_in_time", - "saved_object:config-global/close_point_in_time", - "saved_object:url/bulk_get", - "saved_object:url/get", - "saved_object:url/find", - "saved_object:url/open_point_in_time", - "saved_object:url/close_point_in_time", - "ui:discover/show", - "ui:discover/save", - "ui:discover/saveQuery", - "api:rac", - "app:observability", - "ui:catalogue/observability", - "ui:navLinks/observability", - "ui:observability/read", - "ui:observability/write", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/get", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getRuleState", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getAlertSummary", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getExecutionLog", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getActionErrorLog", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/find", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getBackfill", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/findBackfill", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/create", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/delete", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/update", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/updateApiKey", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/enable", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/disable", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/muteAll", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/unmuteAll", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/muteAlert", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/unmuteAlert", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/snooze", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/bulkEdit", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/bulkDelete", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/bulkEnable", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/bulkDisable", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/unsnooze", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/runSoon", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/scheduleBackfill", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/deleteBackfill", + "alerting:metrics.alert.threshold/observability/rule/get", + "alerting:metrics.alert.threshold/observability/rule/getRuleState", + "alerting:metrics.alert.threshold/observability/rule/getAlertSummary", + "alerting:metrics.alert.threshold/observability/rule/getExecutionLog", + "alerting:metrics.alert.threshold/observability/rule/getActionErrorLog", + "alerting:metrics.alert.threshold/observability/rule/find", + "alerting:metrics.alert.threshold/observability/rule/getRuleExecutionKPI", + "alerting:metrics.alert.threshold/observability/rule/getBackfill", + "alerting:metrics.alert.threshold/observability/rule/findBackfill", + "alerting:metrics.alert.threshold/observability/rule/create", + "alerting:metrics.alert.threshold/observability/rule/delete", + "alerting:metrics.alert.threshold/observability/rule/update", + "alerting:metrics.alert.threshold/observability/rule/updateApiKey", + "alerting:metrics.alert.threshold/observability/rule/enable", + "alerting:metrics.alert.threshold/observability/rule/disable", + "alerting:metrics.alert.threshold/observability/rule/muteAll", + "alerting:metrics.alert.threshold/observability/rule/unmuteAll", + "alerting:metrics.alert.threshold/observability/rule/muteAlert", + "alerting:metrics.alert.threshold/observability/rule/unmuteAlert", + "alerting:metrics.alert.threshold/observability/rule/snooze", + "alerting:metrics.alert.threshold/observability/rule/bulkEdit", + "alerting:metrics.alert.threshold/observability/rule/bulkDelete", + "alerting:metrics.alert.threshold/observability/rule/bulkEnable", + "alerting:metrics.alert.threshold/observability/rule/bulkDisable", + "alerting:metrics.alert.threshold/observability/rule/unsnooze", + "alerting:metrics.alert.threshold/observability/rule/runSoon", + "alerting:metrics.alert.threshold/observability/rule/scheduleBackfill", + "alerting:metrics.alert.threshold/observability/rule/deleteBackfill", + "alerting:metrics.alert.threshold/alerts/rule/get", + "alerting:metrics.alert.threshold/alerts/rule/getRuleState", + "alerting:metrics.alert.threshold/alerts/rule/getAlertSummary", + "alerting:metrics.alert.threshold/alerts/rule/getExecutionLog", + "alerting:metrics.alert.threshold/alerts/rule/getActionErrorLog", + "alerting:metrics.alert.threshold/alerts/rule/find", + "alerting:metrics.alert.threshold/alerts/rule/getRuleExecutionKPI", + "alerting:metrics.alert.threshold/alerts/rule/getBackfill", + "alerting:metrics.alert.threshold/alerts/rule/findBackfill", + "alerting:metrics.alert.threshold/alerts/rule/create", + "alerting:metrics.alert.threshold/alerts/rule/delete", + "alerting:metrics.alert.threshold/alerts/rule/update", + "alerting:metrics.alert.threshold/alerts/rule/updateApiKey", + "alerting:metrics.alert.threshold/alerts/rule/enable", + "alerting:metrics.alert.threshold/alerts/rule/disable", + "alerting:metrics.alert.threshold/alerts/rule/muteAll", + "alerting:metrics.alert.threshold/alerts/rule/unmuteAll", + "alerting:metrics.alert.threshold/alerts/rule/muteAlert", + "alerting:metrics.alert.threshold/alerts/rule/unmuteAlert", + "alerting:metrics.alert.threshold/alerts/rule/snooze", + "alerting:metrics.alert.threshold/alerts/rule/bulkEdit", + "alerting:metrics.alert.threshold/alerts/rule/bulkDelete", + "alerting:metrics.alert.threshold/alerts/rule/bulkEnable", + "alerting:metrics.alert.threshold/alerts/rule/bulkDisable", + "alerting:metrics.alert.threshold/alerts/rule/unsnooze", + "alerting:metrics.alert.threshold/alerts/rule/runSoon", + "alerting:metrics.alert.threshold/alerts/rule/scheduleBackfill", + "alerting:metrics.alert.threshold/alerts/rule/deleteBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/get", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleState", + "alerting:metrics.alert.inventory.threshold/observability/rule/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/rule/getExecutionLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/getActionErrorLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/find", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleExecutionKPI", + "alerting:metrics.alert.inventory.threshold/observability/rule/getBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/findBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/create", + "alerting:metrics.alert.inventory.threshold/observability/rule/delete", + "alerting:metrics.alert.inventory.threshold/observability/rule/update", + "alerting:metrics.alert.inventory.threshold/observability/rule/updateApiKey", + "alerting:metrics.alert.inventory.threshold/observability/rule/enable", + "alerting:metrics.alert.inventory.threshold/observability/rule/disable", + "alerting:metrics.alert.inventory.threshold/observability/rule/muteAll", + "alerting:metrics.alert.inventory.threshold/observability/rule/unmuteAll", + "alerting:metrics.alert.inventory.threshold/observability/rule/muteAlert", + "alerting:metrics.alert.inventory.threshold/observability/rule/unmuteAlert", + "alerting:metrics.alert.inventory.threshold/observability/rule/snooze", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkEdit", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkDelete", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkEnable", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkDisable", + "alerting:metrics.alert.inventory.threshold/observability/rule/unsnooze", + "alerting:metrics.alert.inventory.threshold/observability/rule/runSoon", + "alerting:metrics.alert.inventory.threshold/observability/rule/scheduleBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/deleteBackfill", + "alerting:metrics.alert.inventory.threshold/alerts/rule/get", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getRuleState", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getExecutionLog", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getActionErrorLog", + "alerting:metrics.alert.inventory.threshold/alerts/rule/find", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getRuleExecutionKPI", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getBackfill", + "alerting:metrics.alert.inventory.threshold/alerts/rule/findBackfill", + "alerting:metrics.alert.inventory.threshold/alerts/rule/create", + "alerting:metrics.alert.inventory.threshold/alerts/rule/delete", + "alerting:metrics.alert.inventory.threshold/alerts/rule/update", + "alerting:metrics.alert.inventory.threshold/alerts/rule/updateApiKey", + "alerting:metrics.alert.inventory.threshold/alerts/rule/enable", + "alerting:metrics.alert.inventory.threshold/alerts/rule/disable", + "alerting:metrics.alert.inventory.threshold/alerts/rule/muteAll", + "alerting:metrics.alert.inventory.threshold/alerts/rule/unmuteAll", + "alerting:metrics.alert.inventory.threshold/alerts/rule/muteAlert", + "alerting:metrics.alert.inventory.threshold/alerts/rule/unmuteAlert", + "alerting:metrics.alert.inventory.threshold/alerts/rule/snooze", + "alerting:metrics.alert.inventory.threshold/alerts/rule/bulkEdit", + "alerting:metrics.alert.inventory.threshold/alerts/rule/bulkDelete", + "alerting:metrics.alert.inventory.threshold/alerts/rule/bulkEnable", + "alerting:metrics.alert.inventory.threshold/alerts/rule/bulkDisable", + "alerting:metrics.alert.inventory.threshold/alerts/rule/unsnooze", + "alerting:metrics.alert.inventory.threshold/alerts/rule/runSoon", + "alerting:metrics.alert.inventory.threshold/alerts/rule/scheduleBackfill", + "alerting:metrics.alert.inventory.threshold/alerts/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.tls/observability/rule/get", + "alerting:xpack.uptime.alerts.tls/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.tls/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tls/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tls/observability/rule/find", + "alerting:xpack.uptime.alerts.tls/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tls/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.tls/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.tls/observability/rule/create", + "alerting:xpack.uptime.alerts.tls/observability/rule/delete", + "alerting:xpack.uptime.alerts.tls/observability/rule/update", + "alerting:xpack.uptime.alerts.tls/observability/rule/updateApiKey", + "alerting:xpack.uptime.alerts.tls/observability/rule/enable", + "alerting:xpack.uptime.alerts.tls/observability/rule/disable", + "alerting:xpack.uptime.alerts.tls/observability/rule/muteAll", + "alerting:xpack.uptime.alerts.tls/observability/rule/unmuteAll", + "alerting:xpack.uptime.alerts.tls/observability/rule/muteAlert", + "alerting:xpack.uptime.alerts.tls/observability/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.tls/observability/rule/snooze", + "alerting:xpack.uptime.alerts.tls/observability/rule/bulkEdit", + "alerting:xpack.uptime.alerts.tls/observability/rule/bulkDelete", + "alerting:xpack.uptime.alerts.tls/observability/rule/bulkEnable", + "alerting:xpack.uptime.alerts.tls/observability/rule/bulkDisable", + "alerting:xpack.uptime.alerts.tls/observability/rule/unsnooze", + "alerting:xpack.uptime.alerts.tls/observability/rule/runSoon", + "alerting:xpack.uptime.alerts.tls/observability/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.tls/observability/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.tls/alerts/rule/get", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tls/alerts/rule/find", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.tls/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.tls/alerts/rule/create", + "alerting:xpack.uptime.alerts.tls/alerts/rule/delete", + "alerting:xpack.uptime.alerts.tls/alerts/rule/update", + "alerting:xpack.uptime.alerts.tls/alerts/rule/updateApiKey", + "alerting:xpack.uptime.alerts.tls/alerts/rule/enable", + "alerting:xpack.uptime.alerts.tls/alerts/rule/disable", + "alerting:xpack.uptime.alerts.tls/alerts/rule/muteAll", + "alerting:xpack.uptime.alerts.tls/alerts/rule/unmuteAll", + "alerting:xpack.uptime.alerts.tls/alerts/rule/muteAlert", + "alerting:xpack.uptime.alerts.tls/alerts/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.tls/alerts/rule/snooze", + "alerting:xpack.uptime.alerts.tls/alerts/rule/bulkEdit", + "alerting:xpack.uptime.alerts.tls/alerts/rule/bulkDelete", + "alerting:xpack.uptime.alerts.tls/alerts/rule/bulkEnable", + "alerting:xpack.uptime.alerts.tls/alerts/rule/bulkDisable", + "alerting:xpack.uptime.alerts.tls/alerts/rule/unsnooze", + "alerting:xpack.uptime.alerts.tls/alerts/rule/runSoon", + "alerting:xpack.uptime.alerts.tls/alerts/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.tls/alerts/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/get", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/find", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/create", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/delete", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/update", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/updateApiKey", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/enable", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/disable", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/muteAll", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/unmuteAll", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/muteAlert", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/snooze", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/bulkEdit", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/bulkDelete", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/bulkEnable", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/bulkDisable", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/unsnooze", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/runSoon", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/get", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/find", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/create", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/delete", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/update", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/updateApiKey", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/enable", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/disable", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/muteAll", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/unmuteAll", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/muteAlert", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/snooze", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/bulkEdit", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/bulkDelete", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/bulkEnable", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/bulkDisable", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/unsnooze", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/runSoon", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/get", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/find", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/create", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/delete", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/update", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/updateApiKey", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/enable", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/disable", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/muteAll", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/unmuteAll", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/muteAlert", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/snooze", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/bulkEdit", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/bulkDelete", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/bulkEnable", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/bulkDisable", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/unsnooze", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/runSoon", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/get", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/find", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/create", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/delete", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/update", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/updateApiKey", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/enable", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/disable", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/muteAll", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/unmuteAll", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/muteAlert", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/snooze", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/bulkEdit", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/bulkDelete", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/bulkEnable", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/bulkDisable", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/unsnooze", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/runSoon", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/get", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/find", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/create", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/delete", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/update", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/updateApiKey", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/enable", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/disable", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/muteAll", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/unmuteAll", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/muteAlert", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/snooze", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/bulkEdit", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/bulkDelete", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/bulkEnable", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/bulkDisable", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/unsnooze", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/runSoon", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/get", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/find", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/create", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/delete", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/update", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/updateApiKey", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/enable", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/disable", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/muteAll", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/unmuteAll", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/muteAlert", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/snooze", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/bulkEdit", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/bulkDelete", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/bulkEnable", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/bulkDisable", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/unsnooze", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/runSoon", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/deleteBackfill", + "alerting:logs.alert.document.count/observability/rule/get", + "alerting:logs.alert.document.count/observability/rule/getRuleState", + "alerting:logs.alert.document.count/observability/rule/getAlertSummary", + "alerting:logs.alert.document.count/observability/rule/getExecutionLog", + "alerting:logs.alert.document.count/observability/rule/getActionErrorLog", + "alerting:logs.alert.document.count/observability/rule/find", + "alerting:logs.alert.document.count/observability/rule/getRuleExecutionKPI", + "alerting:logs.alert.document.count/observability/rule/getBackfill", + "alerting:logs.alert.document.count/observability/rule/findBackfill", + "alerting:logs.alert.document.count/observability/rule/create", + "alerting:logs.alert.document.count/observability/rule/delete", + "alerting:logs.alert.document.count/observability/rule/update", + "alerting:logs.alert.document.count/observability/rule/updateApiKey", + "alerting:logs.alert.document.count/observability/rule/enable", + "alerting:logs.alert.document.count/observability/rule/disable", + "alerting:logs.alert.document.count/observability/rule/muteAll", + "alerting:logs.alert.document.count/observability/rule/unmuteAll", + "alerting:logs.alert.document.count/observability/rule/muteAlert", + "alerting:logs.alert.document.count/observability/rule/unmuteAlert", + "alerting:logs.alert.document.count/observability/rule/snooze", + "alerting:logs.alert.document.count/observability/rule/bulkEdit", + "alerting:logs.alert.document.count/observability/rule/bulkDelete", + "alerting:logs.alert.document.count/observability/rule/bulkEnable", + "alerting:logs.alert.document.count/observability/rule/bulkDisable", + "alerting:logs.alert.document.count/observability/rule/unsnooze", + "alerting:logs.alert.document.count/observability/rule/runSoon", + "alerting:logs.alert.document.count/observability/rule/scheduleBackfill", + "alerting:logs.alert.document.count/observability/rule/deleteBackfill", + "alerting:logs.alert.document.count/alerts/rule/get", + "alerting:logs.alert.document.count/alerts/rule/getRuleState", + "alerting:logs.alert.document.count/alerts/rule/getAlertSummary", + "alerting:logs.alert.document.count/alerts/rule/getExecutionLog", + "alerting:logs.alert.document.count/alerts/rule/getActionErrorLog", + "alerting:logs.alert.document.count/alerts/rule/find", + "alerting:logs.alert.document.count/alerts/rule/getRuleExecutionKPI", + "alerting:logs.alert.document.count/alerts/rule/getBackfill", + "alerting:logs.alert.document.count/alerts/rule/findBackfill", + "alerting:logs.alert.document.count/alerts/rule/create", + "alerting:logs.alert.document.count/alerts/rule/delete", + "alerting:logs.alert.document.count/alerts/rule/update", + "alerting:logs.alert.document.count/alerts/rule/updateApiKey", + "alerting:logs.alert.document.count/alerts/rule/enable", + "alerting:logs.alert.document.count/alerts/rule/disable", + "alerting:logs.alert.document.count/alerts/rule/muteAll", + "alerting:logs.alert.document.count/alerts/rule/unmuteAll", + "alerting:logs.alert.document.count/alerts/rule/muteAlert", + "alerting:logs.alert.document.count/alerts/rule/unmuteAlert", + "alerting:logs.alert.document.count/alerts/rule/snooze", + "alerting:logs.alert.document.count/alerts/rule/bulkEdit", + "alerting:logs.alert.document.count/alerts/rule/bulkDelete", + "alerting:logs.alert.document.count/alerts/rule/bulkEnable", + "alerting:logs.alert.document.count/alerts/rule/bulkDisable", + "alerting:logs.alert.document.count/alerts/rule/unsnooze", + "alerting:logs.alert.document.count/alerts/rule/runSoon", + "alerting:logs.alert.document.count/alerts/rule/scheduleBackfill", + "alerting:logs.alert.document.count/alerts/rule/deleteBackfill", "alerting:slo.rules.burnRate/observability/rule/get", "alerting:slo.rules.burnRate/observability/rule/getRuleState", "alerting:slo.rules.burnRate/observability/rule/getAlertSummary", @@ -3254,6 +5656,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:slo.rules.burnRate/observability/rule/runSoon", "alerting:slo.rules.burnRate/observability/rule/scheduleBackfill", "alerting:slo.rules.burnRate/observability/rule/deleteBackfill", + "alerting:slo.rules.burnRate/alerts/rule/get", + "alerting:slo.rules.burnRate/alerts/rule/getRuleState", + "alerting:slo.rules.burnRate/alerts/rule/getAlertSummary", + "alerting:slo.rules.burnRate/alerts/rule/getExecutionLog", + "alerting:slo.rules.burnRate/alerts/rule/getActionErrorLog", + "alerting:slo.rules.burnRate/alerts/rule/find", + "alerting:slo.rules.burnRate/alerts/rule/getRuleExecutionKPI", + "alerting:slo.rules.burnRate/alerts/rule/getBackfill", + "alerting:slo.rules.burnRate/alerts/rule/findBackfill", + "alerting:slo.rules.burnRate/alerts/rule/create", + "alerting:slo.rules.burnRate/alerts/rule/delete", + "alerting:slo.rules.burnRate/alerts/rule/update", + "alerting:slo.rules.burnRate/alerts/rule/updateApiKey", + "alerting:slo.rules.burnRate/alerts/rule/enable", + "alerting:slo.rules.burnRate/alerts/rule/disable", + "alerting:slo.rules.burnRate/alerts/rule/muteAll", + "alerting:slo.rules.burnRate/alerts/rule/unmuteAll", + "alerting:slo.rules.burnRate/alerts/rule/muteAlert", + "alerting:slo.rules.burnRate/alerts/rule/unmuteAlert", + "alerting:slo.rules.burnRate/alerts/rule/snooze", + "alerting:slo.rules.burnRate/alerts/rule/bulkEdit", + "alerting:slo.rules.burnRate/alerts/rule/bulkDelete", + "alerting:slo.rules.burnRate/alerts/rule/bulkEnable", + "alerting:slo.rules.burnRate/alerts/rule/bulkDisable", + "alerting:slo.rules.burnRate/alerts/rule/unsnooze", + "alerting:slo.rules.burnRate/alerts/rule/runSoon", + "alerting:slo.rules.burnRate/alerts/rule/scheduleBackfill", + "alerting:slo.rules.burnRate/alerts/rule/deleteBackfill", "alerting:observability.rules.custom_threshold/observability/rule/get", "alerting:observability.rules.custom_threshold/observability/rule/getRuleState", "alerting:observability.rules.custom_threshold/observability/rule/getAlertSummary", @@ -3282,6 +5712,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:observability.rules.custom_threshold/observability/rule/runSoon", "alerting:observability.rules.custom_threshold/observability/rule/scheduleBackfill", "alerting:observability.rules.custom_threshold/observability/rule/deleteBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/get", + "alerting:observability.rules.custom_threshold/alerts/rule/getRuleState", + "alerting:observability.rules.custom_threshold/alerts/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/alerts/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/alerts/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/alerts/rule/find", + "alerting:observability.rules.custom_threshold/alerts/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/alerts/rule/getBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/findBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/create", + "alerting:observability.rules.custom_threshold/alerts/rule/delete", + "alerting:observability.rules.custom_threshold/alerts/rule/update", + "alerting:observability.rules.custom_threshold/alerts/rule/updateApiKey", + "alerting:observability.rules.custom_threshold/alerts/rule/enable", + "alerting:observability.rules.custom_threshold/alerts/rule/disable", + "alerting:observability.rules.custom_threshold/alerts/rule/muteAll", + "alerting:observability.rules.custom_threshold/alerts/rule/unmuteAll", + "alerting:observability.rules.custom_threshold/alerts/rule/muteAlert", + "alerting:observability.rules.custom_threshold/alerts/rule/unmuteAlert", + "alerting:observability.rules.custom_threshold/alerts/rule/snooze", + "alerting:observability.rules.custom_threshold/alerts/rule/bulkEdit", + "alerting:observability.rules.custom_threshold/alerts/rule/bulkDelete", + "alerting:observability.rules.custom_threshold/alerts/rule/bulkEnable", + "alerting:observability.rules.custom_threshold/alerts/rule/bulkDisable", + "alerting:observability.rules.custom_threshold/alerts/rule/unsnooze", + "alerting:observability.rules.custom_threshold/alerts/rule/runSoon", + "alerting:observability.rules.custom_threshold/alerts/rule/scheduleBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/deleteBackfill", "alerting:.es-query/observability/rule/get", "alerting:.es-query/observability/rule/getRuleState", "alerting:.es-query/observability/rule/getAlertSummary", @@ -3310,6 +5768,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:.es-query/observability/rule/runSoon", "alerting:.es-query/observability/rule/scheduleBackfill", "alerting:.es-query/observability/rule/deleteBackfill", + "alerting:.es-query/alerts/rule/get", + "alerting:.es-query/alerts/rule/getRuleState", + "alerting:.es-query/alerts/rule/getAlertSummary", + "alerting:.es-query/alerts/rule/getExecutionLog", + "alerting:.es-query/alerts/rule/getActionErrorLog", + "alerting:.es-query/alerts/rule/find", + "alerting:.es-query/alerts/rule/getRuleExecutionKPI", + "alerting:.es-query/alerts/rule/getBackfill", + "alerting:.es-query/alerts/rule/findBackfill", + "alerting:.es-query/alerts/rule/create", + "alerting:.es-query/alerts/rule/delete", + "alerting:.es-query/alerts/rule/update", + "alerting:.es-query/alerts/rule/updateApiKey", + "alerting:.es-query/alerts/rule/enable", + "alerting:.es-query/alerts/rule/disable", + "alerting:.es-query/alerts/rule/muteAll", + "alerting:.es-query/alerts/rule/unmuteAll", + "alerting:.es-query/alerts/rule/muteAlert", + "alerting:.es-query/alerts/rule/unmuteAlert", + "alerting:.es-query/alerts/rule/snooze", + "alerting:.es-query/alerts/rule/bulkEdit", + "alerting:.es-query/alerts/rule/bulkDelete", + "alerting:.es-query/alerts/rule/bulkEnable", + "alerting:.es-query/alerts/rule/bulkDisable", + "alerting:.es-query/alerts/rule/unsnooze", + "alerting:.es-query/alerts/rule/runSoon", + "alerting:.es-query/alerts/rule/scheduleBackfill", + "alerting:.es-query/alerts/rule/deleteBackfill", "alerting:xpack.ml.anomaly_detection_alert/observability/rule/get", "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleState", "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getAlertSummary", @@ -3338,34 +5824,284 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.ml.anomaly_detection_alert/observability/rule/runSoon", "alerting:xpack.ml.anomaly_detection_alert/observability/rule/scheduleBackfill", "alerting:xpack.ml.anomaly_detection_alert/observability/rule/deleteBackfill", - "alerting:metrics.alert.inventory.threshold/observability/rule/get", - "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleState", - "alerting:metrics.alert.inventory.threshold/observability/rule/getAlertSummary", - "alerting:metrics.alert.inventory.threshold/observability/rule/getExecutionLog", - "alerting:metrics.alert.inventory.threshold/observability/rule/getActionErrorLog", - "alerting:metrics.alert.inventory.threshold/observability/rule/find", - "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleExecutionKPI", - "alerting:metrics.alert.inventory.threshold/observability/rule/getBackfill", - "alerting:metrics.alert.inventory.threshold/observability/rule/findBackfill", - "alerting:metrics.alert.inventory.threshold/observability/rule/create", - "alerting:metrics.alert.inventory.threshold/observability/rule/delete", - "alerting:metrics.alert.inventory.threshold/observability/rule/update", - "alerting:metrics.alert.inventory.threshold/observability/rule/updateApiKey", - "alerting:metrics.alert.inventory.threshold/observability/rule/enable", - "alerting:metrics.alert.inventory.threshold/observability/rule/disable", - "alerting:metrics.alert.inventory.threshold/observability/rule/muteAll", - "alerting:metrics.alert.inventory.threshold/observability/rule/unmuteAll", - "alerting:metrics.alert.inventory.threshold/observability/rule/muteAlert", - "alerting:metrics.alert.inventory.threshold/observability/rule/unmuteAlert", - "alerting:metrics.alert.inventory.threshold/observability/rule/snooze", - "alerting:metrics.alert.inventory.threshold/observability/rule/bulkEdit", - "alerting:metrics.alert.inventory.threshold/observability/rule/bulkDelete", - "alerting:metrics.alert.inventory.threshold/observability/rule/bulkEnable", - "alerting:metrics.alert.inventory.threshold/observability/rule/bulkDisable", - "alerting:metrics.alert.inventory.threshold/observability/rule/unsnooze", - "alerting:metrics.alert.inventory.threshold/observability/rule/runSoon", - "alerting:metrics.alert.inventory.threshold/observability/rule/scheduleBackfill", - "alerting:metrics.alert.inventory.threshold/observability/rule/deleteBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/create", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/delete", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/update", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/updateApiKey", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/enable", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/disable", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/muteAll", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/unmuteAll", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/muteAlert", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/unmuteAlert", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/snooze", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/bulkEdit", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/bulkDelete", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/bulkEnable", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/bulkDisable", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/unsnooze", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/runSoon", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/scheduleBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/deleteBackfill", + "alerting:apm.error_rate/observability/alert/get", + "alerting:apm.error_rate/observability/alert/find", + "alerting:apm.error_rate/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.error_rate/observability/alert/getAlertSummary", + "alerting:apm.error_rate/observability/alert/update", + "alerting:apm.error_rate/alerts/alert/get", + "alerting:apm.error_rate/alerts/alert/find", + "alerting:apm.error_rate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.error_rate/alerts/alert/getAlertSummary", + "alerting:apm.error_rate/alerts/alert/update", + "alerting:apm.transaction_error_rate/observability/alert/get", + "alerting:apm.transaction_error_rate/observability/alert/find", + "alerting:apm.transaction_error_rate/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_error_rate/observability/alert/getAlertSummary", + "alerting:apm.transaction_error_rate/observability/alert/update", + "alerting:apm.transaction_error_rate/alerts/alert/get", + "alerting:apm.transaction_error_rate/alerts/alert/find", + "alerting:apm.transaction_error_rate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_error_rate/alerts/alert/getAlertSummary", + "alerting:apm.transaction_error_rate/alerts/alert/update", + "alerting:apm.transaction_duration/observability/alert/get", + "alerting:apm.transaction_duration/observability/alert/find", + "alerting:apm.transaction_duration/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_duration/observability/alert/getAlertSummary", + "alerting:apm.transaction_duration/observability/alert/update", + "alerting:apm.transaction_duration/alerts/alert/get", + "alerting:apm.transaction_duration/alerts/alert/find", + "alerting:apm.transaction_duration/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_duration/alerts/alert/getAlertSummary", + "alerting:apm.transaction_duration/alerts/alert/update", + "alerting:apm.anomaly/observability/alert/get", + "alerting:apm.anomaly/observability/alert/find", + "alerting:apm.anomaly/observability/alert/getAuthorizedAlertsIndices", + "alerting:apm.anomaly/observability/alert/getAlertSummary", + "alerting:apm.anomaly/observability/alert/update", + "alerting:apm.anomaly/alerts/alert/get", + "alerting:apm.anomaly/alerts/alert/find", + "alerting:apm.anomaly/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.anomaly/alerts/alert/getAlertSummary", + "alerting:apm.anomaly/alerts/alert/update", + "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/get", + "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/find", + "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/getAlertSummary", + "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/update", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/get", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/find", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/getAlertSummary", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/update", + "alerting:xpack.synthetics.alerts.tls/observability/alert/get", + "alerting:xpack.synthetics.alerts.tls/observability/alert/find", + "alerting:xpack.synthetics.alerts.tls/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.synthetics.alerts.tls/observability/alert/getAlertSummary", + "alerting:xpack.synthetics.alerts.tls/observability/alert/update", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/get", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/find", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/getAlertSummary", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/update", + "alerting:metrics.alert.threshold/observability/alert/get", + "alerting:metrics.alert.threshold/observability/alert/find", + "alerting:metrics.alert.threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.threshold/observability/alert/getAlertSummary", + "alerting:metrics.alert.threshold/observability/alert/update", + "alerting:metrics.alert.threshold/alerts/alert/get", + "alerting:metrics.alert.threshold/alerts/alert/find", + "alerting:metrics.alert.threshold/alerts/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.threshold/alerts/alert/getAlertSummary", + "alerting:metrics.alert.threshold/alerts/alert/update", + "alerting:metrics.alert.inventory.threshold/observability/alert/get", + "alerting:metrics.alert.inventory.threshold/observability/alert/find", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/alert/update", + "alerting:metrics.alert.inventory.threshold/alerts/alert/get", + "alerting:metrics.alert.inventory.threshold/alerts/alert/find", + "alerting:metrics.alert.inventory.threshold/alerts/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.inventory.threshold/alerts/alert/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/alerts/alert/update", + "alerting:xpack.uptime.alerts.tls/observability/alert/get", + "alerting:xpack.uptime.alerts.tls/observability/alert/find", + "alerting:xpack.uptime.alerts.tls/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tls/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/observability/alert/update", + "alerting:xpack.uptime.alerts.tls/alerts/alert/get", + "alerting:xpack.uptime.alerts.tls/alerts/alert/find", + "alerting:xpack.uptime.alerts.tls/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tls/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/alerts/alert/update", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/get", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/find", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/update", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/get", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/find", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/update", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/get", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/find", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/update", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/get", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/find", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/update", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/get", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/find", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/update", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/get", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/find", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/update", + "alerting:logs.alert.document.count/observability/alert/get", + "alerting:logs.alert.document.count/observability/alert/find", + "alerting:logs.alert.document.count/observability/alert/getAuthorizedAlertsIndices", + "alerting:logs.alert.document.count/observability/alert/getAlertSummary", + "alerting:logs.alert.document.count/observability/alert/update", + "alerting:logs.alert.document.count/alerts/alert/get", + "alerting:logs.alert.document.count/alerts/alert/find", + "alerting:logs.alert.document.count/alerts/alert/getAuthorizedAlertsIndices", + "alerting:logs.alert.document.count/alerts/alert/getAlertSummary", + "alerting:logs.alert.document.count/alerts/alert/update", + "alerting:slo.rules.burnRate/observability/alert/get", + "alerting:slo.rules.burnRate/observability/alert/find", + "alerting:slo.rules.burnRate/observability/alert/getAuthorizedAlertsIndices", + "alerting:slo.rules.burnRate/observability/alert/getAlertSummary", + "alerting:slo.rules.burnRate/observability/alert/update", + "alerting:slo.rules.burnRate/alerts/alert/get", + "alerting:slo.rules.burnRate/alerts/alert/find", + "alerting:slo.rules.burnRate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:slo.rules.burnRate/alerts/alert/getAlertSummary", + "alerting:slo.rules.burnRate/alerts/alert/update", + "alerting:observability.rules.custom_threshold/observability/alert/get", + "alerting:observability.rules.custom_threshold/observability/alert/find", + "alerting:observability.rules.custom_threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/observability/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/alert/update", + "alerting:observability.rules.custom_threshold/alerts/alert/get", + "alerting:observability.rules.custom_threshold/alerts/alert/find", + "alerting:observability.rules.custom_threshold/alerts/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/alerts/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/alerts/alert/update", + "alerting:.es-query/observability/alert/get", + "alerting:.es-query/observability/alert/find", + "alerting:.es-query/observability/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/observability/alert/getAlertSummary", + "alerting:.es-query/observability/alert/update", + "alerting:.es-query/alerts/alert/get", + "alerting:.es-query/alerts/alert/find", + "alerting:.es-query/alerts/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/alerts/alert/getAlertSummary", + "alerting:.es-query/alerts/alert/update", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/update", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/update", + ], + "generate_report": Array [ + "login:", + "api:generateReport", + "ui:management/insightsAndAlerting/reporting", + "ui:discover/generateCsv", + ], + "minimal_all": Array [ + "login:", + "api:fileUpload:analyzeFile", + "app:discover", + "app:kibana", + "ui:catalogue/discover", + "ui:navLinks/discover", + "ui:navLinks/kibana", + "saved_object:search/bulk_get", + "saved_object:search/get", + "saved_object:search/find", + "saved_object:search/open_point_in_time", + "saved_object:search/close_point_in_time", + "saved_object:search/create", + "saved_object:search/bulk_create", + "saved_object:search/update", + "saved_object:search/bulk_update", + "saved_object:search/delete", + "saved_object:search/bulk_delete", + "saved_object:search/share_to_space", + "saved_object:query/bulk_get", + "saved_object:query/get", + "saved_object:query/find", + "saved_object:query/open_point_in_time", + "saved_object:query/close_point_in_time", + "saved_object:query/create", + "saved_object:query/bulk_create", + "saved_object:query/update", + "saved_object:query/bulk_update", + "saved_object:query/delete", + "saved_object:query/bulk_delete", + "saved_object:query/share_to_space", + "saved_object:telemetry/bulk_get", + "saved_object:telemetry/get", + "saved_object:telemetry/find", + "saved_object:telemetry/open_point_in_time", + "saved_object:telemetry/close_point_in_time", + "saved_object:telemetry/create", + "saved_object:telemetry/bulk_create", + "saved_object:telemetry/update", + "saved_object:telemetry/bulk_update", + "saved_object:telemetry/delete", + "saved_object:telemetry/bulk_delete", + "saved_object:telemetry/share_to_space", + "saved_object:index-pattern/bulk_get", + "saved_object:index-pattern/get", + "saved_object:index-pattern/find", + "saved_object:index-pattern/open_point_in_time", + "saved_object:index-pattern/close_point_in_time", + "saved_object:config/bulk_get", + "saved_object:config/get", + "saved_object:config/find", + "saved_object:config/open_point_in_time", + "saved_object:config/close_point_in_time", + "saved_object:config-global/bulk_get", + "saved_object:config-global/get", + "saved_object:config-global/find", + "saved_object:config-global/open_point_in_time", + "saved_object:config-global/close_point_in_time", + "saved_object:url/bulk_get", + "saved_object:url/get", + "saved_object:url/find", + "saved_object:url/open_point_in_time", + "saved_object:url/close_point_in_time", + "ui:discover/show", + "ui:discover/save", + "ui:discover/saveQuery", + "api:rac", + "app:observability", + "ui:catalogue/observability", + "ui:navLinks/observability", + "ui:observability/read", + "ui:observability/write", "alerting:apm.error_rate/observability/rule/get", "alerting:apm.error_rate/observability/rule/getRuleState", "alerting:apm.error_rate/observability/rule/getAlertSummary", @@ -3394,6 +6130,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.error_rate/observability/rule/runSoon", "alerting:apm.error_rate/observability/rule/scheduleBackfill", "alerting:apm.error_rate/observability/rule/deleteBackfill", + "alerting:apm.error_rate/alerts/rule/get", + "alerting:apm.error_rate/alerts/rule/getRuleState", + "alerting:apm.error_rate/alerts/rule/getAlertSummary", + "alerting:apm.error_rate/alerts/rule/getExecutionLog", + "alerting:apm.error_rate/alerts/rule/getActionErrorLog", + "alerting:apm.error_rate/alerts/rule/find", + "alerting:apm.error_rate/alerts/rule/getRuleExecutionKPI", + "alerting:apm.error_rate/alerts/rule/getBackfill", + "alerting:apm.error_rate/alerts/rule/findBackfill", + "alerting:apm.error_rate/alerts/rule/create", + "alerting:apm.error_rate/alerts/rule/delete", + "alerting:apm.error_rate/alerts/rule/update", + "alerting:apm.error_rate/alerts/rule/updateApiKey", + "alerting:apm.error_rate/alerts/rule/enable", + "alerting:apm.error_rate/alerts/rule/disable", + "alerting:apm.error_rate/alerts/rule/muteAll", + "alerting:apm.error_rate/alerts/rule/unmuteAll", + "alerting:apm.error_rate/alerts/rule/muteAlert", + "alerting:apm.error_rate/alerts/rule/unmuteAlert", + "alerting:apm.error_rate/alerts/rule/snooze", + "alerting:apm.error_rate/alerts/rule/bulkEdit", + "alerting:apm.error_rate/alerts/rule/bulkDelete", + "alerting:apm.error_rate/alerts/rule/bulkEnable", + "alerting:apm.error_rate/alerts/rule/bulkDisable", + "alerting:apm.error_rate/alerts/rule/unsnooze", + "alerting:apm.error_rate/alerts/rule/runSoon", + "alerting:apm.error_rate/alerts/rule/scheduleBackfill", + "alerting:apm.error_rate/alerts/rule/deleteBackfill", "alerting:apm.transaction_error_rate/observability/rule/get", "alerting:apm.transaction_error_rate/observability/rule/getRuleState", "alerting:apm.transaction_error_rate/observability/rule/getAlertSummary", @@ -3422,6 +6186,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.transaction_error_rate/observability/rule/runSoon", "alerting:apm.transaction_error_rate/observability/rule/scheduleBackfill", "alerting:apm.transaction_error_rate/observability/rule/deleteBackfill", + "alerting:apm.transaction_error_rate/alerts/rule/get", + "alerting:apm.transaction_error_rate/alerts/rule/getRuleState", + "alerting:apm.transaction_error_rate/alerts/rule/getAlertSummary", + "alerting:apm.transaction_error_rate/alerts/rule/getExecutionLog", + "alerting:apm.transaction_error_rate/alerts/rule/getActionErrorLog", + "alerting:apm.transaction_error_rate/alerts/rule/find", + "alerting:apm.transaction_error_rate/alerts/rule/getRuleExecutionKPI", + "alerting:apm.transaction_error_rate/alerts/rule/getBackfill", + "alerting:apm.transaction_error_rate/alerts/rule/findBackfill", + "alerting:apm.transaction_error_rate/alerts/rule/create", + "alerting:apm.transaction_error_rate/alerts/rule/delete", + "alerting:apm.transaction_error_rate/alerts/rule/update", + "alerting:apm.transaction_error_rate/alerts/rule/updateApiKey", + "alerting:apm.transaction_error_rate/alerts/rule/enable", + "alerting:apm.transaction_error_rate/alerts/rule/disable", + "alerting:apm.transaction_error_rate/alerts/rule/muteAll", + "alerting:apm.transaction_error_rate/alerts/rule/unmuteAll", + "alerting:apm.transaction_error_rate/alerts/rule/muteAlert", + "alerting:apm.transaction_error_rate/alerts/rule/unmuteAlert", + "alerting:apm.transaction_error_rate/alerts/rule/snooze", + "alerting:apm.transaction_error_rate/alerts/rule/bulkEdit", + "alerting:apm.transaction_error_rate/alerts/rule/bulkDelete", + "alerting:apm.transaction_error_rate/alerts/rule/bulkEnable", + "alerting:apm.transaction_error_rate/alerts/rule/bulkDisable", + "alerting:apm.transaction_error_rate/alerts/rule/unsnooze", + "alerting:apm.transaction_error_rate/alerts/rule/runSoon", + "alerting:apm.transaction_error_rate/alerts/rule/scheduleBackfill", + "alerting:apm.transaction_error_rate/alerts/rule/deleteBackfill", "alerting:apm.transaction_duration/observability/rule/get", "alerting:apm.transaction_duration/observability/rule/getRuleState", "alerting:apm.transaction_duration/observability/rule/getAlertSummary", @@ -3450,6 +6242,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.transaction_duration/observability/rule/runSoon", "alerting:apm.transaction_duration/observability/rule/scheduleBackfill", "alerting:apm.transaction_duration/observability/rule/deleteBackfill", + "alerting:apm.transaction_duration/alerts/rule/get", + "alerting:apm.transaction_duration/alerts/rule/getRuleState", + "alerting:apm.transaction_duration/alerts/rule/getAlertSummary", + "alerting:apm.transaction_duration/alerts/rule/getExecutionLog", + "alerting:apm.transaction_duration/alerts/rule/getActionErrorLog", + "alerting:apm.transaction_duration/alerts/rule/find", + "alerting:apm.transaction_duration/alerts/rule/getRuleExecutionKPI", + "alerting:apm.transaction_duration/alerts/rule/getBackfill", + "alerting:apm.transaction_duration/alerts/rule/findBackfill", + "alerting:apm.transaction_duration/alerts/rule/create", + "alerting:apm.transaction_duration/alerts/rule/delete", + "alerting:apm.transaction_duration/alerts/rule/update", + "alerting:apm.transaction_duration/alerts/rule/updateApiKey", + "alerting:apm.transaction_duration/alerts/rule/enable", + "alerting:apm.transaction_duration/alerts/rule/disable", + "alerting:apm.transaction_duration/alerts/rule/muteAll", + "alerting:apm.transaction_duration/alerts/rule/unmuteAll", + "alerting:apm.transaction_duration/alerts/rule/muteAlert", + "alerting:apm.transaction_duration/alerts/rule/unmuteAlert", + "alerting:apm.transaction_duration/alerts/rule/snooze", + "alerting:apm.transaction_duration/alerts/rule/bulkEdit", + "alerting:apm.transaction_duration/alerts/rule/bulkDelete", + "alerting:apm.transaction_duration/alerts/rule/bulkEnable", + "alerting:apm.transaction_duration/alerts/rule/bulkDisable", + "alerting:apm.transaction_duration/alerts/rule/unsnooze", + "alerting:apm.transaction_duration/alerts/rule/runSoon", + "alerting:apm.transaction_duration/alerts/rule/scheduleBackfill", + "alerting:apm.transaction_duration/alerts/rule/deleteBackfill", "alerting:apm.anomaly/observability/rule/get", "alerting:apm.anomaly/observability/rule/getRuleState", "alerting:apm.anomaly/observability/rule/getAlertSummary", @@ -3478,6 +6298,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.anomaly/observability/rule/runSoon", "alerting:apm.anomaly/observability/rule/scheduleBackfill", "alerting:apm.anomaly/observability/rule/deleteBackfill", + "alerting:apm.anomaly/alerts/rule/get", + "alerting:apm.anomaly/alerts/rule/getRuleState", + "alerting:apm.anomaly/alerts/rule/getAlertSummary", + "alerting:apm.anomaly/alerts/rule/getExecutionLog", + "alerting:apm.anomaly/alerts/rule/getActionErrorLog", + "alerting:apm.anomaly/alerts/rule/find", + "alerting:apm.anomaly/alerts/rule/getRuleExecutionKPI", + "alerting:apm.anomaly/alerts/rule/getBackfill", + "alerting:apm.anomaly/alerts/rule/findBackfill", + "alerting:apm.anomaly/alerts/rule/create", + "alerting:apm.anomaly/alerts/rule/delete", + "alerting:apm.anomaly/alerts/rule/update", + "alerting:apm.anomaly/alerts/rule/updateApiKey", + "alerting:apm.anomaly/alerts/rule/enable", + "alerting:apm.anomaly/alerts/rule/disable", + "alerting:apm.anomaly/alerts/rule/muteAll", + "alerting:apm.anomaly/alerts/rule/unmuteAll", + "alerting:apm.anomaly/alerts/rule/muteAlert", + "alerting:apm.anomaly/alerts/rule/unmuteAlert", + "alerting:apm.anomaly/alerts/rule/snooze", + "alerting:apm.anomaly/alerts/rule/bulkEdit", + "alerting:apm.anomaly/alerts/rule/bulkDelete", + "alerting:apm.anomaly/alerts/rule/bulkEnable", + "alerting:apm.anomaly/alerts/rule/bulkDisable", + "alerting:apm.anomaly/alerts/rule/unsnooze", + "alerting:apm.anomaly/alerts/rule/runSoon", + "alerting:apm.anomaly/alerts/rule/scheduleBackfill", + "alerting:apm.anomaly/alerts/rule/deleteBackfill", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/get", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/getRuleState", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/getAlertSummary", @@ -3506,6 +6354,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/runSoon", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/scheduleBackfill", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/deleteBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/get", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getRuleState", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getAlertSummary", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getExecutionLog", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getActionErrorLog", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/find", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/findBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/create", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/delete", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/update", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/updateApiKey", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/enable", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/disable", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/muteAll", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/unmuteAll", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/muteAlert", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/unmuteAlert", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/snooze", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/bulkEdit", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/bulkDelete", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/bulkEnable", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/bulkDisable", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/unsnooze", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/runSoon", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/scheduleBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/deleteBackfill", "alerting:xpack.synthetics.alerts.tls/observability/rule/get", "alerting:xpack.synthetics.alerts.tls/observability/rule/getRuleState", "alerting:xpack.synthetics.alerts.tls/observability/rule/getAlertSummary", @@ -3534,61 +6410,820 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.synthetics.alerts.tls/observability/rule/runSoon", "alerting:xpack.synthetics.alerts.tls/observability/rule/scheduleBackfill", "alerting:xpack.synthetics.alerts.tls/observability/rule/deleteBackfill", - "alerting:slo.rules.burnRate/observability/alert/get", - "alerting:slo.rules.burnRate/observability/alert/find", - "alerting:slo.rules.burnRate/observability/alert/getAuthorizedAlertsIndices", - "alerting:slo.rules.burnRate/observability/alert/getAlertSummary", - "alerting:slo.rules.burnRate/observability/alert/update", - "alerting:observability.rules.custom_threshold/observability/alert/get", - "alerting:observability.rules.custom_threshold/observability/alert/find", - "alerting:observability.rules.custom_threshold/observability/alert/getAuthorizedAlertsIndices", - "alerting:observability.rules.custom_threshold/observability/alert/getAlertSummary", - "alerting:observability.rules.custom_threshold/observability/alert/update", - "alerting:.es-query/observability/alert/get", - "alerting:.es-query/observability/alert/find", - "alerting:.es-query/observability/alert/getAuthorizedAlertsIndices", - "alerting:.es-query/observability/alert/getAlertSummary", - "alerting:.es-query/observability/alert/update", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/get", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/find", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAuthorizedAlertsIndices", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAlertSummary", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/update", - "alerting:metrics.alert.inventory.threshold/observability/alert/get", - "alerting:metrics.alert.inventory.threshold/observability/alert/find", - "alerting:metrics.alert.inventory.threshold/observability/alert/getAuthorizedAlertsIndices", - "alerting:metrics.alert.inventory.threshold/observability/alert/getAlertSummary", - "alerting:metrics.alert.inventory.threshold/observability/alert/update", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/get", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getRuleState", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getAlertSummary", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getExecutionLog", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getActionErrorLog", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/find", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getBackfill", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/findBackfill", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/create", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/delete", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/update", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/updateApiKey", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/enable", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/disable", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/muteAll", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/unmuteAll", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/muteAlert", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/unmuteAlert", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/snooze", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/bulkEdit", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/bulkDelete", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/bulkEnable", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/bulkDisable", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/unsnooze", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/runSoon", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/scheduleBackfill", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/deleteBackfill", + "alerting:metrics.alert.threshold/observability/rule/get", + "alerting:metrics.alert.threshold/observability/rule/getRuleState", + "alerting:metrics.alert.threshold/observability/rule/getAlertSummary", + "alerting:metrics.alert.threshold/observability/rule/getExecutionLog", + "alerting:metrics.alert.threshold/observability/rule/getActionErrorLog", + "alerting:metrics.alert.threshold/observability/rule/find", + "alerting:metrics.alert.threshold/observability/rule/getRuleExecutionKPI", + "alerting:metrics.alert.threshold/observability/rule/getBackfill", + "alerting:metrics.alert.threshold/observability/rule/findBackfill", + "alerting:metrics.alert.threshold/observability/rule/create", + "alerting:metrics.alert.threshold/observability/rule/delete", + "alerting:metrics.alert.threshold/observability/rule/update", + "alerting:metrics.alert.threshold/observability/rule/updateApiKey", + "alerting:metrics.alert.threshold/observability/rule/enable", + "alerting:metrics.alert.threshold/observability/rule/disable", + "alerting:metrics.alert.threshold/observability/rule/muteAll", + "alerting:metrics.alert.threshold/observability/rule/unmuteAll", + "alerting:metrics.alert.threshold/observability/rule/muteAlert", + "alerting:metrics.alert.threshold/observability/rule/unmuteAlert", + "alerting:metrics.alert.threshold/observability/rule/snooze", + "alerting:metrics.alert.threshold/observability/rule/bulkEdit", + "alerting:metrics.alert.threshold/observability/rule/bulkDelete", + "alerting:metrics.alert.threshold/observability/rule/bulkEnable", + "alerting:metrics.alert.threshold/observability/rule/bulkDisable", + "alerting:metrics.alert.threshold/observability/rule/unsnooze", + "alerting:metrics.alert.threshold/observability/rule/runSoon", + "alerting:metrics.alert.threshold/observability/rule/scheduleBackfill", + "alerting:metrics.alert.threshold/observability/rule/deleteBackfill", + "alerting:metrics.alert.threshold/alerts/rule/get", + "alerting:metrics.alert.threshold/alerts/rule/getRuleState", + "alerting:metrics.alert.threshold/alerts/rule/getAlertSummary", + "alerting:metrics.alert.threshold/alerts/rule/getExecutionLog", + "alerting:metrics.alert.threshold/alerts/rule/getActionErrorLog", + "alerting:metrics.alert.threshold/alerts/rule/find", + "alerting:metrics.alert.threshold/alerts/rule/getRuleExecutionKPI", + "alerting:metrics.alert.threshold/alerts/rule/getBackfill", + "alerting:metrics.alert.threshold/alerts/rule/findBackfill", + "alerting:metrics.alert.threshold/alerts/rule/create", + "alerting:metrics.alert.threshold/alerts/rule/delete", + "alerting:metrics.alert.threshold/alerts/rule/update", + "alerting:metrics.alert.threshold/alerts/rule/updateApiKey", + "alerting:metrics.alert.threshold/alerts/rule/enable", + "alerting:metrics.alert.threshold/alerts/rule/disable", + "alerting:metrics.alert.threshold/alerts/rule/muteAll", + "alerting:metrics.alert.threshold/alerts/rule/unmuteAll", + "alerting:metrics.alert.threshold/alerts/rule/muteAlert", + "alerting:metrics.alert.threshold/alerts/rule/unmuteAlert", + "alerting:metrics.alert.threshold/alerts/rule/snooze", + "alerting:metrics.alert.threshold/alerts/rule/bulkEdit", + "alerting:metrics.alert.threshold/alerts/rule/bulkDelete", + "alerting:metrics.alert.threshold/alerts/rule/bulkEnable", + "alerting:metrics.alert.threshold/alerts/rule/bulkDisable", + "alerting:metrics.alert.threshold/alerts/rule/unsnooze", + "alerting:metrics.alert.threshold/alerts/rule/runSoon", + "alerting:metrics.alert.threshold/alerts/rule/scheduleBackfill", + "alerting:metrics.alert.threshold/alerts/rule/deleteBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/get", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleState", + "alerting:metrics.alert.inventory.threshold/observability/rule/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/rule/getExecutionLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/getActionErrorLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/find", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleExecutionKPI", + "alerting:metrics.alert.inventory.threshold/observability/rule/getBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/findBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/create", + "alerting:metrics.alert.inventory.threshold/observability/rule/delete", + "alerting:metrics.alert.inventory.threshold/observability/rule/update", + "alerting:metrics.alert.inventory.threshold/observability/rule/updateApiKey", + "alerting:metrics.alert.inventory.threshold/observability/rule/enable", + "alerting:metrics.alert.inventory.threshold/observability/rule/disable", + "alerting:metrics.alert.inventory.threshold/observability/rule/muteAll", + "alerting:metrics.alert.inventory.threshold/observability/rule/unmuteAll", + "alerting:metrics.alert.inventory.threshold/observability/rule/muteAlert", + "alerting:metrics.alert.inventory.threshold/observability/rule/unmuteAlert", + "alerting:metrics.alert.inventory.threshold/observability/rule/snooze", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkEdit", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkDelete", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkEnable", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkDisable", + "alerting:metrics.alert.inventory.threshold/observability/rule/unsnooze", + "alerting:metrics.alert.inventory.threshold/observability/rule/runSoon", + "alerting:metrics.alert.inventory.threshold/observability/rule/scheduleBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/deleteBackfill", + "alerting:metrics.alert.inventory.threshold/alerts/rule/get", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getRuleState", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getExecutionLog", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getActionErrorLog", + "alerting:metrics.alert.inventory.threshold/alerts/rule/find", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getRuleExecutionKPI", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getBackfill", + "alerting:metrics.alert.inventory.threshold/alerts/rule/findBackfill", + "alerting:metrics.alert.inventory.threshold/alerts/rule/create", + "alerting:metrics.alert.inventory.threshold/alerts/rule/delete", + "alerting:metrics.alert.inventory.threshold/alerts/rule/update", + "alerting:metrics.alert.inventory.threshold/alerts/rule/updateApiKey", + "alerting:metrics.alert.inventory.threshold/alerts/rule/enable", + "alerting:metrics.alert.inventory.threshold/alerts/rule/disable", + "alerting:metrics.alert.inventory.threshold/alerts/rule/muteAll", + "alerting:metrics.alert.inventory.threshold/alerts/rule/unmuteAll", + "alerting:metrics.alert.inventory.threshold/alerts/rule/muteAlert", + "alerting:metrics.alert.inventory.threshold/alerts/rule/unmuteAlert", + "alerting:metrics.alert.inventory.threshold/alerts/rule/snooze", + "alerting:metrics.alert.inventory.threshold/alerts/rule/bulkEdit", + "alerting:metrics.alert.inventory.threshold/alerts/rule/bulkDelete", + "alerting:metrics.alert.inventory.threshold/alerts/rule/bulkEnable", + "alerting:metrics.alert.inventory.threshold/alerts/rule/bulkDisable", + "alerting:metrics.alert.inventory.threshold/alerts/rule/unsnooze", + "alerting:metrics.alert.inventory.threshold/alerts/rule/runSoon", + "alerting:metrics.alert.inventory.threshold/alerts/rule/scheduleBackfill", + "alerting:metrics.alert.inventory.threshold/alerts/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.tls/observability/rule/get", + "alerting:xpack.uptime.alerts.tls/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.tls/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tls/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tls/observability/rule/find", + "alerting:xpack.uptime.alerts.tls/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tls/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.tls/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.tls/observability/rule/create", + "alerting:xpack.uptime.alerts.tls/observability/rule/delete", + "alerting:xpack.uptime.alerts.tls/observability/rule/update", + "alerting:xpack.uptime.alerts.tls/observability/rule/updateApiKey", + "alerting:xpack.uptime.alerts.tls/observability/rule/enable", + "alerting:xpack.uptime.alerts.tls/observability/rule/disable", + "alerting:xpack.uptime.alerts.tls/observability/rule/muteAll", + "alerting:xpack.uptime.alerts.tls/observability/rule/unmuteAll", + "alerting:xpack.uptime.alerts.tls/observability/rule/muteAlert", + "alerting:xpack.uptime.alerts.tls/observability/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.tls/observability/rule/snooze", + "alerting:xpack.uptime.alerts.tls/observability/rule/bulkEdit", + "alerting:xpack.uptime.alerts.tls/observability/rule/bulkDelete", + "alerting:xpack.uptime.alerts.tls/observability/rule/bulkEnable", + "alerting:xpack.uptime.alerts.tls/observability/rule/bulkDisable", + "alerting:xpack.uptime.alerts.tls/observability/rule/unsnooze", + "alerting:xpack.uptime.alerts.tls/observability/rule/runSoon", + "alerting:xpack.uptime.alerts.tls/observability/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.tls/observability/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.tls/alerts/rule/get", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tls/alerts/rule/find", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.tls/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.tls/alerts/rule/create", + "alerting:xpack.uptime.alerts.tls/alerts/rule/delete", + "alerting:xpack.uptime.alerts.tls/alerts/rule/update", + "alerting:xpack.uptime.alerts.tls/alerts/rule/updateApiKey", + "alerting:xpack.uptime.alerts.tls/alerts/rule/enable", + "alerting:xpack.uptime.alerts.tls/alerts/rule/disable", + "alerting:xpack.uptime.alerts.tls/alerts/rule/muteAll", + "alerting:xpack.uptime.alerts.tls/alerts/rule/unmuteAll", + "alerting:xpack.uptime.alerts.tls/alerts/rule/muteAlert", + "alerting:xpack.uptime.alerts.tls/alerts/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.tls/alerts/rule/snooze", + "alerting:xpack.uptime.alerts.tls/alerts/rule/bulkEdit", + "alerting:xpack.uptime.alerts.tls/alerts/rule/bulkDelete", + "alerting:xpack.uptime.alerts.tls/alerts/rule/bulkEnable", + "alerting:xpack.uptime.alerts.tls/alerts/rule/bulkDisable", + "alerting:xpack.uptime.alerts.tls/alerts/rule/unsnooze", + "alerting:xpack.uptime.alerts.tls/alerts/rule/runSoon", + "alerting:xpack.uptime.alerts.tls/alerts/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.tls/alerts/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/get", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/find", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/create", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/delete", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/update", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/updateApiKey", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/enable", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/disable", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/muteAll", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/unmuteAll", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/muteAlert", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/snooze", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/bulkEdit", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/bulkDelete", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/bulkEnable", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/bulkDisable", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/unsnooze", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/runSoon", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/get", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/find", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/create", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/delete", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/update", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/updateApiKey", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/enable", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/disable", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/muteAll", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/unmuteAll", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/muteAlert", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/snooze", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/bulkEdit", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/bulkDelete", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/bulkEnable", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/bulkDisable", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/unsnooze", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/runSoon", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/get", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/find", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/create", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/delete", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/update", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/updateApiKey", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/enable", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/disable", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/muteAll", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/unmuteAll", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/muteAlert", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/snooze", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/bulkEdit", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/bulkDelete", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/bulkEnable", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/bulkDisable", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/unsnooze", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/runSoon", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/get", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/find", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/create", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/delete", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/update", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/updateApiKey", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/enable", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/disable", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/muteAll", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/unmuteAll", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/muteAlert", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/snooze", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/bulkEdit", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/bulkDelete", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/bulkEnable", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/bulkDisable", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/unsnooze", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/runSoon", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/get", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/find", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/create", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/delete", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/update", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/updateApiKey", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/enable", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/disable", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/muteAll", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/unmuteAll", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/muteAlert", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/snooze", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/bulkEdit", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/bulkDelete", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/bulkEnable", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/bulkDisable", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/unsnooze", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/runSoon", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/get", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/find", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/create", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/delete", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/update", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/updateApiKey", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/enable", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/disable", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/muteAll", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/unmuteAll", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/muteAlert", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/snooze", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/bulkEdit", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/bulkDelete", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/bulkEnable", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/bulkDisable", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/unsnooze", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/runSoon", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/deleteBackfill", + "alerting:logs.alert.document.count/observability/rule/get", + "alerting:logs.alert.document.count/observability/rule/getRuleState", + "alerting:logs.alert.document.count/observability/rule/getAlertSummary", + "alerting:logs.alert.document.count/observability/rule/getExecutionLog", + "alerting:logs.alert.document.count/observability/rule/getActionErrorLog", + "alerting:logs.alert.document.count/observability/rule/find", + "alerting:logs.alert.document.count/observability/rule/getRuleExecutionKPI", + "alerting:logs.alert.document.count/observability/rule/getBackfill", + "alerting:logs.alert.document.count/observability/rule/findBackfill", + "alerting:logs.alert.document.count/observability/rule/create", + "alerting:logs.alert.document.count/observability/rule/delete", + "alerting:logs.alert.document.count/observability/rule/update", + "alerting:logs.alert.document.count/observability/rule/updateApiKey", + "alerting:logs.alert.document.count/observability/rule/enable", + "alerting:logs.alert.document.count/observability/rule/disable", + "alerting:logs.alert.document.count/observability/rule/muteAll", + "alerting:logs.alert.document.count/observability/rule/unmuteAll", + "alerting:logs.alert.document.count/observability/rule/muteAlert", + "alerting:logs.alert.document.count/observability/rule/unmuteAlert", + "alerting:logs.alert.document.count/observability/rule/snooze", + "alerting:logs.alert.document.count/observability/rule/bulkEdit", + "alerting:logs.alert.document.count/observability/rule/bulkDelete", + "alerting:logs.alert.document.count/observability/rule/bulkEnable", + "alerting:logs.alert.document.count/observability/rule/bulkDisable", + "alerting:logs.alert.document.count/observability/rule/unsnooze", + "alerting:logs.alert.document.count/observability/rule/runSoon", + "alerting:logs.alert.document.count/observability/rule/scheduleBackfill", + "alerting:logs.alert.document.count/observability/rule/deleteBackfill", + "alerting:logs.alert.document.count/alerts/rule/get", + "alerting:logs.alert.document.count/alerts/rule/getRuleState", + "alerting:logs.alert.document.count/alerts/rule/getAlertSummary", + "alerting:logs.alert.document.count/alerts/rule/getExecutionLog", + "alerting:logs.alert.document.count/alerts/rule/getActionErrorLog", + "alerting:logs.alert.document.count/alerts/rule/find", + "alerting:logs.alert.document.count/alerts/rule/getRuleExecutionKPI", + "alerting:logs.alert.document.count/alerts/rule/getBackfill", + "alerting:logs.alert.document.count/alerts/rule/findBackfill", + "alerting:logs.alert.document.count/alerts/rule/create", + "alerting:logs.alert.document.count/alerts/rule/delete", + "alerting:logs.alert.document.count/alerts/rule/update", + "alerting:logs.alert.document.count/alerts/rule/updateApiKey", + "alerting:logs.alert.document.count/alerts/rule/enable", + "alerting:logs.alert.document.count/alerts/rule/disable", + "alerting:logs.alert.document.count/alerts/rule/muteAll", + "alerting:logs.alert.document.count/alerts/rule/unmuteAll", + "alerting:logs.alert.document.count/alerts/rule/muteAlert", + "alerting:logs.alert.document.count/alerts/rule/unmuteAlert", + "alerting:logs.alert.document.count/alerts/rule/snooze", + "alerting:logs.alert.document.count/alerts/rule/bulkEdit", + "alerting:logs.alert.document.count/alerts/rule/bulkDelete", + "alerting:logs.alert.document.count/alerts/rule/bulkEnable", + "alerting:logs.alert.document.count/alerts/rule/bulkDisable", + "alerting:logs.alert.document.count/alerts/rule/unsnooze", + "alerting:logs.alert.document.count/alerts/rule/runSoon", + "alerting:logs.alert.document.count/alerts/rule/scheduleBackfill", + "alerting:logs.alert.document.count/alerts/rule/deleteBackfill", + "alerting:slo.rules.burnRate/observability/rule/get", + "alerting:slo.rules.burnRate/observability/rule/getRuleState", + "alerting:slo.rules.burnRate/observability/rule/getAlertSummary", + "alerting:slo.rules.burnRate/observability/rule/getExecutionLog", + "alerting:slo.rules.burnRate/observability/rule/getActionErrorLog", + "alerting:slo.rules.burnRate/observability/rule/find", + "alerting:slo.rules.burnRate/observability/rule/getRuleExecutionKPI", + "alerting:slo.rules.burnRate/observability/rule/getBackfill", + "alerting:slo.rules.burnRate/observability/rule/findBackfill", + "alerting:slo.rules.burnRate/observability/rule/create", + "alerting:slo.rules.burnRate/observability/rule/delete", + "alerting:slo.rules.burnRate/observability/rule/update", + "alerting:slo.rules.burnRate/observability/rule/updateApiKey", + "alerting:slo.rules.burnRate/observability/rule/enable", + "alerting:slo.rules.burnRate/observability/rule/disable", + "alerting:slo.rules.burnRate/observability/rule/muteAll", + "alerting:slo.rules.burnRate/observability/rule/unmuteAll", + "alerting:slo.rules.burnRate/observability/rule/muteAlert", + "alerting:slo.rules.burnRate/observability/rule/unmuteAlert", + "alerting:slo.rules.burnRate/observability/rule/snooze", + "alerting:slo.rules.burnRate/observability/rule/bulkEdit", + "alerting:slo.rules.burnRate/observability/rule/bulkDelete", + "alerting:slo.rules.burnRate/observability/rule/bulkEnable", + "alerting:slo.rules.burnRate/observability/rule/bulkDisable", + "alerting:slo.rules.burnRate/observability/rule/unsnooze", + "alerting:slo.rules.burnRate/observability/rule/runSoon", + "alerting:slo.rules.burnRate/observability/rule/scheduleBackfill", + "alerting:slo.rules.burnRate/observability/rule/deleteBackfill", + "alerting:slo.rules.burnRate/alerts/rule/get", + "alerting:slo.rules.burnRate/alerts/rule/getRuleState", + "alerting:slo.rules.burnRate/alerts/rule/getAlertSummary", + "alerting:slo.rules.burnRate/alerts/rule/getExecutionLog", + "alerting:slo.rules.burnRate/alerts/rule/getActionErrorLog", + "alerting:slo.rules.burnRate/alerts/rule/find", + "alerting:slo.rules.burnRate/alerts/rule/getRuleExecutionKPI", + "alerting:slo.rules.burnRate/alerts/rule/getBackfill", + "alerting:slo.rules.burnRate/alerts/rule/findBackfill", + "alerting:slo.rules.burnRate/alerts/rule/create", + "alerting:slo.rules.burnRate/alerts/rule/delete", + "alerting:slo.rules.burnRate/alerts/rule/update", + "alerting:slo.rules.burnRate/alerts/rule/updateApiKey", + "alerting:slo.rules.burnRate/alerts/rule/enable", + "alerting:slo.rules.burnRate/alerts/rule/disable", + "alerting:slo.rules.burnRate/alerts/rule/muteAll", + "alerting:slo.rules.burnRate/alerts/rule/unmuteAll", + "alerting:slo.rules.burnRate/alerts/rule/muteAlert", + "alerting:slo.rules.burnRate/alerts/rule/unmuteAlert", + "alerting:slo.rules.burnRate/alerts/rule/snooze", + "alerting:slo.rules.burnRate/alerts/rule/bulkEdit", + "alerting:slo.rules.burnRate/alerts/rule/bulkDelete", + "alerting:slo.rules.burnRate/alerts/rule/bulkEnable", + "alerting:slo.rules.burnRate/alerts/rule/bulkDisable", + "alerting:slo.rules.burnRate/alerts/rule/unsnooze", + "alerting:slo.rules.burnRate/alerts/rule/runSoon", + "alerting:slo.rules.burnRate/alerts/rule/scheduleBackfill", + "alerting:slo.rules.burnRate/alerts/rule/deleteBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/get", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleState", + "alerting:observability.rules.custom_threshold/observability/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/observability/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/observability/rule/find", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/observability/rule/getBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/findBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/create", + "alerting:observability.rules.custom_threshold/observability/rule/delete", + "alerting:observability.rules.custom_threshold/observability/rule/update", + "alerting:observability.rules.custom_threshold/observability/rule/updateApiKey", + "alerting:observability.rules.custom_threshold/observability/rule/enable", + "alerting:observability.rules.custom_threshold/observability/rule/disable", + "alerting:observability.rules.custom_threshold/observability/rule/muteAll", + "alerting:observability.rules.custom_threshold/observability/rule/unmuteAll", + "alerting:observability.rules.custom_threshold/observability/rule/muteAlert", + "alerting:observability.rules.custom_threshold/observability/rule/unmuteAlert", + "alerting:observability.rules.custom_threshold/observability/rule/snooze", + "alerting:observability.rules.custom_threshold/observability/rule/bulkEdit", + "alerting:observability.rules.custom_threshold/observability/rule/bulkDelete", + "alerting:observability.rules.custom_threshold/observability/rule/bulkEnable", + "alerting:observability.rules.custom_threshold/observability/rule/bulkDisable", + "alerting:observability.rules.custom_threshold/observability/rule/unsnooze", + "alerting:observability.rules.custom_threshold/observability/rule/runSoon", + "alerting:observability.rules.custom_threshold/observability/rule/scheduleBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/deleteBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/get", + "alerting:observability.rules.custom_threshold/alerts/rule/getRuleState", + "alerting:observability.rules.custom_threshold/alerts/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/alerts/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/alerts/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/alerts/rule/find", + "alerting:observability.rules.custom_threshold/alerts/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/alerts/rule/getBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/findBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/create", + "alerting:observability.rules.custom_threshold/alerts/rule/delete", + "alerting:observability.rules.custom_threshold/alerts/rule/update", + "alerting:observability.rules.custom_threshold/alerts/rule/updateApiKey", + "alerting:observability.rules.custom_threshold/alerts/rule/enable", + "alerting:observability.rules.custom_threshold/alerts/rule/disable", + "alerting:observability.rules.custom_threshold/alerts/rule/muteAll", + "alerting:observability.rules.custom_threshold/alerts/rule/unmuteAll", + "alerting:observability.rules.custom_threshold/alerts/rule/muteAlert", + "alerting:observability.rules.custom_threshold/alerts/rule/unmuteAlert", + "alerting:observability.rules.custom_threshold/alerts/rule/snooze", + "alerting:observability.rules.custom_threshold/alerts/rule/bulkEdit", + "alerting:observability.rules.custom_threshold/alerts/rule/bulkDelete", + "alerting:observability.rules.custom_threshold/alerts/rule/bulkEnable", + "alerting:observability.rules.custom_threshold/alerts/rule/bulkDisable", + "alerting:observability.rules.custom_threshold/alerts/rule/unsnooze", + "alerting:observability.rules.custom_threshold/alerts/rule/runSoon", + "alerting:observability.rules.custom_threshold/alerts/rule/scheduleBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/deleteBackfill", + "alerting:.es-query/observability/rule/get", + "alerting:.es-query/observability/rule/getRuleState", + "alerting:.es-query/observability/rule/getAlertSummary", + "alerting:.es-query/observability/rule/getExecutionLog", + "alerting:.es-query/observability/rule/getActionErrorLog", + "alerting:.es-query/observability/rule/find", + "alerting:.es-query/observability/rule/getRuleExecutionKPI", + "alerting:.es-query/observability/rule/getBackfill", + "alerting:.es-query/observability/rule/findBackfill", + "alerting:.es-query/observability/rule/create", + "alerting:.es-query/observability/rule/delete", + "alerting:.es-query/observability/rule/update", + "alerting:.es-query/observability/rule/updateApiKey", + "alerting:.es-query/observability/rule/enable", + "alerting:.es-query/observability/rule/disable", + "alerting:.es-query/observability/rule/muteAll", + "alerting:.es-query/observability/rule/unmuteAll", + "alerting:.es-query/observability/rule/muteAlert", + "alerting:.es-query/observability/rule/unmuteAlert", + "alerting:.es-query/observability/rule/snooze", + "alerting:.es-query/observability/rule/bulkEdit", + "alerting:.es-query/observability/rule/bulkDelete", + "alerting:.es-query/observability/rule/bulkEnable", + "alerting:.es-query/observability/rule/bulkDisable", + "alerting:.es-query/observability/rule/unsnooze", + "alerting:.es-query/observability/rule/runSoon", + "alerting:.es-query/observability/rule/scheduleBackfill", + "alerting:.es-query/observability/rule/deleteBackfill", + "alerting:.es-query/alerts/rule/get", + "alerting:.es-query/alerts/rule/getRuleState", + "alerting:.es-query/alerts/rule/getAlertSummary", + "alerting:.es-query/alerts/rule/getExecutionLog", + "alerting:.es-query/alerts/rule/getActionErrorLog", + "alerting:.es-query/alerts/rule/find", + "alerting:.es-query/alerts/rule/getRuleExecutionKPI", + "alerting:.es-query/alerts/rule/getBackfill", + "alerting:.es-query/alerts/rule/findBackfill", + "alerting:.es-query/alerts/rule/create", + "alerting:.es-query/alerts/rule/delete", + "alerting:.es-query/alerts/rule/update", + "alerting:.es-query/alerts/rule/updateApiKey", + "alerting:.es-query/alerts/rule/enable", + "alerting:.es-query/alerts/rule/disable", + "alerting:.es-query/alerts/rule/muteAll", + "alerting:.es-query/alerts/rule/unmuteAll", + "alerting:.es-query/alerts/rule/muteAlert", + "alerting:.es-query/alerts/rule/unmuteAlert", + "alerting:.es-query/alerts/rule/snooze", + "alerting:.es-query/alerts/rule/bulkEdit", + "alerting:.es-query/alerts/rule/bulkDelete", + "alerting:.es-query/alerts/rule/bulkEnable", + "alerting:.es-query/alerts/rule/bulkDisable", + "alerting:.es-query/alerts/rule/unsnooze", + "alerting:.es-query/alerts/rule/runSoon", + "alerting:.es-query/alerts/rule/scheduleBackfill", + "alerting:.es-query/alerts/rule/deleteBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/create", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/delete", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/update", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/updateApiKey", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/enable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/disable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/muteAll", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unmuteAll", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/muteAlert", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unmuteAlert", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/snooze", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkEdit", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkDelete", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkEnable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkDisable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unsnooze", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/runSoon", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/scheduleBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/deleteBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/create", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/delete", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/update", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/updateApiKey", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/enable", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/disable", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/muteAll", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/unmuteAll", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/muteAlert", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/unmuteAlert", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/snooze", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/bulkEdit", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/bulkDelete", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/bulkEnable", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/bulkDisable", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/unsnooze", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/runSoon", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/scheduleBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/deleteBackfill", "alerting:apm.error_rate/observability/alert/get", "alerting:apm.error_rate/observability/alert/find", "alerting:apm.error_rate/observability/alert/getAuthorizedAlertsIndices", "alerting:apm.error_rate/observability/alert/getAlertSummary", "alerting:apm.error_rate/observability/alert/update", + "alerting:apm.error_rate/alerts/alert/get", + "alerting:apm.error_rate/alerts/alert/find", + "alerting:apm.error_rate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.error_rate/alerts/alert/getAlertSummary", + "alerting:apm.error_rate/alerts/alert/update", "alerting:apm.transaction_error_rate/observability/alert/get", "alerting:apm.transaction_error_rate/observability/alert/find", "alerting:apm.transaction_error_rate/observability/alert/getAuthorizedAlertsIndices", "alerting:apm.transaction_error_rate/observability/alert/getAlertSummary", "alerting:apm.transaction_error_rate/observability/alert/update", + "alerting:apm.transaction_error_rate/alerts/alert/get", + "alerting:apm.transaction_error_rate/alerts/alert/find", + "alerting:apm.transaction_error_rate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_error_rate/alerts/alert/getAlertSummary", + "alerting:apm.transaction_error_rate/alerts/alert/update", "alerting:apm.transaction_duration/observability/alert/get", "alerting:apm.transaction_duration/observability/alert/find", "alerting:apm.transaction_duration/observability/alert/getAuthorizedAlertsIndices", "alerting:apm.transaction_duration/observability/alert/getAlertSummary", "alerting:apm.transaction_duration/observability/alert/update", + "alerting:apm.transaction_duration/alerts/alert/get", + "alerting:apm.transaction_duration/alerts/alert/find", + "alerting:apm.transaction_duration/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_duration/alerts/alert/getAlertSummary", + "alerting:apm.transaction_duration/alerts/alert/update", "alerting:apm.anomaly/observability/alert/get", "alerting:apm.anomaly/observability/alert/find", "alerting:apm.anomaly/observability/alert/getAuthorizedAlertsIndices", "alerting:apm.anomaly/observability/alert/getAlertSummary", "alerting:apm.anomaly/observability/alert/update", + "alerting:apm.anomaly/alerts/alert/get", + "alerting:apm.anomaly/alerts/alert/find", + "alerting:apm.anomaly/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.anomaly/alerts/alert/getAlertSummary", + "alerting:apm.anomaly/alerts/alert/update", "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/get", "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/find", "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/getAuthorizedAlertsIndices", "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/getAlertSummary", "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/update", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/get", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/find", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/getAlertSummary", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/update", "alerting:xpack.synthetics.alerts.tls/observability/alert/get", "alerting:xpack.synthetics.alerts.tls/observability/alert/find", "alerting:xpack.synthetics.alerts.tls/observability/alert/getAuthorizedAlertsIndices", "alerting:xpack.synthetics.alerts.tls/observability/alert/getAlertSummary", "alerting:xpack.synthetics.alerts.tls/observability/alert/update", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/get", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/find", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/getAlertSummary", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/update", + "alerting:metrics.alert.threshold/observability/alert/get", + "alerting:metrics.alert.threshold/observability/alert/find", + "alerting:metrics.alert.threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.threshold/observability/alert/getAlertSummary", + "alerting:metrics.alert.threshold/observability/alert/update", + "alerting:metrics.alert.threshold/alerts/alert/get", + "alerting:metrics.alert.threshold/alerts/alert/find", + "alerting:metrics.alert.threshold/alerts/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.threshold/alerts/alert/getAlertSummary", + "alerting:metrics.alert.threshold/alerts/alert/update", + "alerting:metrics.alert.inventory.threshold/observability/alert/get", + "alerting:metrics.alert.inventory.threshold/observability/alert/find", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/alert/update", + "alerting:metrics.alert.inventory.threshold/alerts/alert/get", + "alerting:metrics.alert.inventory.threshold/alerts/alert/find", + "alerting:metrics.alert.inventory.threshold/alerts/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.inventory.threshold/alerts/alert/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/alerts/alert/update", + "alerting:xpack.uptime.alerts.tls/observability/alert/get", + "alerting:xpack.uptime.alerts.tls/observability/alert/find", + "alerting:xpack.uptime.alerts.tls/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tls/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/observability/alert/update", + "alerting:xpack.uptime.alerts.tls/alerts/alert/get", + "alerting:xpack.uptime.alerts.tls/alerts/alert/find", + "alerting:xpack.uptime.alerts.tls/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tls/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/alerts/alert/update", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/get", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/find", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/update", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/get", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/find", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/update", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/get", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/find", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/update", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/get", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/find", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/update", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/get", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/find", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/update", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/get", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/find", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/update", + "alerting:logs.alert.document.count/observability/alert/get", + "alerting:logs.alert.document.count/observability/alert/find", + "alerting:logs.alert.document.count/observability/alert/getAuthorizedAlertsIndices", + "alerting:logs.alert.document.count/observability/alert/getAlertSummary", + "alerting:logs.alert.document.count/observability/alert/update", + "alerting:logs.alert.document.count/alerts/alert/get", + "alerting:logs.alert.document.count/alerts/alert/find", + "alerting:logs.alert.document.count/alerts/alert/getAuthorizedAlertsIndices", + "alerting:logs.alert.document.count/alerts/alert/getAlertSummary", + "alerting:logs.alert.document.count/alerts/alert/update", + "alerting:slo.rules.burnRate/observability/alert/get", + "alerting:slo.rules.burnRate/observability/alert/find", + "alerting:slo.rules.burnRate/observability/alert/getAuthorizedAlertsIndices", + "alerting:slo.rules.burnRate/observability/alert/getAlertSummary", + "alerting:slo.rules.burnRate/observability/alert/update", + "alerting:slo.rules.burnRate/alerts/alert/get", + "alerting:slo.rules.burnRate/alerts/alert/find", + "alerting:slo.rules.burnRate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:slo.rules.burnRate/alerts/alert/getAlertSummary", + "alerting:slo.rules.burnRate/alerts/alert/update", + "alerting:observability.rules.custom_threshold/observability/alert/get", + "alerting:observability.rules.custom_threshold/observability/alert/find", + "alerting:observability.rules.custom_threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/observability/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/alert/update", + "alerting:observability.rules.custom_threshold/alerts/alert/get", + "alerting:observability.rules.custom_threshold/alerts/alert/find", + "alerting:observability.rules.custom_threshold/alerts/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/alerts/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/alerts/alert/update", + "alerting:.es-query/observability/alert/get", + "alerting:.es-query/observability/alert/find", + "alerting:.es-query/observability/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/observability/alert/getAlertSummary", + "alerting:.es-query/observability/alert/update", + "alerting:.es-query/alerts/alert/get", + "alerting:.es-query/alerts/alert/find", + "alerting:.es-query/alerts/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/alerts/alert/getAlertSummary", + "alerting:.es-query/alerts/alert/update", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/update", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/update", ], "minimal_read": Array [ "login:", @@ -3638,51 +7273,6 @@ export default function ({ getService }: FtrProviderContext) { "ui:catalogue/observability", "ui:navLinks/observability", "ui:observability/read", - "alerting:slo.rules.burnRate/observability/rule/get", - "alerting:slo.rules.burnRate/observability/rule/getRuleState", - "alerting:slo.rules.burnRate/observability/rule/getAlertSummary", - "alerting:slo.rules.burnRate/observability/rule/getExecutionLog", - "alerting:slo.rules.burnRate/observability/rule/getActionErrorLog", - "alerting:slo.rules.burnRate/observability/rule/find", - "alerting:slo.rules.burnRate/observability/rule/getRuleExecutionKPI", - "alerting:slo.rules.burnRate/observability/rule/getBackfill", - "alerting:slo.rules.burnRate/observability/rule/findBackfill", - "alerting:observability.rules.custom_threshold/observability/rule/get", - "alerting:observability.rules.custom_threshold/observability/rule/getRuleState", - "alerting:observability.rules.custom_threshold/observability/rule/getAlertSummary", - "alerting:observability.rules.custom_threshold/observability/rule/getExecutionLog", - "alerting:observability.rules.custom_threshold/observability/rule/getActionErrorLog", - "alerting:observability.rules.custom_threshold/observability/rule/find", - "alerting:observability.rules.custom_threshold/observability/rule/getRuleExecutionKPI", - "alerting:observability.rules.custom_threshold/observability/rule/getBackfill", - "alerting:observability.rules.custom_threshold/observability/rule/findBackfill", - "alerting:.es-query/observability/rule/get", - "alerting:.es-query/observability/rule/getRuleState", - "alerting:.es-query/observability/rule/getAlertSummary", - "alerting:.es-query/observability/rule/getExecutionLog", - "alerting:.es-query/observability/rule/getActionErrorLog", - "alerting:.es-query/observability/rule/find", - "alerting:.es-query/observability/rule/getRuleExecutionKPI", - "alerting:.es-query/observability/rule/getBackfill", - "alerting:.es-query/observability/rule/findBackfill", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/get", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleState", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getAlertSummary", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getExecutionLog", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getActionErrorLog", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/find", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleExecutionKPI", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getBackfill", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/findBackfill", - "alerting:metrics.alert.inventory.threshold/observability/rule/get", - "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleState", - "alerting:metrics.alert.inventory.threshold/observability/rule/getAlertSummary", - "alerting:metrics.alert.inventory.threshold/observability/rule/getExecutionLog", - "alerting:metrics.alert.inventory.threshold/observability/rule/getActionErrorLog", - "alerting:metrics.alert.inventory.threshold/observability/rule/find", - "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleExecutionKPI", - "alerting:metrics.alert.inventory.threshold/observability/rule/getBackfill", - "alerting:metrics.alert.inventory.threshold/observability/rule/findBackfill", "alerting:apm.error_rate/observability/rule/get", "alerting:apm.error_rate/observability/rule/getRuleState", "alerting:apm.error_rate/observability/rule/getAlertSummary", @@ -3692,6 +7282,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.error_rate/observability/rule/getRuleExecutionKPI", "alerting:apm.error_rate/observability/rule/getBackfill", "alerting:apm.error_rate/observability/rule/findBackfill", + "alerting:apm.error_rate/alerts/rule/get", + "alerting:apm.error_rate/alerts/rule/getRuleState", + "alerting:apm.error_rate/alerts/rule/getAlertSummary", + "alerting:apm.error_rate/alerts/rule/getExecutionLog", + "alerting:apm.error_rate/alerts/rule/getActionErrorLog", + "alerting:apm.error_rate/alerts/rule/find", + "alerting:apm.error_rate/alerts/rule/getRuleExecutionKPI", + "alerting:apm.error_rate/alerts/rule/getBackfill", + "alerting:apm.error_rate/alerts/rule/findBackfill", "alerting:apm.transaction_error_rate/observability/rule/get", "alerting:apm.transaction_error_rate/observability/rule/getRuleState", "alerting:apm.transaction_error_rate/observability/rule/getAlertSummary", @@ -3701,6 +7300,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.transaction_error_rate/observability/rule/getRuleExecutionKPI", "alerting:apm.transaction_error_rate/observability/rule/getBackfill", "alerting:apm.transaction_error_rate/observability/rule/findBackfill", + "alerting:apm.transaction_error_rate/alerts/rule/get", + "alerting:apm.transaction_error_rate/alerts/rule/getRuleState", + "alerting:apm.transaction_error_rate/alerts/rule/getAlertSummary", + "alerting:apm.transaction_error_rate/alerts/rule/getExecutionLog", + "alerting:apm.transaction_error_rate/alerts/rule/getActionErrorLog", + "alerting:apm.transaction_error_rate/alerts/rule/find", + "alerting:apm.transaction_error_rate/alerts/rule/getRuleExecutionKPI", + "alerting:apm.transaction_error_rate/alerts/rule/getBackfill", + "alerting:apm.transaction_error_rate/alerts/rule/findBackfill", "alerting:apm.transaction_duration/observability/rule/get", "alerting:apm.transaction_duration/observability/rule/getRuleState", "alerting:apm.transaction_duration/observability/rule/getAlertSummary", @@ -3710,6 +7318,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.transaction_duration/observability/rule/getRuleExecutionKPI", "alerting:apm.transaction_duration/observability/rule/getBackfill", "alerting:apm.transaction_duration/observability/rule/findBackfill", + "alerting:apm.transaction_duration/alerts/rule/get", + "alerting:apm.transaction_duration/alerts/rule/getRuleState", + "alerting:apm.transaction_duration/alerts/rule/getAlertSummary", + "alerting:apm.transaction_duration/alerts/rule/getExecutionLog", + "alerting:apm.transaction_duration/alerts/rule/getActionErrorLog", + "alerting:apm.transaction_duration/alerts/rule/find", + "alerting:apm.transaction_duration/alerts/rule/getRuleExecutionKPI", + "alerting:apm.transaction_duration/alerts/rule/getBackfill", + "alerting:apm.transaction_duration/alerts/rule/findBackfill", "alerting:apm.anomaly/observability/rule/get", "alerting:apm.anomaly/observability/rule/getRuleState", "alerting:apm.anomaly/observability/rule/getAlertSummary", @@ -3719,6 +7336,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.anomaly/observability/rule/getRuleExecutionKPI", "alerting:apm.anomaly/observability/rule/getBackfill", "alerting:apm.anomaly/observability/rule/findBackfill", + "alerting:apm.anomaly/alerts/rule/get", + "alerting:apm.anomaly/alerts/rule/getRuleState", + "alerting:apm.anomaly/alerts/rule/getAlertSummary", + "alerting:apm.anomaly/alerts/rule/getExecutionLog", + "alerting:apm.anomaly/alerts/rule/getActionErrorLog", + "alerting:apm.anomaly/alerts/rule/find", + "alerting:apm.anomaly/alerts/rule/getRuleExecutionKPI", + "alerting:apm.anomaly/alerts/rule/getBackfill", + "alerting:apm.anomaly/alerts/rule/findBackfill", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/get", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/getRuleState", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/getAlertSummary", @@ -3728,6 +7354,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/getRuleExecutionKPI", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/getBackfill", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/findBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/get", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getRuleState", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getAlertSummary", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getExecutionLog", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getActionErrorLog", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/find", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/findBackfill", "alerting:xpack.synthetics.alerts.tls/observability/rule/get", "alerting:xpack.synthetics.alerts.tls/observability/rule/getRuleState", "alerting:xpack.synthetics.alerts.tls/observability/rule/getAlertSummary", @@ -3737,50 +7372,349 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.synthetics.alerts.tls/observability/rule/getRuleExecutionKPI", "alerting:xpack.synthetics.alerts.tls/observability/rule/getBackfill", "alerting:xpack.synthetics.alerts.tls/observability/rule/findBackfill", - "alerting:slo.rules.burnRate/observability/alert/get", - "alerting:slo.rules.burnRate/observability/alert/find", - "alerting:slo.rules.burnRate/observability/alert/getAuthorizedAlertsIndices", - "alerting:slo.rules.burnRate/observability/alert/getAlertSummary", - "alerting:observability.rules.custom_threshold/observability/alert/get", - "alerting:observability.rules.custom_threshold/observability/alert/find", - "alerting:observability.rules.custom_threshold/observability/alert/getAuthorizedAlertsIndices", - "alerting:observability.rules.custom_threshold/observability/alert/getAlertSummary", - "alerting:.es-query/observability/alert/get", - "alerting:.es-query/observability/alert/find", - "alerting:.es-query/observability/alert/getAuthorizedAlertsIndices", - "alerting:.es-query/observability/alert/getAlertSummary", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/get", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/find", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAuthorizedAlertsIndices", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAlertSummary", - "alerting:metrics.alert.inventory.threshold/observability/alert/get", - "alerting:metrics.alert.inventory.threshold/observability/alert/find", - "alerting:metrics.alert.inventory.threshold/observability/alert/getAuthorizedAlertsIndices", - "alerting:metrics.alert.inventory.threshold/observability/alert/getAlertSummary", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/get", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getRuleState", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getAlertSummary", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getExecutionLog", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getActionErrorLog", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/find", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getBackfill", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/findBackfill", + "alerting:metrics.alert.threshold/observability/rule/get", + "alerting:metrics.alert.threshold/observability/rule/getRuleState", + "alerting:metrics.alert.threshold/observability/rule/getAlertSummary", + "alerting:metrics.alert.threshold/observability/rule/getExecutionLog", + "alerting:metrics.alert.threshold/observability/rule/getActionErrorLog", + "alerting:metrics.alert.threshold/observability/rule/find", + "alerting:metrics.alert.threshold/observability/rule/getRuleExecutionKPI", + "alerting:metrics.alert.threshold/observability/rule/getBackfill", + "alerting:metrics.alert.threshold/observability/rule/findBackfill", + "alerting:metrics.alert.threshold/alerts/rule/get", + "alerting:metrics.alert.threshold/alerts/rule/getRuleState", + "alerting:metrics.alert.threshold/alerts/rule/getAlertSummary", + "alerting:metrics.alert.threshold/alerts/rule/getExecutionLog", + "alerting:metrics.alert.threshold/alerts/rule/getActionErrorLog", + "alerting:metrics.alert.threshold/alerts/rule/find", + "alerting:metrics.alert.threshold/alerts/rule/getRuleExecutionKPI", + "alerting:metrics.alert.threshold/alerts/rule/getBackfill", + "alerting:metrics.alert.threshold/alerts/rule/findBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/get", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleState", + "alerting:metrics.alert.inventory.threshold/observability/rule/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/rule/getExecutionLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/getActionErrorLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/find", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleExecutionKPI", + "alerting:metrics.alert.inventory.threshold/observability/rule/getBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/findBackfill", + "alerting:metrics.alert.inventory.threshold/alerts/rule/get", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getRuleState", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getExecutionLog", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getActionErrorLog", + "alerting:metrics.alert.inventory.threshold/alerts/rule/find", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getRuleExecutionKPI", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getBackfill", + "alerting:metrics.alert.inventory.threshold/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.tls/observability/rule/get", + "alerting:xpack.uptime.alerts.tls/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.tls/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tls/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tls/observability/rule/find", + "alerting:xpack.uptime.alerts.tls/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tls/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.tls/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.tls/alerts/rule/get", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tls/alerts/rule/find", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.tls/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/get", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/find", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/get", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/find", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/get", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/find", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/get", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/find", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/get", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/find", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/get", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/find", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/findBackfill", + "alerting:logs.alert.document.count/observability/rule/get", + "alerting:logs.alert.document.count/observability/rule/getRuleState", + "alerting:logs.alert.document.count/observability/rule/getAlertSummary", + "alerting:logs.alert.document.count/observability/rule/getExecutionLog", + "alerting:logs.alert.document.count/observability/rule/getActionErrorLog", + "alerting:logs.alert.document.count/observability/rule/find", + "alerting:logs.alert.document.count/observability/rule/getRuleExecutionKPI", + "alerting:logs.alert.document.count/observability/rule/getBackfill", + "alerting:logs.alert.document.count/observability/rule/findBackfill", + "alerting:logs.alert.document.count/alerts/rule/get", + "alerting:logs.alert.document.count/alerts/rule/getRuleState", + "alerting:logs.alert.document.count/alerts/rule/getAlertSummary", + "alerting:logs.alert.document.count/alerts/rule/getExecutionLog", + "alerting:logs.alert.document.count/alerts/rule/getActionErrorLog", + "alerting:logs.alert.document.count/alerts/rule/find", + "alerting:logs.alert.document.count/alerts/rule/getRuleExecutionKPI", + "alerting:logs.alert.document.count/alerts/rule/getBackfill", + "alerting:logs.alert.document.count/alerts/rule/findBackfill", + "alerting:slo.rules.burnRate/observability/rule/get", + "alerting:slo.rules.burnRate/observability/rule/getRuleState", + "alerting:slo.rules.burnRate/observability/rule/getAlertSummary", + "alerting:slo.rules.burnRate/observability/rule/getExecutionLog", + "alerting:slo.rules.burnRate/observability/rule/getActionErrorLog", + "alerting:slo.rules.burnRate/observability/rule/find", + "alerting:slo.rules.burnRate/observability/rule/getRuleExecutionKPI", + "alerting:slo.rules.burnRate/observability/rule/getBackfill", + "alerting:slo.rules.burnRate/observability/rule/findBackfill", + "alerting:slo.rules.burnRate/alerts/rule/get", + "alerting:slo.rules.burnRate/alerts/rule/getRuleState", + "alerting:slo.rules.burnRate/alerts/rule/getAlertSummary", + "alerting:slo.rules.burnRate/alerts/rule/getExecutionLog", + "alerting:slo.rules.burnRate/alerts/rule/getActionErrorLog", + "alerting:slo.rules.burnRate/alerts/rule/find", + "alerting:slo.rules.burnRate/alerts/rule/getRuleExecutionKPI", + "alerting:slo.rules.burnRate/alerts/rule/getBackfill", + "alerting:slo.rules.burnRate/alerts/rule/findBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/get", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleState", + "alerting:observability.rules.custom_threshold/observability/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/observability/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/observability/rule/find", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/observability/rule/getBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/findBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/get", + "alerting:observability.rules.custom_threshold/alerts/rule/getRuleState", + "alerting:observability.rules.custom_threshold/alerts/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/alerts/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/alerts/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/alerts/rule/find", + "alerting:observability.rules.custom_threshold/alerts/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/alerts/rule/getBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/findBackfill", + "alerting:.es-query/observability/rule/get", + "alerting:.es-query/observability/rule/getRuleState", + "alerting:.es-query/observability/rule/getAlertSummary", + "alerting:.es-query/observability/rule/getExecutionLog", + "alerting:.es-query/observability/rule/getActionErrorLog", + "alerting:.es-query/observability/rule/find", + "alerting:.es-query/observability/rule/getRuleExecutionKPI", + "alerting:.es-query/observability/rule/getBackfill", + "alerting:.es-query/observability/rule/findBackfill", + "alerting:.es-query/alerts/rule/get", + "alerting:.es-query/alerts/rule/getRuleState", + "alerting:.es-query/alerts/rule/getAlertSummary", + "alerting:.es-query/alerts/rule/getExecutionLog", + "alerting:.es-query/alerts/rule/getActionErrorLog", + "alerting:.es-query/alerts/rule/find", + "alerting:.es-query/alerts/rule/getRuleExecutionKPI", + "alerting:.es-query/alerts/rule/getBackfill", + "alerting:.es-query/alerts/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/findBackfill", "alerting:apm.error_rate/observability/alert/get", "alerting:apm.error_rate/observability/alert/find", "alerting:apm.error_rate/observability/alert/getAuthorizedAlertsIndices", "alerting:apm.error_rate/observability/alert/getAlertSummary", + "alerting:apm.error_rate/alerts/alert/get", + "alerting:apm.error_rate/alerts/alert/find", + "alerting:apm.error_rate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.error_rate/alerts/alert/getAlertSummary", "alerting:apm.transaction_error_rate/observability/alert/get", "alerting:apm.transaction_error_rate/observability/alert/find", "alerting:apm.transaction_error_rate/observability/alert/getAuthorizedAlertsIndices", "alerting:apm.transaction_error_rate/observability/alert/getAlertSummary", + "alerting:apm.transaction_error_rate/alerts/alert/get", + "alerting:apm.transaction_error_rate/alerts/alert/find", + "alerting:apm.transaction_error_rate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_error_rate/alerts/alert/getAlertSummary", "alerting:apm.transaction_duration/observability/alert/get", "alerting:apm.transaction_duration/observability/alert/find", "alerting:apm.transaction_duration/observability/alert/getAuthorizedAlertsIndices", "alerting:apm.transaction_duration/observability/alert/getAlertSummary", + "alerting:apm.transaction_duration/alerts/alert/get", + "alerting:apm.transaction_duration/alerts/alert/find", + "alerting:apm.transaction_duration/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_duration/alerts/alert/getAlertSummary", "alerting:apm.anomaly/observability/alert/get", "alerting:apm.anomaly/observability/alert/find", "alerting:apm.anomaly/observability/alert/getAuthorizedAlertsIndices", "alerting:apm.anomaly/observability/alert/getAlertSummary", + "alerting:apm.anomaly/alerts/alert/get", + "alerting:apm.anomaly/alerts/alert/find", + "alerting:apm.anomaly/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.anomaly/alerts/alert/getAlertSummary", "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/get", "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/find", "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/getAuthorizedAlertsIndices", "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/getAlertSummary", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/get", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/find", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/getAlertSummary", "alerting:xpack.synthetics.alerts.tls/observability/alert/get", "alerting:xpack.synthetics.alerts.tls/observability/alert/find", "alerting:xpack.synthetics.alerts.tls/observability/alert/getAuthorizedAlertsIndices", "alerting:xpack.synthetics.alerts.tls/observability/alert/getAlertSummary", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/get", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/find", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/getAlertSummary", + "alerting:metrics.alert.threshold/observability/alert/get", + "alerting:metrics.alert.threshold/observability/alert/find", + "alerting:metrics.alert.threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.threshold/observability/alert/getAlertSummary", + "alerting:metrics.alert.threshold/alerts/alert/get", + "alerting:metrics.alert.threshold/alerts/alert/find", + "alerting:metrics.alert.threshold/alerts/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.threshold/alerts/alert/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/alert/get", + "alerting:metrics.alert.inventory.threshold/observability/alert/find", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/alerts/alert/get", + "alerting:metrics.alert.inventory.threshold/alerts/alert/find", + "alerting:metrics.alert.inventory.threshold/alerts/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.inventory.threshold/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/observability/alert/get", + "alerting:xpack.uptime.alerts.tls/observability/alert/find", + "alerting:xpack.uptime.alerts.tls/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tls/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/alerts/alert/get", + "alerting:xpack.uptime.alerts.tls/alerts/alert/find", + "alerting:xpack.uptime.alerts.tls/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tls/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/get", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/find", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/get", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/find", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/get", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/find", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/get", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/find", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/get", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/find", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/get", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/find", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/getAlertSummary", + "alerting:logs.alert.document.count/observability/alert/get", + "alerting:logs.alert.document.count/observability/alert/find", + "alerting:logs.alert.document.count/observability/alert/getAuthorizedAlertsIndices", + "alerting:logs.alert.document.count/observability/alert/getAlertSummary", + "alerting:logs.alert.document.count/alerts/alert/get", + "alerting:logs.alert.document.count/alerts/alert/find", + "alerting:logs.alert.document.count/alerts/alert/getAuthorizedAlertsIndices", + "alerting:logs.alert.document.count/alerts/alert/getAlertSummary", + "alerting:slo.rules.burnRate/observability/alert/get", + "alerting:slo.rules.burnRate/observability/alert/find", + "alerting:slo.rules.burnRate/observability/alert/getAuthorizedAlertsIndices", + "alerting:slo.rules.burnRate/observability/alert/getAlertSummary", + "alerting:slo.rules.burnRate/alerts/alert/get", + "alerting:slo.rules.burnRate/alerts/alert/find", + "alerting:slo.rules.burnRate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:slo.rules.burnRate/alerts/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/alert/get", + "alerting:observability.rules.custom_threshold/observability/alert/find", + "alerting:observability.rules.custom_threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/observability/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/alerts/alert/get", + "alerting:observability.rules.custom_threshold/alerts/alert/find", + "alerting:observability.rules.custom_threshold/alerts/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/alerts/alert/getAlertSummary", + "alerting:.es-query/observability/alert/get", + "alerting:.es-query/observability/alert/find", + "alerting:.es-query/observability/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/observability/alert/getAlertSummary", + "alerting:.es-query/alerts/alert/get", + "alerting:.es-query/alerts/alert/find", + "alerting:.es-query/alerts/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/alerts/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/getAlertSummary", ], "read": Array [ "login:", @@ -3838,51 +7772,6 @@ export default function ({ getService }: FtrProviderContext) { "ui:catalogue/observability", "ui:navLinks/observability", "ui:observability/read", - "alerting:slo.rules.burnRate/observability/rule/get", - "alerting:slo.rules.burnRate/observability/rule/getRuleState", - "alerting:slo.rules.burnRate/observability/rule/getAlertSummary", - "alerting:slo.rules.burnRate/observability/rule/getExecutionLog", - "alerting:slo.rules.burnRate/observability/rule/getActionErrorLog", - "alerting:slo.rules.burnRate/observability/rule/find", - "alerting:slo.rules.burnRate/observability/rule/getRuleExecutionKPI", - "alerting:slo.rules.burnRate/observability/rule/getBackfill", - "alerting:slo.rules.burnRate/observability/rule/findBackfill", - "alerting:observability.rules.custom_threshold/observability/rule/get", - "alerting:observability.rules.custom_threshold/observability/rule/getRuleState", - "alerting:observability.rules.custom_threshold/observability/rule/getAlertSummary", - "alerting:observability.rules.custom_threshold/observability/rule/getExecutionLog", - "alerting:observability.rules.custom_threshold/observability/rule/getActionErrorLog", - "alerting:observability.rules.custom_threshold/observability/rule/find", - "alerting:observability.rules.custom_threshold/observability/rule/getRuleExecutionKPI", - "alerting:observability.rules.custom_threshold/observability/rule/getBackfill", - "alerting:observability.rules.custom_threshold/observability/rule/findBackfill", - "alerting:.es-query/observability/rule/get", - "alerting:.es-query/observability/rule/getRuleState", - "alerting:.es-query/observability/rule/getAlertSummary", - "alerting:.es-query/observability/rule/getExecutionLog", - "alerting:.es-query/observability/rule/getActionErrorLog", - "alerting:.es-query/observability/rule/find", - "alerting:.es-query/observability/rule/getRuleExecutionKPI", - "alerting:.es-query/observability/rule/getBackfill", - "alerting:.es-query/observability/rule/findBackfill", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/get", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleState", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getAlertSummary", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getExecutionLog", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getActionErrorLog", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/find", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleExecutionKPI", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getBackfill", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/findBackfill", - "alerting:metrics.alert.inventory.threshold/observability/rule/get", - "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleState", - "alerting:metrics.alert.inventory.threshold/observability/rule/getAlertSummary", - "alerting:metrics.alert.inventory.threshold/observability/rule/getExecutionLog", - "alerting:metrics.alert.inventory.threshold/observability/rule/getActionErrorLog", - "alerting:metrics.alert.inventory.threshold/observability/rule/find", - "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleExecutionKPI", - "alerting:metrics.alert.inventory.threshold/observability/rule/getBackfill", - "alerting:metrics.alert.inventory.threshold/observability/rule/findBackfill", "alerting:apm.error_rate/observability/rule/get", "alerting:apm.error_rate/observability/rule/getRuleState", "alerting:apm.error_rate/observability/rule/getAlertSummary", @@ -3892,6 +7781,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.error_rate/observability/rule/getRuleExecutionKPI", "alerting:apm.error_rate/observability/rule/getBackfill", "alerting:apm.error_rate/observability/rule/findBackfill", + "alerting:apm.error_rate/alerts/rule/get", + "alerting:apm.error_rate/alerts/rule/getRuleState", + "alerting:apm.error_rate/alerts/rule/getAlertSummary", + "alerting:apm.error_rate/alerts/rule/getExecutionLog", + "alerting:apm.error_rate/alerts/rule/getActionErrorLog", + "alerting:apm.error_rate/alerts/rule/find", + "alerting:apm.error_rate/alerts/rule/getRuleExecutionKPI", + "alerting:apm.error_rate/alerts/rule/getBackfill", + "alerting:apm.error_rate/alerts/rule/findBackfill", "alerting:apm.transaction_error_rate/observability/rule/get", "alerting:apm.transaction_error_rate/observability/rule/getRuleState", "alerting:apm.transaction_error_rate/observability/rule/getAlertSummary", @@ -3901,6 +7799,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.transaction_error_rate/observability/rule/getRuleExecutionKPI", "alerting:apm.transaction_error_rate/observability/rule/getBackfill", "alerting:apm.transaction_error_rate/observability/rule/findBackfill", + "alerting:apm.transaction_error_rate/alerts/rule/get", + "alerting:apm.transaction_error_rate/alerts/rule/getRuleState", + "alerting:apm.transaction_error_rate/alerts/rule/getAlertSummary", + "alerting:apm.transaction_error_rate/alerts/rule/getExecutionLog", + "alerting:apm.transaction_error_rate/alerts/rule/getActionErrorLog", + "alerting:apm.transaction_error_rate/alerts/rule/find", + "alerting:apm.transaction_error_rate/alerts/rule/getRuleExecutionKPI", + "alerting:apm.transaction_error_rate/alerts/rule/getBackfill", + "alerting:apm.transaction_error_rate/alerts/rule/findBackfill", "alerting:apm.transaction_duration/observability/rule/get", "alerting:apm.transaction_duration/observability/rule/getRuleState", "alerting:apm.transaction_duration/observability/rule/getAlertSummary", @@ -3910,6 +7817,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.transaction_duration/observability/rule/getRuleExecutionKPI", "alerting:apm.transaction_duration/observability/rule/getBackfill", "alerting:apm.transaction_duration/observability/rule/findBackfill", + "alerting:apm.transaction_duration/alerts/rule/get", + "alerting:apm.transaction_duration/alerts/rule/getRuleState", + "alerting:apm.transaction_duration/alerts/rule/getAlertSummary", + "alerting:apm.transaction_duration/alerts/rule/getExecutionLog", + "alerting:apm.transaction_duration/alerts/rule/getActionErrorLog", + "alerting:apm.transaction_duration/alerts/rule/find", + "alerting:apm.transaction_duration/alerts/rule/getRuleExecutionKPI", + "alerting:apm.transaction_duration/alerts/rule/getBackfill", + "alerting:apm.transaction_duration/alerts/rule/findBackfill", "alerting:apm.anomaly/observability/rule/get", "alerting:apm.anomaly/observability/rule/getRuleState", "alerting:apm.anomaly/observability/rule/getAlertSummary", @@ -3919,6 +7835,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.anomaly/observability/rule/getRuleExecutionKPI", "alerting:apm.anomaly/observability/rule/getBackfill", "alerting:apm.anomaly/observability/rule/findBackfill", + "alerting:apm.anomaly/alerts/rule/get", + "alerting:apm.anomaly/alerts/rule/getRuleState", + "alerting:apm.anomaly/alerts/rule/getAlertSummary", + "alerting:apm.anomaly/alerts/rule/getExecutionLog", + "alerting:apm.anomaly/alerts/rule/getActionErrorLog", + "alerting:apm.anomaly/alerts/rule/find", + "alerting:apm.anomaly/alerts/rule/getRuleExecutionKPI", + "alerting:apm.anomaly/alerts/rule/getBackfill", + "alerting:apm.anomaly/alerts/rule/findBackfill", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/get", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/getRuleState", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/getAlertSummary", @@ -3928,6 +7853,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/getRuleExecutionKPI", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/getBackfill", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/findBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/get", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getRuleState", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getAlertSummary", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getExecutionLog", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getActionErrorLog", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/find", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/findBackfill", "alerting:xpack.synthetics.alerts.tls/observability/rule/get", "alerting:xpack.synthetics.alerts.tls/observability/rule/getRuleState", "alerting:xpack.synthetics.alerts.tls/observability/rule/getAlertSummary", @@ -3937,50 +7871,349 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.synthetics.alerts.tls/observability/rule/getRuleExecutionKPI", "alerting:xpack.synthetics.alerts.tls/observability/rule/getBackfill", "alerting:xpack.synthetics.alerts.tls/observability/rule/findBackfill", - "alerting:slo.rules.burnRate/observability/alert/get", - "alerting:slo.rules.burnRate/observability/alert/find", - "alerting:slo.rules.burnRate/observability/alert/getAuthorizedAlertsIndices", - "alerting:slo.rules.burnRate/observability/alert/getAlertSummary", - "alerting:observability.rules.custom_threshold/observability/alert/get", - "alerting:observability.rules.custom_threshold/observability/alert/find", - "alerting:observability.rules.custom_threshold/observability/alert/getAuthorizedAlertsIndices", - "alerting:observability.rules.custom_threshold/observability/alert/getAlertSummary", - "alerting:.es-query/observability/alert/get", - "alerting:.es-query/observability/alert/find", - "alerting:.es-query/observability/alert/getAuthorizedAlertsIndices", - "alerting:.es-query/observability/alert/getAlertSummary", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/get", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/find", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAuthorizedAlertsIndices", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAlertSummary", - "alerting:metrics.alert.inventory.threshold/observability/alert/get", - "alerting:metrics.alert.inventory.threshold/observability/alert/find", - "alerting:metrics.alert.inventory.threshold/observability/alert/getAuthorizedAlertsIndices", - "alerting:metrics.alert.inventory.threshold/observability/alert/getAlertSummary", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/get", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getRuleState", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getAlertSummary", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getExecutionLog", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getActionErrorLog", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/find", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getBackfill", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/findBackfill", + "alerting:metrics.alert.threshold/observability/rule/get", + "alerting:metrics.alert.threshold/observability/rule/getRuleState", + "alerting:metrics.alert.threshold/observability/rule/getAlertSummary", + "alerting:metrics.alert.threshold/observability/rule/getExecutionLog", + "alerting:metrics.alert.threshold/observability/rule/getActionErrorLog", + "alerting:metrics.alert.threshold/observability/rule/find", + "alerting:metrics.alert.threshold/observability/rule/getRuleExecutionKPI", + "alerting:metrics.alert.threshold/observability/rule/getBackfill", + "alerting:metrics.alert.threshold/observability/rule/findBackfill", + "alerting:metrics.alert.threshold/alerts/rule/get", + "alerting:metrics.alert.threshold/alerts/rule/getRuleState", + "alerting:metrics.alert.threshold/alerts/rule/getAlertSummary", + "alerting:metrics.alert.threshold/alerts/rule/getExecutionLog", + "alerting:metrics.alert.threshold/alerts/rule/getActionErrorLog", + "alerting:metrics.alert.threshold/alerts/rule/find", + "alerting:metrics.alert.threshold/alerts/rule/getRuleExecutionKPI", + "alerting:metrics.alert.threshold/alerts/rule/getBackfill", + "alerting:metrics.alert.threshold/alerts/rule/findBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/get", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleState", + "alerting:metrics.alert.inventory.threshold/observability/rule/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/rule/getExecutionLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/getActionErrorLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/find", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleExecutionKPI", + "alerting:metrics.alert.inventory.threshold/observability/rule/getBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/findBackfill", + "alerting:metrics.alert.inventory.threshold/alerts/rule/get", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getRuleState", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getExecutionLog", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getActionErrorLog", + "alerting:metrics.alert.inventory.threshold/alerts/rule/find", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getRuleExecutionKPI", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getBackfill", + "alerting:metrics.alert.inventory.threshold/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.tls/observability/rule/get", + "alerting:xpack.uptime.alerts.tls/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.tls/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tls/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tls/observability/rule/find", + "alerting:xpack.uptime.alerts.tls/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tls/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.tls/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.tls/alerts/rule/get", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tls/alerts/rule/find", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.tls/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/get", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/find", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/get", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/find", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/get", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/find", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/get", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/find", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/get", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/find", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/get", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/find", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/findBackfill", + "alerting:logs.alert.document.count/observability/rule/get", + "alerting:logs.alert.document.count/observability/rule/getRuleState", + "alerting:logs.alert.document.count/observability/rule/getAlertSummary", + "alerting:logs.alert.document.count/observability/rule/getExecutionLog", + "alerting:logs.alert.document.count/observability/rule/getActionErrorLog", + "alerting:logs.alert.document.count/observability/rule/find", + "alerting:logs.alert.document.count/observability/rule/getRuleExecutionKPI", + "alerting:logs.alert.document.count/observability/rule/getBackfill", + "alerting:logs.alert.document.count/observability/rule/findBackfill", + "alerting:logs.alert.document.count/alerts/rule/get", + "alerting:logs.alert.document.count/alerts/rule/getRuleState", + "alerting:logs.alert.document.count/alerts/rule/getAlertSummary", + "alerting:logs.alert.document.count/alerts/rule/getExecutionLog", + "alerting:logs.alert.document.count/alerts/rule/getActionErrorLog", + "alerting:logs.alert.document.count/alerts/rule/find", + "alerting:logs.alert.document.count/alerts/rule/getRuleExecutionKPI", + "alerting:logs.alert.document.count/alerts/rule/getBackfill", + "alerting:logs.alert.document.count/alerts/rule/findBackfill", + "alerting:slo.rules.burnRate/observability/rule/get", + "alerting:slo.rules.burnRate/observability/rule/getRuleState", + "alerting:slo.rules.burnRate/observability/rule/getAlertSummary", + "alerting:slo.rules.burnRate/observability/rule/getExecutionLog", + "alerting:slo.rules.burnRate/observability/rule/getActionErrorLog", + "alerting:slo.rules.burnRate/observability/rule/find", + "alerting:slo.rules.burnRate/observability/rule/getRuleExecutionKPI", + "alerting:slo.rules.burnRate/observability/rule/getBackfill", + "alerting:slo.rules.burnRate/observability/rule/findBackfill", + "alerting:slo.rules.burnRate/alerts/rule/get", + "alerting:slo.rules.burnRate/alerts/rule/getRuleState", + "alerting:slo.rules.burnRate/alerts/rule/getAlertSummary", + "alerting:slo.rules.burnRate/alerts/rule/getExecutionLog", + "alerting:slo.rules.burnRate/alerts/rule/getActionErrorLog", + "alerting:slo.rules.burnRate/alerts/rule/find", + "alerting:slo.rules.burnRate/alerts/rule/getRuleExecutionKPI", + "alerting:slo.rules.burnRate/alerts/rule/getBackfill", + "alerting:slo.rules.burnRate/alerts/rule/findBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/get", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleState", + "alerting:observability.rules.custom_threshold/observability/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/observability/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/observability/rule/find", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/observability/rule/getBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/findBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/get", + "alerting:observability.rules.custom_threshold/alerts/rule/getRuleState", + "alerting:observability.rules.custom_threshold/alerts/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/alerts/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/alerts/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/alerts/rule/find", + "alerting:observability.rules.custom_threshold/alerts/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/alerts/rule/getBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/findBackfill", + "alerting:.es-query/observability/rule/get", + "alerting:.es-query/observability/rule/getRuleState", + "alerting:.es-query/observability/rule/getAlertSummary", + "alerting:.es-query/observability/rule/getExecutionLog", + "alerting:.es-query/observability/rule/getActionErrorLog", + "alerting:.es-query/observability/rule/find", + "alerting:.es-query/observability/rule/getRuleExecutionKPI", + "alerting:.es-query/observability/rule/getBackfill", + "alerting:.es-query/observability/rule/findBackfill", + "alerting:.es-query/alerts/rule/get", + "alerting:.es-query/alerts/rule/getRuleState", + "alerting:.es-query/alerts/rule/getAlertSummary", + "alerting:.es-query/alerts/rule/getExecutionLog", + "alerting:.es-query/alerts/rule/getActionErrorLog", + "alerting:.es-query/alerts/rule/find", + "alerting:.es-query/alerts/rule/getRuleExecutionKPI", + "alerting:.es-query/alerts/rule/getBackfill", + "alerting:.es-query/alerts/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/findBackfill", "alerting:apm.error_rate/observability/alert/get", "alerting:apm.error_rate/observability/alert/find", "alerting:apm.error_rate/observability/alert/getAuthorizedAlertsIndices", "alerting:apm.error_rate/observability/alert/getAlertSummary", + "alerting:apm.error_rate/alerts/alert/get", + "alerting:apm.error_rate/alerts/alert/find", + "alerting:apm.error_rate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.error_rate/alerts/alert/getAlertSummary", "alerting:apm.transaction_error_rate/observability/alert/get", "alerting:apm.transaction_error_rate/observability/alert/find", "alerting:apm.transaction_error_rate/observability/alert/getAuthorizedAlertsIndices", "alerting:apm.transaction_error_rate/observability/alert/getAlertSummary", + "alerting:apm.transaction_error_rate/alerts/alert/get", + "alerting:apm.transaction_error_rate/alerts/alert/find", + "alerting:apm.transaction_error_rate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_error_rate/alerts/alert/getAlertSummary", "alerting:apm.transaction_duration/observability/alert/get", "alerting:apm.transaction_duration/observability/alert/find", "alerting:apm.transaction_duration/observability/alert/getAuthorizedAlertsIndices", "alerting:apm.transaction_duration/observability/alert/getAlertSummary", + "alerting:apm.transaction_duration/alerts/alert/get", + "alerting:apm.transaction_duration/alerts/alert/find", + "alerting:apm.transaction_duration/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_duration/alerts/alert/getAlertSummary", "alerting:apm.anomaly/observability/alert/get", "alerting:apm.anomaly/observability/alert/find", "alerting:apm.anomaly/observability/alert/getAuthorizedAlertsIndices", "alerting:apm.anomaly/observability/alert/getAlertSummary", + "alerting:apm.anomaly/alerts/alert/get", + "alerting:apm.anomaly/alerts/alert/find", + "alerting:apm.anomaly/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.anomaly/alerts/alert/getAlertSummary", "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/get", "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/find", "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/getAuthorizedAlertsIndices", "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/getAlertSummary", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/get", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/find", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/getAlertSummary", "alerting:xpack.synthetics.alerts.tls/observability/alert/get", "alerting:xpack.synthetics.alerts.tls/observability/alert/find", "alerting:xpack.synthetics.alerts.tls/observability/alert/getAuthorizedAlertsIndices", "alerting:xpack.synthetics.alerts.tls/observability/alert/getAlertSummary", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/get", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/find", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/getAlertSummary", + "alerting:metrics.alert.threshold/observability/alert/get", + "alerting:metrics.alert.threshold/observability/alert/find", + "alerting:metrics.alert.threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.threshold/observability/alert/getAlertSummary", + "alerting:metrics.alert.threshold/alerts/alert/get", + "alerting:metrics.alert.threshold/alerts/alert/find", + "alerting:metrics.alert.threshold/alerts/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.threshold/alerts/alert/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/alert/get", + "alerting:metrics.alert.inventory.threshold/observability/alert/find", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/alerts/alert/get", + "alerting:metrics.alert.inventory.threshold/alerts/alert/find", + "alerting:metrics.alert.inventory.threshold/alerts/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.inventory.threshold/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/observability/alert/get", + "alerting:xpack.uptime.alerts.tls/observability/alert/find", + "alerting:xpack.uptime.alerts.tls/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tls/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/alerts/alert/get", + "alerting:xpack.uptime.alerts.tls/alerts/alert/find", + "alerting:xpack.uptime.alerts.tls/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tls/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/get", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/find", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/get", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/find", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/get", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/find", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/get", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/find", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/get", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/find", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/get", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/find", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/getAlertSummary", + "alerting:logs.alert.document.count/observability/alert/get", + "alerting:logs.alert.document.count/observability/alert/find", + "alerting:logs.alert.document.count/observability/alert/getAuthorizedAlertsIndices", + "alerting:logs.alert.document.count/observability/alert/getAlertSummary", + "alerting:logs.alert.document.count/alerts/alert/get", + "alerting:logs.alert.document.count/alerts/alert/find", + "alerting:logs.alert.document.count/alerts/alert/getAuthorizedAlertsIndices", + "alerting:logs.alert.document.count/alerts/alert/getAlertSummary", + "alerting:slo.rules.burnRate/observability/alert/get", + "alerting:slo.rules.burnRate/observability/alert/find", + "alerting:slo.rules.burnRate/observability/alert/getAuthorizedAlertsIndices", + "alerting:slo.rules.burnRate/observability/alert/getAlertSummary", + "alerting:slo.rules.burnRate/alerts/alert/get", + "alerting:slo.rules.burnRate/alerts/alert/find", + "alerting:slo.rules.burnRate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:slo.rules.burnRate/alerts/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/alert/get", + "alerting:observability.rules.custom_threshold/observability/alert/find", + "alerting:observability.rules.custom_threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/observability/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/alerts/alert/get", + "alerting:observability.rules.custom_threshold/alerts/alert/find", + "alerting:observability.rules.custom_threshold/alerts/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/alerts/alert/getAlertSummary", + "alerting:.es-query/observability/alert/get", + "alerting:.es-query/observability/alert/find", + "alerting:.es-query/observability/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/observability/alert/getAlertSummary", + "alerting:.es-query/alerts/alert/get", + "alerting:.es-query/alerts/alert/find", + "alerting:.es-query/alerts/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/alerts/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/getAlertSummary", ], "store_search_session": Array [ "login:", @@ -4266,6 +8499,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:logs.alert.document.count/logs/rule/runSoon", "alerting:logs.alert.document.count/logs/rule/scheduleBackfill", "alerting:logs.alert.document.count/logs/rule/deleteBackfill", + "alerting:logs.alert.document.count/alerts/rule/get", + "alerting:logs.alert.document.count/alerts/rule/getRuleState", + "alerting:logs.alert.document.count/alerts/rule/getAlertSummary", + "alerting:logs.alert.document.count/alerts/rule/getExecutionLog", + "alerting:logs.alert.document.count/alerts/rule/getActionErrorLog", + "alerting:logs.alert.document.count/alerts/rule/find", + "alerting:logs.alert.document.count/alerts/rule/getRuleExecutionKPI", + "alerting:logs.alert.document.count/alerts/rule/getBackfill", + "alerting:logs.alert.document.count/alerts/rule/findBackfill", + "alerting:logs.alert.document.count/alerts/rule/create", + "alerting:logs.alert.document.count/alerts/rule/delete", + "alerting:logs.alert.document.count/alerts/rule/update", + "alerting:logs.alert.document.count/alerts/rule/updateApiKey", + "alerting:logs.alert.document.count/alerts/rule/enable", + "alerting:logs.alert.document.count/alerts/rule/disable", + "alerting:logs.alert.document.count/alerts/rule/muteAll", + "alerting:logs.alert.document.count/alerts/rule/unmuteAll", + "alerting:logs.alert.document.count/alerts/rule/muteAlert", + "alerting:logs.alert.document.count/alerts/rule/unmuteAlert", + "alerting:logs.alert.document.count/alerts/rule/snooze", + "alerting:logs.alert.document.count/alerts/rule/bulkEdit", + "alerting:logs.alert.document.count/alerts/rule/bulkDelete", + "alerting:logs.alert.document.count/alerts/rule/bulkEnable", + "alerting:logs.alert.document.count/alerts/rule/bulkDisable", + "alerting:logs.alert.document.count/alerts/rule/unsnooze", + "alerting:logs.alert.document.count/alerts/rule/runSoon", + "alerting:logs.alert.document.count/alerts/rule/scheduleBackfill", + "alerting:logs.alert.document.count/alerts/rule/deleteBackfill", "alerting:.es-query/logs/rule/get", "alerting:.es-query/logs/rule/getRuleState", "alerting:.es-query/logs/rule/getAlertSummary", @@ -4294,6 +8555,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:.es-query/logs/rule/runSoon", "alerting:.es-query/logs/rule/scheduleBackfill", "alerting:.es-query/logs/rule/deleteBackfill", + "alerting:.es-query/alerts/rule/get", + "alerting:.es-query/alerts/rule/getRuleState", + "alerting:.es-query/alerts/rule/getAlertSummary", + "alerting:.es-query/alerts/rule/getExecutionLog", + "alerting:.es-query/alerts/rule/getActionErrorLog", + "alerting:.es-query/alerts/rule/find", + "alerting:.es-query/alerts/rule/getRuleExecutionKPI", + "alerting:.es-query/alerts/rule/getBackfill", + "alerting:.es-query/alerts/rule/findBackfill", + "alerting:.es-query/alerts/rule/create", + "alerting:.es-query/alerts/rule/delete", + "alerting:.es-query/alerts/rule/update", + "alerting:.es-query/alerts/rule/updateApiKey", + "alerting:.es-query/alerts/rule/enable", + "alerting:.es-query/alerts/rule/disable", + "alerting:.es-query/alerts/rule/muteAll", + "alerting:.es-query/alerts/rule/unmuteAll", + "alerting:.es-query/alerts/rule/muteAlert", + "alerting:.es-query/alerts/rule/unmuteAlert", + "alerting:.es-query/alerts/rule/snooze", + "alerting:.es-query/alerts/rule/bulkEdit", + "alerting:.es-query/alerts/rule/bulkDelete", + "alerting:.es-query/alerts/rule/bulkEnable", + "alerting:.es-query/alerts/rule/bulkDisable", + "alerting:.es-query/alerts/rule/unsnooze", + "alerting:.es-query/alerts/rule/runSoon", + "alerting:.es-query/alerts/rule/scheduleBackfill", + "alerting:.es-query/alerts/rule/deleteBackfill", "alerting:observability.rules.custom_threshold/logs/rule/get", "alerting:observability.rules.custom_threshold/logs/rule/getRuleState", "alerting:observability.rules.custom_threshold/logs/rule/getAlertSummary", @@ -4322,6 +8611,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:observability.rules.custom_threshold/logs/rule/runSoon", "alerting:observability.rules.custom_threshold/logs/rule/scheduleBackfill", "alerting:observability.rules.custom_threshold/logs/rule/deleteBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/get", + "alerting:observability.rules.custom_threshold/alerts/rule/getRuleState", + "alerting:observability.rules.custom_threshold/alerts/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/alerts/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/alerts/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/alerts/rule/find", + "alerting:observability.rules.custom_threshold/alerts/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/alerts/rule/getBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/findBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/create", + "alerting:observability.rules.custom_threshold/alerts/rule/delete", + "alerting:observability.rules.custom_threshold/alerts/rule/update", + "alerting:observability.rules.custom_threshold/alerts/rule/updateApiKey", + "alerting:observability.rules.custom_threshold/alerts/rule/enable", + "alerting:observability.rules.custom_threshold/alerts/rule/disable", + "alerting:observability.rules.custom_threshold/alerts/rule/muteAll", + "alerting:observability.rules.custom_threshold/alerts/rule/unmuteAll", + "alerting:observability.rules.custom_threshold/alerts/rule/muteAlert", + "alerting:observability.rules.custom_threshold/alerts/rule/unmuteAlert", + "alerting:observability.rules.custom_threshold/alerts/rule/snooze", + "alerting:observability.rules.custom_threshold/alerts/rule/bulkEdit", + "alerting:observability.rules.custom_threshold/alerts/rule/bulkDelete", + "alerting:observability.rules.custom_threshold/alerts/rule/bulkEnable", + "alerting:observability.rules.custom_threshold/alerts/rule/bulkDisable", + "alerting:observability.rules.custom_threshold/alerts/rule/unsnooze", + "alerting:observability.rules.custom_threshold/alerts/rule/runSoon", + "alerting:observability.rules.custom_threshold/alerts/rule/scheduleBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/deleteBackfill", "alerting:xpack.ml.anomaly_detection_alert/logs/rule/get", "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getRuleState", "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getAlertSummary", @@ -4350,26 +8667,74 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.ml.anomaly_detection_alert/logs/rule/runSoon", "alerting:xpack.ml.anomaly_detection_alert/logs/rule/scheduleBackfill", "alerting:xpack.ml.anomaly_detection_alert/logs/rule/deleteBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/create", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/delete", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/update", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/updateApiKey", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/enable", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/disable", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/muteAll", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/unmuteAll", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/muteAlert", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/unmuteAlert", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/snooze", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/bulkEdit", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/bulkDelete", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/bulkEnable", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/bulkDisable", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/unsnooze", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/runSoon", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/scheduleBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/deleteBackfill", "alerting:logs.alert.document.count/logs/alert/get", "alerting:logs.alert.document.count/logs/alert/find", "alerting:logs.alert.document.count/logs/alert/getAuthorizedAlertsIndices", "alerting:logs.alert.document.count/logs/alert/getAlertSummary", "alerting:logs.alert.document.count/logs/alert/update", + "alerting:logs.alert.document.count/alerts/alert/get", + "alerting:logs.alert.document.count/alerts/alert/find", + "alerting:logs.alert.document.count/alerts/alert/getAuthorizedAlertsIndices", + "alerting:logs.alert.document.count/alerts/alert/getAlertSummary", + "alerting:logs.alert.document.count/alerts/alert/update", "alerting:.es-query/logs/alert/get", "alerting:.es-query/logs/alert/find", "alerting:.es-query/logs/alert/getAuthorizedAlertsIndices", "alerting:.es-query/logs/alert/getAlertSummary", "alerting:.es-query/logs/alert/update", + "alerting:.es-query/alerts/alert/get", + "alerting:.es-query/alerts/alert/find", + "alerting:.es-query/alerts/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/alerts/alert/getAlertSummary", + "alerting:.es-query/alerts/alert/update", "alerting:observability.rules.custom_threshold/logs/alert/get", "alerting:observability.rules.custom_threshold/logs/alert/find", "alerting:observability.rules.custom_threshold/logs/alert/getAuthorizedAlertsIndices", "alerting:observability.rules.custom_threshold/logs/alert/getAlertSummary", "alerting:observability.rules.custom_threshold/logs/alert/update", + "alerting:observability.rules.custom_threshold/alerts/alert/get", + "alerting:observability.rules.custom_threshold/alerts/alert/find", + "alerting:observability.rules.custom_threshold/alerts/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/alerts/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/alerts/alert/update", "alerting:xpack.ml.anomaly_detection_alert/logs/alert/get", "alerting:xpack.ml.anomaly_detection_alert/logs/alert/find", "alerting:xpack.ml.anomaly_detection_alert/logs/alert/getAuthorizedAlertsIndices", "alerting:xpack.ml.anomaly_detection_alert/logs/alert/getAlertSummary", "alerting:xpack.ml.anomaly_detection_alert/logs/alert/update", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/update", ], "minimal_all": Array [ "login:", @@ -4619,6 +8984,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:logs.alert.document.count/logs/rule/runSoon", "alerting:logs.alert.document.count/logs/rule/scheduleBackfill", "alerting:logs.alert.document.count/logs/rule/deleteBackfill", + "alerting:logs.alert.document.count/alerts/rule/get", + "alerting:logs.alert.document.count/alerts/rule/getRuleState", + "alerting:logs.alert.document.count/alerts/rule/getAlertSummary", + "alerting:logs.alert.document.count/alerts/rule/getExecutionLog", + "alerting:logs.alert.document.count/alerts/rule/getActionErrorLog", + "alerting:logs.alert.document.count/alerts/rule/find", + "alerting:logs.alert.document.count/alerts/rule/getRuleExecutionKPI", + "alerting:logs.alert.document.count/alerts/rule/getBackfill", + "alerting:logs.alert.document.count/alerts/rule/findBackfill", + "alerting:logs.alert.document.count/alerts/rule/create", + "alerting:logs.alert.document.count/alerts/rule/delete", + "alerting:logs.alert.document.count/alerts/rule/update", + "alerting:logs.alert.document.count/alerts/rule/updateApiKey", + "alerting:logs.alert.document.count/alerts/rule/enable", + "alerting:logs.alert.document.count/alerts/rule/disable", + "alerting:logs.alert.document.count/alerts/rule/muteAll", + "alerting:logs.alert.document.count/alerts/rule/unmuteAll", + "alerting:logs.alert.document.count/alerts/rule/muteAlert", + "alerting:logs.alert.document.count/alerts/rule/unmuteAlert", + "alerting:logs.alert.document.count/alerts/rule/snooze", + "alerting:logs.alert.document.count/alerts/rule/bulkEdit", + "alerting:logs.alert.document.count/alerts/rule/bulkDelete", + "alerting:logs.alert.document.count/alerts/rule/bulkEnable", + "alerting:logs.alert.document.count/alerts/rule/bulkDisable", + "alerting:logs.alert.document.count/alerts/rule/unsnooze", + "alerting:logs.alert.document.count/alerts/rule/runSoon", + "alerting:logs.alert.document.count/alerts/rule/scheduleBackfill", + "alerting:logs.alert.document.count/alerts/rule/deleteBackfill", "alerting:.es-query/logs/rule/get", "alerting:.es-query/logs/rule/getRuleState", "alerting:.es-query/logs/rule/getAlertSummary", @@ -4647,6 +9040,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:.es-query/logs/rule/runSoon", "alerting:.es-query/logs/rule/scheduleBackfill", "alerting:.es-query/logs/rule/deleteBackfill", + "alerting:.es-query/alerts/rule/get", + "alerting:.es-query/alerts/rule/getRuleState", + "alerting:.es-query/alerts/rule/getAlertSummary", + "alerting:.es-query/alerts/rule/getExecutionLog", + "alerting:.es-query/alerts/rule/getActionErrorLog", + "alerting:.es-query/alerts/rule/find", + "alerting:.es-query/alerts/rule/getRuleExecutionKPI", + "alerting:.es-query/alerts/rule/getBackfill", + "alerting:.es-query/alerts/rule/findBackfill", + "alerting:.es-query/alerts/rule/create", + "alerting:.es-query/alerts/rule/delete", + "alerting:.es-query/alerts/rule/update", + "alerting:.es-query/alerts/rule/updateApiKey", + "alerting:.es-query/alerts/rule/enable", + "alerting:.es-query/alerts/rule/disable", + "alerting:.es-query/alerts/rule/muteAll", + "alerting:.es-query/alerts/rule/unmuteAll", + "alerting:.es-query/alerts/rule/muteAlert", + "alerting:.es-query/alerts/rule/unmuteAlert", + "alerting:.es-query/alerts/rule/snooze", + "alerting:.es-query/alerts/rule/bulkEdit", + "alerting:.es-query/alerts/rule/bulkDelete", + "alerting:.es-query/alerts/rule/bulkEnable", + "alerting:.es-query/alerts/rule/bulkDisable", + "alerting:.es-query/alerts/rule/unsnooze", + "alerting:.es-query/alerts/rule/runSoon", + "alerting:.es-query/alerts/rule/scheduleBackfill", + "alerting:.es-query/alerts/rule/deleteBackfill", "alerting:observability.rules.custom_threshold/logs/rule/get", "alerting:observability.rules.custom_threshold/logs/rule/getRuleState", "alerting:observability.rules.custom_threshold/logs/rule/getAlertSummary", @@ -4675,6 +9096,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:observability.rules.custom_threshold/logs/rule/runSoon", "alerting:observability.rules.custom_threshold/logs/rule/scheduleBackfill", "alerting:observability.rules.custom_threshold/logs/rule/deleteBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/get", + "alerting:observability.rules.custom_threshold/alerts/rule/getRuleState", + "alerting:observability.rules.custom_threshold/alerts/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/alerts/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/alerts/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/alerts/rule/find", + "alerting:observability.rules.custom_threshold/alerts/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/alerts/rule/getBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/findBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/create", + "alerting:observability.rules.custom_threshold/alerts/rule/delete", + "alerting:observability.rules.custom_threshold/alerts/rule/update", + "alerting:observability.rules.custom_threshold/alerts/rule/updateApiKey", + "alerting:observability.rules.custom_threshold/alerts/rule/enable", + "alerting:observability.rules.custom_threshold/alerts/rule/disable", + "alerting:observability.rules.custom_threshold/alerts/rule/muteAll", + "alerting:observability.rules.custom_threshold/alerts/rule/unmuteAll", + "alerting:observability.rules.custom_threshold/alerts/rule/muteAlert", + "alerting:observability.rules.custom_threshold/alerts/rule/unmuteAlert", + "alerting:observability.rules.custom_threshold/alerts/rule/snooze", + "alerting:observability.rules.custom_threshold/alerts/rule/bulkEdit", + "alerting:observability.rules.custom_threshold/alerts/rule/bulkDelete", + "alerting:observability.rules.custom_threshold/alerts/rule/bulkEnable", + "alerting:observability.rules.custom_threshold/alerts/rule/bulkDisable", + "alerting:observability.rules.custom_threshold/alerts/rule/unsnooze", + "alerting:observability.rules.custom_threshold/alerts/rule/runSoon", + "alerting:observability.rules.custom_threshold/alerts/rule/scheduleBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/deleteBackfill", "alerting:xpack.ml.anomaly_detection_alert/logs/rule/get", "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getRuleState", "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getAlertSummary", @@ -4703,26 +9152,74 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.ml.anomaly_detection_alert/logs/rule/runSoon", "alerting:xpack.ml.anomaly_detection_alert/logs/rule/scheduleBackfill", "alerting:xpack.ml.anomaly_detection_alert/logs/rule/deleteBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/create", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/delete", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/update", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/updateApiKey", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/enable", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/disable", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/muteAll", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/unmuteAll", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/muteAlert", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/unmuteAlert", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/snooze", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/bulkEdit", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/bulkDelete", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/bulkEnable", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/bulkDisable", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/unsnooze", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/runSoon", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/scheduleBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/deleteBackfill", "alerting:logs.alert.document.count/logs/alert/get", "alerting:logs.alert.document.count/logs/alert/find", "alerting:logs.alert.document.count/logs/alert/getAuthorizedAlertsIndices", "alerting:logs.alert.document.count/logs/alert/getAlertSummary", "alerting:logs.alert.document.count/logs/alert/update", + "alerting:logs.alert.document.count/alerts/alert/get", + "alerting:logs.alert.document.count/alerts/alert/find", + "alerting:logs.alert.document.count/alerts/alert/getAuthorizedAlertsIndices", + "alerting:logs.alert.document.count/alerts/alert/getAlertSummary", + "alerting:logs.alert.document.count/alerts/alert/update", "alerting:.es-query/logs/alert/get", "alerting:.es-query/logs/alert/find", "alerting:.es-query/logs/alert/getAuthorizedAlertsIndices", "alerting:.es-query/logs/alert/getAlertSummary", "alerting:.es-query/logs/alert/update", + "alerting:.es-query/alerts/alert/get", + "alerting:.es-query/alerts/alert/find", + "alerting:.es-query/alerts/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/alerts/alert/getAlertSummary", + "alerting:.es-query/alerts/alert/update", "alerting:observability.rules.custom_threshold/logs/alert/get", "alerting:observability.rules.custom_threshold/logs/alert/find", "alerting:observability.rules.custom_threshold/logs/alert/getAuthorizedAlertsIndices", "alerting:observability.rules.custom_threshold/logs/alert/getAlertSummary", "alerting:observability.rules.custom_threshold/logs/alert/update", + "alerting:observability.rules.custom_threshold/alerts/alert/get", + "alerting:observability.rules.custom_threshold/alerts/alert/find", + "alerting:observability.rules.custom_threshold/alerts/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/alerts/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/alerts/alert/update", "alerting:xpack.ml.anomaly_detection_alert/logs/alert/get", "alerting:xpack.ml.anomaly_detection_alert/logs/alert/find", "alerting:xpack.ml.anomaly_detection_alert/logs/alert/getAuthorizedAlertsIndices", "alerting:xpack.ml.anomaly_detection_alert/logs/alert/getAlertSummary", "alerting:xpack.ml.anomaly_detection_alert/logs/alert/update", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/update", ], "minimal_read": Array [ "login:", @@ -4844,6 +9341,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:logs.alert.document.count/logs/rule/getRuleExecutionKPI", "alerting:logs.alert.document.count/logs/rule/getBackfill", "alerting:logs.alert.document.count/logs/rule/findBackfill", + "alerting:logs.alert.document.count/alerts/rule/get", + "alerting:logs.alert.document.count/alerts/rule/getRuleState", + "alerting:logs.alert.document.count/alerts/rule/getAlertSummary", + "alerting:logs.alert.document.count/alerts/rule/getExecutionLog", + "alerting:logs.alert.document.count/alerts/rule/getActionErrorLog", + "alerting:logs.alert.document.count/alerts/rule/find", + "alerting:logs.alert.document.count/alerts/rule/getRuleExecutionKPI", + "alerting:logs.alert.document.count/alerts/rule/getBackfill", + "alerting:logs.alert.document.count/alerts/rule/findBackfill", "alerting:.es-query/logs/rule/get", "alerting:.es-query/logs/rule/getRuleState", "alerting:.es-query/logs/rule/getAlertSummary", @@ -4853,6 +9359,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:.es-query/logs/rule/getRuleExecutionKPI", "alerting:.es-query/logs/rule/getBackfill", "alerting:.es-query/logs/rule/findBackfill", + "alerting:.es-query/alerts/rule/get", + "alerting:.es-query/alerts/rule/getRuleState", + "alerting:.es-query/alerts/rule/getAlertSummary", + "alerting:.es-query/alerts/rule/getExecutionLog", + "alerting:.es-query/alerts/rule/getActionErrorLog", + "alerting:.es-query/alerts/rule/find", + "alerting:.es-query/alerts/rule/getRuleExecutionKPI", + "alerting:.es-query/alerts/rule/getBackfill", + "alerting:.es-query/alerts/rule/findBackfill", "alerting:observability.rules.custom_threshold/logs/rule/get", "alerting:observability.rules.custom_threshold/logs/rule/getRuleState", "alerting:observability.rules.custom_threshold/logs/rule/getAlertSummary", @@ -4862,6 +9377,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:observability.rules.custom_threshold/logs/rule/getRuleExecutionKPI", "alerting:observability.rules.custom_threshold/logs/rule/getBackfill", "alerting:observability.rules.custom_threshold/logs/rule/findBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/get", + "alerting:observability.rules.custom_threshold/alerts/rule/getRuleState", + "alerting:observability.rules.custom_threshold/alerts/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/alerts/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/alerts/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/alerts/rule/find", + "alerting:observability.rules.custom_threshold/alerts/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/alerts/rule/getBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/findBackfill", "alerting:xpack.ml.anomaly_detection_alert/logs/rule/get", "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getRuleState", "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getAlertSummary", @@ -4871,22 +9395,47 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getRuleExecutionKPI", "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getBackfill", "alerting:xpack.ml.anomaly_detection_alert/logs/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/findBackfill", "alerting:logs.alert.document.count/logs/alert/get", "alerting:logs.alert.document.count/logs/alert/find", "alerting:logs.alert.document.count/logs/alert/getAuthorizedAlertsIndices", "alerting:logs.alert.document.count/logs/alert/getAlertSummary", + "alerting:logs.alert.document.count/alerts/alert/get", + "alerting:logs.alert.document.count/alerts/alert/find", + "alerting:logs.alert.document.count/alerts/alert/getAuthorizedAlertsIndices", + "alerting:logs.alert.document.count/alerts/alert/getAlertSummary", "alerting:.es-query/logs/alert/get", "alerting:.es-query/logs/alert/find", "alerting:.es-query/logs/alert/getAuthorizedAlertsIndices", "alerting:.es-query/logs/alert/getAlertSummary", + "alerting:.es-query/alerts/alert/get", + "alerting:.es-query/alerts/alert/find", + "alerting:.es-query/alerts/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/alerts/alert/getAlertSummary", "alerting:observability.rules.custom_threshold/logs/alert/get", "alerting:observability.rules.custom_threshold/logs/alert/find", "alerting:observability.rules.custom_threshold/logs/alert/getAuthorizedAlertsIndices", "alerting:observability.rules.custom_threshold/logs/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/alerts/alert/get", + "alerting:observability.rules.custom_threshold/alerts/alert/find", + "alerting:observability.rules.custom_threshold/alerts/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/alerts/alert/getAlertSummary", "alerting:xpack.ml.anomaly_detection_alert/logs/alert/get", "alerting:xpack.ml.anomaly_detection_alert/logs/alert/find", "alerting:xpack.ml.anomaly_detection_alert/logs/alert/getAuthorizedAlertsIndices", "alerting:xpack.ml.anomaly_detection_alert/logs/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/getAlertSummary", ], "read": Array [ "login:", @@ -5008,6 +9557,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:logs.alert.document.count/logs/rule/getRuleExecutionKPI", "alerting:logs.alert.document.count/logs/rule/getBackfill", "alerting:logs.alert.document.count/logs/rule/findBackfill", + "alerting:logs.alert.document.count/alerts/rule/get", + "alerting:logs.alert.document.count/alerts/rule/getRuleState", + "alerting:logs.alert.document.count/alerts/rule/getAlertSummary", + "alerting:logs.alert.document.count/alerts/rule/getExecutionLog", + "alerting:logs.alert.document.count/alerts/rule/getActionErrorLog", + "alerting:logs.alert.document.count/alerts/rule/find", + "alerting:logs.alert.document.count/alerts/rule/getRuleExecutionKPI", + "alerting:logs.alert.document.count/alerts/rule/getBackfill", + "alerting:logs.alert.document.count/alerts/rule/findBackfill", "alerting:.es-query/logs/rule/get", "alerting:.es-query/logs/rule/getRuleState", "alerting:.es-query/logs/rule/getAlertSummary", @@ -5017,6 +9575,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:.es-query/logs/rule/getRuleExecutionKPI", "alerting:.es-query/logs/rule/getBackfill", "alerting:.es-query/logs/rule/findBackfill", + "alerting:.es-query/alerts/rule/get", + "alerting:.es-query/alerts/rule/getRuleState", + "alerting:.es-query/alerts/rule/getAlertSummary", + "alerting:.es-query/alerts/rule/getExecutionLog", + "alerting:.es-query/alerts/rule/getActionErrorLog", + "alerting:.es-query/alerts/rule/find", + "alerting:.es-query/alerts/rule/getRuleExecutionKPI", + "alerting:.es-query/alerts/rule/getBackfill", + "alerting:.es-query/alerts/rule/findBackfill", "alerting:observability.rules.custom_threshold/logs/rule/get", "alerting:observability.rules.custom_threshold/logs/rule/getRuleState", "alerting:observability.rules.custom_threshold/logs/rule/getAlertSummary", @@ -5026,6 +9593,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:observability.rules.custom_threshold/logs/rule/getRuleExecutionKPI", "alerting:observability.rules.custom_threshold/logs/rule/getBackfill", "alerting:observability.rules.custom_threshold/logs/rule/findBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/get", + "alerting:observability.rules.custom_threshold/alerts/rule/getRuleState", + "alerting:observability.rules.custom_threshold/alerts/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/alerts/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/alerts/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/alerts/rule/find", + "alerting:observability.rules.custom_threshold/alerts/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/alerts/rule/getBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/findBackfill", "alerting:xpack.ml.anomaly_detection_alert/logs/rule/get", "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getRuleState", "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getAlertSummary", @@ -5035,22 +9611,47 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getRuleExecutionKPI", "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getBackfill", "alerting:xpack.ml.anomaly_detection_alert/logs/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/findBackfill", "alerting:logs.alert.document.count/logs/alert/get", "alerting:logs.alert.document.count/logs/alert/find", "alerting:logs.alert.document.count/logs/alert/getAuthorizedAlertsIndices", "alerting:logs.alert.document.count/logs/alert/getAlertSummary", + "alerting:logs.alert.document.count/alerts/alert/get", + "alerting:logs.alert.document.count/alerts/alert/find", + "alerting:logs.alert.document.count/alerts/alert/getAuthorizedAlertsIndices", + "alerting:logs.alert.document.count/alerts/alert/getAlertSummary", "alerting:.es-query/logs/alert/get", "alerting:.es-query/logs/alert/find", "alerting:.es-query/logs/alert/getAuthorizedAlertsIndices", "alerting:.es-query/logs/alert/getAlertSummary", + "alerting:.es-query/alerts/alert/get", + "alerting:.es-query/alerts/alert/find", + "alerting:.es-query/alerts/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/alerts/alert/getAlertSummary", "alerting:observability.rules.custom_threshold/logs/alert/get", "alerting:observability.rules.custom_threshold/logs/alert/find", "alerting:observability.rules.custom_threshold/logs/alert/getAuthorizedAlertsIndices", "alerting:observability.rules.custom_threshold/logs/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/alerts/alert/get", + "alerting:observability.rules.custom_threshold/alerts/alert/find", + "alerting:observability.rules.custom_threshold/alerts/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/alerts/alert/getAlertSummary", "alerting:xpack.ml.anomaly_detection_alert/logs/alert/get", "alerting:xpack.ml.anomaly_detection_alert/logs/alert/find", "alerting:xpack.ml.anomaly_detection_alert/logs/alert/getAuthorizedAlertsIndices", "alerting:xpack.ml.anomaly_detection_alert/logs/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/getAlertSummary", ], }, "infrastructure": Object { @@ -5154,6 +9755,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:metrics.alert.threshold/infrastructure/rule/runSoon", "alerting:metrics.alert.threshold/infrastructure/rule/scheduleBackfill", "alerting:metrics.alert.threshold/infrastructure/rule/deleteBackfill", + "alerting:metrics.alert.threshold/alerts/rule/get", + "alerting:metrics.alert.threshold/alerts/rule/getRuleState", + "alerting:metrics.alert.threshold/alerts/rule/getAlertSummary", + "alerting:metrics.alert.threshold/alerts/rule/getExecutionLog", + "alerting:metrics.alert.threshold/alerts/rule/getActionErrorLog", + "alerting:metrics.alert.threshold/alerts/rule/find", + "alerting:metrics.alert.threshold/alerts/rule/getRuleExecutionKPI", + "alerting:metrics.alert.threshold/alerts/rule/getBackfill", + "alerting:metrics.alert.threshold/alerts/rule/findBackfill", + "alerting:metrics.alert.threshold/alerts/rule/create", + "alerting:metrics.alert.threshold/alerts/rule/delete", + "alerting:metrics.alert.threshold/alerts/rule/update", + "alerting:metrics.alert.threshold/alerts/rule/updateApiKey", + "alerting:metrics.alert.threshold/alerts/rule/enable", + "alerting:metrics.alert.threshold/alerts/rule/disable", + "alerting:metrics.alert.threshold/alerts/rule/muteAll", + "alerting:metrics.alert.threshold/alerts/rule/unmuteAll", + "alerting:metrics.alert.threshold/alerts/rule/muteAlert", + "alerting:metrics.alert.threshold/alerts/rule/unmuteAlert", + "alerting:metrics.alert.threshold/alerts/rule/snooze", + "alerting:metrics.alert.threshold/alerts/rule/bulkEdit", + "alerting:metrics.alert.threshold/alerts/rule/bulkDelete", + "alerting:metrics.alert.threshold/alerts/rule/bulkEnable", + "alerting:metrics.alert.threshold/alerts/rule/bulkDisable", + "alerting:metrics.alert.threshold/alerts/rule/unsnooze", + "alerting:metrics.alert.threshold/alerts/rule/runSoon", + "alerting:metrics.alert.threshold/alerts/rule/scheduleBackfill", + "alerting:metrics.alert.threshold/alerts/rule/deleteBackfill", "alerting:metrics.alert.inventory.threshold/infrastructure/rule/get", "alerting:metrics.alert.inventory.threshold/infrastructure/rule/getRuleState", "alerting:metrics.alert.inventory.threshold/infrastructure/rule/getAlertSummary", @@ -5182,6 +9811,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:metrics.alert.inventory.threshold/infrastructure/rule/runSoon", "alerting:metrics.alert.inventory.threshold/infrastructure/rule/scheduleBackfill", "alerting:metrics.alert.inventory.threshold/infrastructure/rule/deleteBackfill", + "alerting:metrics.alert.inventory.threshold/alerts/rule/get", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getRuleState", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getExecutionLog", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getActionErrorLog", + "alerting:metrics.alert.inventory.threshold/alerts/rule/find", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getRuleExecutionKPI", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getBackfill", + "alerting:metrics.alert.inventory.threshold/alerts/rule/findBackfill", + "alerting:metrics.alert.inventory.threshold/alerts/rule/create", + "alerting:metrics.alert.inventory.threshold/alerts/rule/delete", + "alerting:metrics.alert.inventory.threshold/alerts/rule/update", + "alerting:metrics.alert.inventory.threshold/alerts/rule/updateApiKey", + "alerting:metrics.alert.inventory.threshold/alerts/rule/enable", + "alerting:metrics.alert.inventory.threshold/alerts/rule/disable", + "alerting:metrics.alert.inventory.threshold/alerts/rule/muteAll", + "alerting:metrics.alert.inventory.threshold/alerts/rule/unmuteAll", + "alerting:metrics.alert.inventory.threshold/alerts/rule/muteAlert", + "alerting:metrics.alert.inventory.threshold/alerts/rule/unmuteAlert", + "alerting:metrics.alert.inventory.threshold/alerts/rule/snooze", + "alerting:metrics.alert.inventory.threshold/alerts/rule/bulkEdit", + "alerting:metrics.alert.inventory.threshold/alerts/rule/bulkDelete", + "alerting:metrics.alert.inventory.threshold/alerts/rule/bulkEnable", + "alerting:metrics.alert.inventory.threshold/alerts/rule/bulkDisable", + "alerting:metrics.alert.inventory.threshold/alerts/rule/unsnooze", + "alerting:metrics.alert.inventory.threshold/alerts/rule/runSoon", + "alerting:metrics.alert.inventory.threshold/alerts/rule/scheduleBackfill", + "alerting:metrics.alert.inventory.threshold/alerts/rule/deleteBackfill", "alerting:.es-query/infrastructure/rule/get", "alerting:.es-query/infrastructure/rule/getRuleState", "alerting:.es-query/infrastructure/rule/getAlertSummary", @@ -5210,6 +9867,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:.es-query/infrastructure/rule/runSoon", "alerting:.es-query/infrastructure/rule/scheduleBackfill", "alerting:.es-query/infrastructure/rule/deleteBackfill", + "alerting:.es-query/alerts/rule/get", + "alerting:.es-query/alerts/rule/getRuleState", + "alerting:.es-query/alerts/rule/getAlertSummary", + "alerting:.es-query/alerts/rule/getExecutionLog", + "alerting:.es-query/alerts/rule/getActionErrorLog", + "alerting:.es-query/alerts/rule/find", + "alerting:.es-query/alerts/rule/getRuleExecutionKPI", + "alerting:.es-query/alerts/rule/getBackfill", + "alerting:.es-query/alerts/rule/findBackfill", + "alerting:.es-query/alerts/rule/create", + "alerting:.es-query/alerts/rule/delete", + "alerting:.es-query/alerts/rule/update", + "alerting:.es-query/alerts/rule/updateApiKey", + "alerting:.es-query/alerts/rule/enable", + "alerting:.es-query/alerts/rule/disable", + "alerting:.es-query/alerts/rule/muteAll", + "alerting:.es-query/alerts/rule/unmuteAll", + "alerting:.es-query/alerts/rule/muteAlert", + "alerting:.es-query/alerts/rule/unmuteAlert", + "alerting:.es-query/alerts/rule/snooze", + "alerting:.es-query/alerts/rule/bulkEdit", + "alerting:.es-query/alerts/rule/bulkDelete", + "alerting:.es-query/alerts/rule/bulkEnable", + "alerting:.es-query/alerts/rule/bulkDisable", + "alerting:.es-query/alerts/rule/unsnooze", + "alerting:.es-query/alerts/rule/runSoon", + "alerting:.es-query/alerts/rule/scheduleBackfill", + "alerting:.es-query/alerts/rule/deleteBackfill", "alerting:observability.rules.custom_threshold/infrastructure/rule/get", "alerting:observability.rules.custom_threshold/infrastructure/rule/getRuleState", "alerting:observability.rules.custom_threshold/infrastructure/rule/getAlertSummary", @@ -5238,6 +9923,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:observability.rules.custom_threshold/infrastructure/rule/runSoon", "alerting:observability.rules.custom_threshold/infrastructure/rule/scheduleBackfill", "alerting:observability.rules.custom_threshold/infrastructure/rule/deleteBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/get", + "alerting:observability.rules.custom_threshold/alerts/rule/getRuleState", + "alerting:observability.rules.custom_threshold/alerts/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/alerts/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/alerts/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/alerts/rule/find", + "alerting:observability.rules.custom_threshold/alerts/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/alerts/rule/getBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/findBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/create", + "alerting:observability.rules.custom_threshold/alerts/rule/delete", + "alerting:observability.rules.custom_threshold/alerts/rule/update", + "alerting:observability.rules.custom_threshold/alerts/rule/updateApiKey", + "alerting:observability.rules.custom_threshold/alerts/rule/enable", + "alerting:observability.rules.custom_threshold/alerts/rule/disable", + "alerting:observability.rules.custom_threshold/alerts/rule/muteAll", + "alerting:observability.rules.custom_threshold/alerts/rule/unmuteAll", + "alerting:observability.rules.custom_threshold/alerts/rule/muteAlert", + "alerting:observability.rules.custom_threshold/alerts/rule/unmuteAlert", + "alerting:observability.rules.custom_threshold/alerts/rule/snooze", + "alerting:observability.rules.custom_threshold/alerts/rule/bulkEdit", + "alerting:observability.rules.custom_threshold/alerts/rule/bulkDelete", + "alerting:observability.rules.custom_threshold/alerts/rule/bulkEnable", + "alerting:observability.rules.custom_threshold/alerts/rule/bulkDisable", + "alerting:observability.rules.custom_threshold/alerts/rule/unsnooze", + "alerting:observability.rules.custom_threshold/alerts/rule/runSoon", + "alerting:observability.rules.custom_threshold/alerts/rule/scheduleBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/deleteBackfill", "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/get", "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/getRuleState", "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/getAlertSummary", @@ -5266,31 +9979,84 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/runSoon", "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/scheduleBackfill", "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/deleteBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/create", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/delete", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/update", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/updateApiKey", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/enable", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/disable", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/muteAll", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/unmuteAll", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/muteAlert", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/unmuteAlert", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/snooze", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/bulkEdit", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/bulkDelete", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/bulkEnable", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/bulkDisable", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/unsnooze", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/runSoon", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/scheduleBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/deleteBackfill", "alerting:metrics.alert.threshold/infrastructure/alert/get", "alerting:metrics.alert.threshold/infrastructure/alert/find", "alerting:metrics.alert.threshold/infrastructure/alert/getAuthorizedAlertsIndices", "alerting:metrics.alert.threshold/infrastructure/alert/getAlertSummary", "alerting:metrics.alert.threshold/infrastructure/alert/update", + "alerting:metrics.alert.threshold/alerts/alert/get", + "alerting:metrics.alert.threshold/alerts/alert/find", + "alerting:metrics.alert.threshold/alerts/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.threshold/alerts/alert/getAlertSummary", + "alerting:metrics.alert.threshold/alerts/alert/update", "alerting:metrics.alert.inventory.threshold/infrastructure/alert/get", "alerting:metrics.alert.inventory.threshold/infrastructure/alert/find", "alerting:metrics.alert.inventory.threshold/infrastructure/alert/getAuthorizedAlertsIndices", "alerting:metrics.alert.inventory.threshold/infrastructure/alert/getAlertSummary", "alerting:metrics.alert.inventory.threshold/infrastructure/alert/update", + "alerting:metrics.alert.inventory.threshold/alerts/alert/get", + "alerting:metrics.alert.inventory.threshold/alerts/alert/find", + "alerting:metrics.alert.inventory.threshold/alerts/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.inventory.threshold/alerts/alert/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/alerts/alert/update", "alerting:.es-query/infrastructure/alert/get", "alerting:.es-query/infrastructure/alert/find", "alerting:.es-query/infrastructure/alert/getAuthorizedAlertsIndices", "alerting:.es-query/infrastructure/alert/getAlertSummary", "alerting:.es-query/infrastructure/alert/update", + "alerting:.es-query/alerts/alert/get", + "alerting:.es-query/alerts/alert/find", + "alerting:.es-query/alerts/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/alerts/alert/getAlertSummary", + "alerting:.es-query/alerts/alert/update", "alerting:observability.rules.custom_threshold/infrastructure/alert/get", "alerting:observability.rules.custom_threshold/infrastructure/alert/find", "alerting:observability.rules.custom_threshold/infrastructure/alert/getAuthorizedAlertsIndices", "alerting:observability.rules.custom_threshold/infrastructure/alert/getAlertSummary", "alerting:observability.rules.custom_threshold/infrastructure/alert/update", + "alerting:observability.rules.custom_threshold/alerts/alert/get", + "alerting:observability.rules.custom_threshold/alerts/alert/find", + "alerting:observability.rules.custom_threshold/alerts/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/alerts/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/alerts/alert/update", "alerting:xpack.ml.anomaly_detection_alert/infrastructure/alert/get", "alerting:xpack.ml.anomaly_detection_alert/infrastructure/alert/find", "alerting:xpack.ml.anomaly_detection_alert/infrastructure/alert/getAuthorizedAlertsIndices", "alerting:xpack.ml.anomaly_detection_alert/infrastructure/alert/getAlertSummary", "alerting:xpack.ml.anomaly_detection_alert/infrastructure/alert/update", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/update", "app:logs", "app:observability-logs-explorer", "ui:catalogue/infralogging", @@ -5340,6 +10106,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:logs.alert.document.count/logs/rule/runSoon", "alerting:logs.alert.document.count/logs/rule/scheduleBackfill", "alerting:logs.alert.document.count/logs/rule/deleteBackfill", + "alerting:logs.alert.document.count/alerts/rule/get", + "alerting:logs.alert.document.count/alerts/rule/getRuleState", + "alerting:logs.alert.document.count/alerts/rule/getAlertSummary", + "alerting:logs.alert.document.count/alerts/rule/getExecutionLog", + "alerting:logs.alert.document.count/alerts/rule/getActionErrorLog", + "alerting:logs.alert.document.count/alerts/rule/find", + "alerting:logs.alert.document.count/alerts/rule/getRuleExecutionKPI", + "alerting:logs.alert.document.count/alerts/rule/getBackfill", + "alerting:logs.alert.document.count/alerts/rule/findBackfill", + "alerting:logs.alert.document.count/alerts/rule/create", + "alerting:logs.alert.document.count/alerts/rule/delete", + "alerting:logs.alert.document.count/alerts/rule/update", + "alerting:logs.alert.document.count/alerts/rule/updateApiKey", + "alerting:logs.alert.document.count/alerts/rule/enable", + "alerting:logs.alert.document.count/alerts/rule/disable", + "alerting:logs.alert.document.count/alerts/rule/muteAll", + "alerting:logs.alert.document.count/alerts/rule/unmuteAll", + "alerting:logs.alert.document.count/alerts/rule/muteAlert", + "alerting:logs.alert.document.count/alerts/rule/unmuteAlert", + "alerting:logs.alert.document.count/alerts/rule/snooze", + "alerting:logs.alert.document.count/alerts/rule/bulkEdit", + "alerting:logs.alert.document.count/alerts/rule/bulkDelete", + "alerting:logs.alert.document.count/alerts/rule/bulkEnable", + "alerting:logs.alert.document.count/alerts/rule/bulkDisable", + "alerting:logs.alert.document.count/alerts/rule/unsnooze", + "alerting:logs.alert.document.count/alerts/rule/runSoon", + "alerting:logs.alert.document.count/alerts/rule/scheduleBackfill", + "alerting:logs.alert.document.count/alerts/rule/deleteBackfill", "alerting:.es-query/logs/rule/get", "alerting:.es-query/logs/rule/getRuleState", "alerting:.es-query/logs/rule/getAlertSummary", @@ -5367,228 +10161,93 @@ export default function ({ getService }: FtrProviderContext) { "alerting:.es-query/logs/rule/unsnooze", "alerting:.es-query/logs/rule/runSoon", "alerting:.es-query/logs/rule/scheduleBackfill", - "alerting:.es-query/logs/rule/deleteBackfill", - "alerting:observability.rules.custom_threshold/logs/rule/get", - "alerting:observability.rules.custom_threshold/logs/rule/getRuleState", - "alerting:observability.rules.custom_threshold/logs/rule/getAlertSummary", - "alerting:observability.rules.custom_threshold/logs/rule/getExecutionLog", - "alerting:observability.rules.custom_threshold/logs/rule/getActionErrorLog", - "alerting:observability.rules.custom_threshold/logs/rule/find", - "alerting:observability.rules.custom_threshold/logs/rule/getRuleExecutionKPI", - "alerting:observability.rules.custom_threshold/logs/rule/getBackfill", - "alerting:observability.rules.custom_threshold/logs/rule/findBackfill", - "alerting:observability.rules.custom_threshold/logs/rule/create", - "alerting:observability.rules.custom_threshold/logs/rule/delete", - "alerting:observability.rules.custom_threshold/logs/rule/update", - "alerting:observability.rules.custom_threshold/logs/rule/updateApiKey", - "alerting:observability.rules.custom_threshold/logs/rule/enable", - "alerting:observability.rules.custom_threshold/logs/rule/disable", - "alerting:observability.rules.custom_threshold/logs/rule/muteAll", - "alerting:observability.rules.custom_threshold/logs/rule/unmuteAll", - "alerting:observability.rules.custom_threshold/logs/rule/muteAlert", - "alerting:observability.rules.custom_threshold/logs/rule/unmuteAlert", - "alerting:observability.rules.custom_threshold/logs/rule/snooze", - "alerting:observability.rules.custom_threshold/logs/rule/bulkEdit", - "alerting:observability.rules.custom_threshold/logs/rule/bulkDelete", - "alerting:observability.rules.custom_threshold/logs/rule/bulkEnable", - "alerting:observability.rules.custom_threshold/logs/rule/bulkDisable", - "alerting:observability.rules.custom_threshold/logs/rule/unsnooze", - "alerting:observability.rules.custom_threshold/logs/rule/runSoon", - "alerting:observability.rules.custom_threshold/logs/rule/scheduleBackfill", - "alerting:observability.rules.custom_threshold/logs/rule/deleteBackfill", - "alerting:xpack.ml.anomaly_detection_alert/logs/rule/get", - "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getRuleState", - "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getAlertSummary", - "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getExecutionLog", - "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getActionErrorLog", - "alerting:xpack.ml.anomaly_detection_alert/logs/rule/find", - "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getRuleExecutionKPI", - "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getBackfill", - "alerting:xpack.ml.anomaly_detection_alert/logs/rule/findBackfill", - "alerting:xpack.ml.anomaly_detection_alert/logs/rule/create", - "alerting:xpack.ml.anomaly_detection_alert/logs/rule/delete", - "alerting:xpack.ml.anomaly_detection_alert/logs/rule/update", - "alerting:xpack.ml.anomaly_detection_alert/logs/rule/updateApiKey", - "alerting:xpack.ml.anomaly_detection_alert/logs/rule/enable", - "alerting:xpack.ml.anomaly_detection_alert/logs/rule/disable", - "alerting:xpack.ml.anomaly_detection_alert/logs/rule/muteAll", - "alerting:xpack.ml.anomaly_detection_alert/logs/rule/unmuteAll", - "alerting:xpack.ml.anomaly_detection_alert/logs/rule/muteAlert", - "alerting:xpack.ml.anomaly_detection_alert/logs/rule/unmuteAlert", - "alerting:xpack.ml.anomaly_detection_alert/logs/rule/snooze", - "alerting:xpack.ml.anomaly_detection_alert/logs/rule/bulkEdit", - "alerting:xpack.ml.anomaly_detection_alert/logs/rule/bulkDelete", - "alerting:xpack.ml.anomaly_detection_alert/logs/rule/bulkEnable", - "alerting:xpack.ml.anomaly_detection_alert/logs/rule/bulkDisable", - "alerting:xpack.ml.anomaly_detection_alert/logs/rule/unsnooze", - "alerting:xpack.ml.anomaly_detection_alert/logs/rule/runSoon", - "alerting:xpack.ml.anomaly_detection_alert/logs/rule/scheduleBackfill", - "alerting:xpack.ml.anomaly_detection_alert/logs/rule/deleteBackfill", - "alerting:logs.alert.document.count/logs/alert/get", - "alerting:logs.alert.document.count/logs/alert/find", - "alerting:logs.alert.document.count/logs/alert/getAuthorizedAlertsIndices", - "alerting:logs.alert.document.count/logs/alert/getAlertSummary", - "alerting:logs.alert.document.count/logs/alert/update", - "alerting:.es-query/logs/alert/get", - "alerting:.es-query/logs/alert/find", - "alerting:.es-query/logs/alert/getAuthorizedAlertsIndices", - "alerting:.es-query/logs/alert/getAlertSummary", - "alerting:.es-query/logs/alert/update", - "alerting:observability.rules.custom_threshold/logs/alert/get", - "alerting:observability.rules.custom_threshold/logs/alert/find", - "alerting:observability.rules.custom_threshold/logs/alert/getAuthorizedAlertsIndices", - "alerting:observability.rules.custom_threshold/logs/alert/getAlertSummary", - "alerting:observability.rules.custom_threshold/logs/alert/update", - "alerting:xpack.ml.anomaly_detection_alert/logs/alert/get", - "alerting:xpack.ml.anomaly_detection_alert/logs/alert/find", - "alerting:xpack.ml.anomaly_detection_alert/logs/alert/getAuthorizedAlertsIndices", - "alerting:xpack.ml.anomaly_detection_alert/logs/alert/getAlertSummary", - "alerting:xpack.ml.anomaly_detection_alert/logs/alert/update", - "app:observability", - "ui:catalogue/observability", - "ui:navLinks/observability", - "ui:observability/read", - "ui:observability/write", - "alerting:slo.rules.burnRate/observability/rule/get", - "alerting:slo.rules.burnRate/observability/rule/getRuleState", - "alerting:slo.rules.burnRate/observability/rule/getAlertSummary", - "alerting:slo.rules.burnRate/observability/rule/getExecutionLog", - "alerting:slo.rules.burnRate/observability/rule/getActionErrorLog", - "alerting:slo.rules.burnRate/observability/rule/find", - "alerting:slo.rules.burnRate/observability/rule/getRuleExecutionKPI", - "alerting:slo.rules.burnRate/observability/rule/getBackfill", - "alerting:slo.rules.burnRate/observability/rule/findBackfill", - "alerting:slo.rules.burnRate/observability/rule/create", - "alerting:slo.rules.burnRate/observability/rule/delete", - "alerting:slo.rules.burnRate/observability/rule/update", - "alerting:slo.rules.burnRate/observability/rule/updateApiKey", - "alerting:slo.rules.burnRate/observability/rule/enable", - "alerting:slo.rules.burnRate/observability/rule/disable", - "alerting:slo.rules.burnRate/observability/rule/muteAll", - "alerting:slo.rules.burnRate/observability/rule/unmuteAll", - "alerting:slo.rules.burnRate/observability/rule/muteAlert", - "alerting:slo.rules.burnRate/observability/rule/unmuteAlert", - "alerting:slo.rules.burnRate/observability/rule/snooze", - "alerting:slo.rules.burnRate/observability/rule/bulkEdit", - "alerting:slo.rules.burnRate/observability/rule/bulkDelete", - "alerting:slo.rules.burnRate/observability/rule/bulkEnable", - "alerting:slo.rules.burnRate/observability/rule/bulkDisable", - "alerting:slo.rules.burnRate/observability/rule/unsnooze", - "alerting:slo.rules.burnRate/observability/rule/runSoon", - "alerting:slo.rules.burnRate/observability/rule/scheduleBackfill", - "alerting:slo.rules.burnRate/observability/rule/deleteBackfill", - "alerting:observability.rules.custom_threshold/observability/rule/get", - "alerting:observability.rules.custom_threshold/observability/rule/getRuleState", - "alerting:observability.rules.custom_threshold/observability/rule/getAlertSummary", - "alerting:observability.rules.custom_threshold/observability/rule/getExecutionLog", - "alerting:observability.rules.custom_threshold/observability/rule/getActionErrorLog", - "alerting:observability.rules.custom_threshold/observability/rule/find", - "alerting:observability.rules.custom_threshold/observability/rule/getRuleExecutionKPI", - "alerting:observability.rules.custom_threshold/observability/rule/getBackfill", - "alerting:observability.rules.custom_threshold/observability/rule/findBackfill", - "alerting:observability.rules.custom_threshold/observability/rule/create", - "alerting:observability.rules.custom_threshold/observability/rule/delete", - "alerting:observability.rules.custom_threshold/observability/rule/update", - "alerting:observability.rules.custom_threshold/observability/rule/updateApiKey", - "alerting:observability.rules.custom_threshold/observability/rule/enable", - "alerting:observability.rules.custom_threshold/observability/rule/disable", - "alerting:observability.rules.custom_threshold/observability/rule/muteAll", - "alerting:observability.rules.custom_threshold/observability/rule/unmuteAll", - "alerting:observability.rules.custom_threshold/observability/rule/muteAlert", - "alerting:observability.rules.custom_threshold/observability/rule/unmuteAlert", - "alerting:observability.rules.custom_threshold/observability/rule/snooze", - "alerting:observability.rules.custom_threshold/observability/rule/bulkEdit", - "alerting:observability.rules.custom_threshold/observability/rule/bulkDelete", - "alerting:observability.rules.custom_threshold/observability/rule/bulkEnable", - "alerting:observability.rules.custom_threshold/observability/rule/bulkDisable", - "alerting:observability.rules.custom_threshold/observability/rule/unsnooze", - "alerting:observability.rules.custom_threshold/observability/rule/runSoon", - "alerting:observability.rules.custom_threshold/observability/rule/scheduleBackfill", - "alerting:observability.rules.custom_threshold/observability/rule/deleteBackfill", - "alerting:.es-query/observability/rule/get", - "alerting:.es-query/observability/rule/getRuleState", - "alerting:.es-query/observability/rule/getAlertSummary", - "alerting:.es-query/observability/rule/getExecutionLog", - "alerting:.es-query/observability/rule/getActionErrorLog", - "alerting:.es-query/observability/rule/find", - "alerting:.es-query/observability/rule/getRuleExecutionKPI", - "alerting:.es-query/observability/rule/getBackfill", - "alerting:.es-query/observability/rule/findBackfill", - "alerting:.es-query/observability/rule/create", - "alerting:.es-query/observability/rule/delete", - "alerting:.es-query/observability/rule/update", - "alerting:.es-query/observability/rule/updateApiKey", - "alerting:.es-query/observability/rule/enable", - "alerting:.es-query/observability/rule/disable", - "alerting:.es-query/observability/rule/muteAll", - "alerting:.es-query/observability/rule/unmuteAll", - "alerting:.es-query/observability/rule/muteAlert", - "alerting:.es-query/observability/rule/unmuteAlert", - "alerting:.es-query/observability/rule/snooze", - "alerting:.es-query/observability/rule/bulkEdit", - "alerting:.es-query/observability/rule/bulkDelete", - "alerting:.es-query/observability/rule/bulkEnable", - "alerting:.es-query/observability/rule/bulkDisable", - "alerting:.es-query/observability/rule/unsnooze", - "alerting:.es-query/observability/rule/runSoon", - "alerting:.es-query/observability/rule/scheduleBackfill", - "alerting:.es-query/observability/rule/deleteBackfill", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/get", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleState", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getAlertSummary", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getExecutionLog", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getActionErrorLog", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/find", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleExecutionKPI", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getBackfill", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/findBackfill", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/create", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/delete", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/update", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/updateApiKey", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/enable", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/disable", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/muteAll", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unmuteAll", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/muteAlert", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unmuteAlert", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/snooze", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkEdit", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkDelete", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkEnable", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkDisable", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unsnooze", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/runSoon", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/scheduleBackfill", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/deleteBackfill", - "alerting:metrics.alert.inventory.threshold/observability/rule/get", - "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleState", - "alerting:metrics.alert.inventory.threshold/observability/rule/getAlertSummary", - "alerting:metrics.alert.inventory.threshold/observability/rule/getExecutionLog", - "alerting:metrics.alert.inventory.threshold/observability/rule/getActionErrorLog", - "alerting:metrics.alert.inventory.threshold/observability/rule/find", - "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleExecutionKPI", - "alerting:metrics.alert.inventory.threshold/observability/rule/getBackfill", - "alerting:metrics.alert.inventory.threshold/observability/rule/findBackfill", - "alerting:metrics.alert.inventory.threshold/observability/rule/create", - "alerting:metrics.alert.inventory.threshold/observability/rule/delete", - "alerting:metrics.alert.inventory.threshold/observability/rule/update", - "alerting:metrics.alert.inventory.threshold/observability/rule/updateApiKey", - "alerting:metrics.alert.inventory.threshold/observability/rule/enable", - "alerting:metrics.alert.inventory.threshold/observability/rule/disable", - "alerting:metrics.alert.inventory.threshold/observability/rule/muteAll", - "alerting:metrics.alert.inventory.threshold/observability/rule/unmuteAll", - "alerting:metrics.alert.inventory.threshold/observability/rule/muteAlert", - "alerting:metrics.alert.inventory.threshold/observability/rule/unmuteAlert", - "alerting:metrics.alert.inventory.threshold/observability/rule/snooze", - "alerting:metrics.alert.inventory.threshold/observability/rule/bulkEdit", - "alerting:metrics.alert.inventory.threshold/observability/rule/bulkDelete", - "alerting:metrics.alert.inventory.threshold/observability/rule/bulkEnable", - "alerting:metrics.alert.inventory.threshold/observability/rule/bulkDisable", - "alerting:metrics.alert.inventory.threshold/observability/rule/unsnooze", - "alerting:metrics.alert.inventory.threshold/observability/rule/runSoon", - "alerting:metrics.alert.inventory.threshold/observability/rule/scheduleBackfill", - "alerting:metrics.alert.inventory.threshold/observability/rule/deleteBackfill", + "alerting:.es-query/logs/rule/deleteBackfill", + "alerting:observability.rules.custom_threshold/logs/rule/get", + "alerting:observability.rules.custom_threshold/logs/rule/getRuleState", + "alerting:observability.rules.custom_threshold/logs/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/logs/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/logs/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/logs/rule/find", + "alerting:observability.rules.custom_threshold/logs/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/logs/rule/getBackfill", + "alerting:observability.rules.custom_threshold/logs/rule/findBackfill", + "alerting:observability.rules.custom_threshold/logs/rule/create", + "alerting:observability.rules.custom_threshold/logs/rule/delete", + "alerting:observability.rules.custom_threshold/logs/rule/update", + "alerting:observability.rules.custom_threshold/logs/rule/updateApiKey", + "alerting:observability.rules.custom_threshold/logs/rule/enable", + "alerting:observability.rules.custom_threshold/logs/rule/disable", + "alerting:observability.rules.custom_threshold/logs/rule/muteAll", + "alerting:observability.rules.custom_threshold/logs/rule/unmuteAll", + "alerting:observability.rules.custom_threshold/logs/rule/muteAlert", + "alerting:observability.rules.custom_threshold/logs/rule/unmuteAlert", + "alerting:observability.rules.custom_threshold/logs/rule/snooze", + "alerting:observability.rules.custom_threshold/logs/rule/bulkEdit", + "alerting:observability.rules.custom_threshold/logs/rule/bulkDelete", + "alerting:observability.rules.custom_threshold/logs/rule/bulkEnable", + "alerting:observability.rules.custom_threshold/logs/rule/bulkDisable", + "alerting:observability.rules.custom_threshold/logs/rule/unsnooze", + "alerting:observability.rules.custom_threshold/logs/rule/runSoon", + "alerting:observability.rules.custom_threshold/logs/rule/scheduleBackfill", + "alerting:observability.rules.custom_threshold/logs/rule/deleteBackfill", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/create", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/delete", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/update", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/updateApiKey", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/enable", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/disable", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/muteAll", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/unmuteAll", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/muteAlert", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/unmuteAlert", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/snooze", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/bulkEdit", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/bulkDelete", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/bulkEnable", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/bulkDisable", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/unsnooze", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/runSoon", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/scheduleBackfill", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/deleteBackfill", + "alerting:logs.alert.document.count/logs/alert/get", + "alerting:logs.alert.document.count/logs/alert/find", + "alerting:logs.alert.document.count/logs/alert/getAuthorizedAlertsIndices", + "alerting:logs.alert.document.count/logs/alert/getAlertSummary", + "alerting:logs.alert.document.count/logs/alert/update", + "alerting:logs.alert.document.count/alerts/alert/get", + "alerting:logs.alert.document.count/alerts/alert/find", + "alerting:logs.alert.document.count/alerts/alert/getAuthorizedAlertsIndices", + "alerting:logs.alert.document.count/alerts/alert/getAlertSummary", + "alerting:logs.alert.document.count/alerts/alert/update", + "alerting:.es-query/logs/alert/get", + "alerting:.es-query/logs/alert/find", + "alerting:.es-query/logs/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/logs/alert/getAlertSummary", + "alerting:.es-query/logs/alert/update", + "alerting:observability.rules.custom_threshold/logs/alert/get", + "alerting:observability.rules.custom_threshold/logs/alert/find", + "alerting:observability.rules.custom_threshold/logs/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/logs/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/logs/alert/update", + "alerting:xpack.ml.anomaly_detection_alert/logs/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/logs/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/logs/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/logs/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/logs/alert/update", + "app:observability", + "ui:catalogue/observability", + "ui:navLinks/observability", + "ui:observability/read", + "ui:observability/write", "alerting:apm.error_rate/observability/rule/get", "alerting:apm.error_rate/observability/rule/getRuleState", "alerting:apm.error_rate/observability/rule/getAlertSummary", @@ -5617,6 +10276,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.error_rate/observability/rule/runSoon", "alerting:apm.error_rate/observability/rule/scheduleBackfill", "alerting:apm.error_rate/observability/rule/deleteBackfill", + "alerting:apm.error_rate/alerts/rule/get", + "alerting:apm.error_rate/alerts/rule/getRuleState", + "alerting:apm.error_rate/alerts/rule/getAlertSummary", + "alerting:apm.error_rate/alerts/rule/getExecutionLog", + "alerting:apm.error_rate/alerts/rule/getActionErrorLog", + "alerting:apm.error_rate/alerts/rule/find", + "alerting:apm.error_rate/alerts/rule/getRuleExecutionKPI", + "alerting:apm.error_rate/alerts/rule/getBackfill", + "alerting:apm.error_rate/alerts/rule/findBackfill", + "alerting:apm.error_rate/alerts/rule/create", + "alerting:apm.error_rate/alerts/rule/delete", + "alerting:apm.error_rate/alerts/rule/update", + "alerting:apm.error_rate/alerts/rule/updateApiKey", + "alerting:apm.error_rate/alerts/rule/enable", + "alerting:apm.error_rate/alerts/rule/disable", + "alerting:apm.error_rate/alerts/rule/muteAll", + "alerting:apm.error_rate/alerts/rule/unmuteAll", + "alerting:apm.error_rate/alerts/rule/muteAlert", + "alerting:apm.error_rate/alerts/rule/unmuteAlert", + "alerting:apm.error_rate/alerts/rule/snooze", + "alerting:apm.error_rate/alerts/rule/bulkEdit", + "alerting:apm.error_rate/alerts/rule/bulkDelete", + "alerting:apm.error_rate/alerts/rule/bulkEnable", + "alerting:apm.error_rate/alerts/rule/bulkDisable", + "alerting:apm.error_rate/alerts/rule/unsnooze", + "alerting:apm.error_rate/alerts/rule/runSoon", + "alerting:apm.error_rate/alerts/rule/scheduleBackfill", + "alerting:apm.error_rate/alerts/rule/deleteBackfill", "alerting:apm.transaction_error_rate/observability/rule/get", "alerting:apm.transaction_error_rate/observability/rule/getRuleState", "alerting:apm.transaction_error_rate/observability/rule/getAlertSummary", @@ -5645,6 +10332,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.transaction_error_rate/observability/rule/runSoon", "alerting:apm.transaction_error_rate/observability/rule/scheduleBackfill", "alerting:apm.transaction_error_rate/observability/rule/deleteBackfill", + "alerting:apm.transaction_error_rate/alerts/rule/get", + "alerting:apm.transaction_error_rate/alerts/rule/getRuleState", + "alerting:apm.transaction_error_rate/alerts/rule/getAlertSummary", + "alerting:apm.transaction_error_rate/alerts/rule/getExecutionLog", + "alerting:apm.transaction_error_rate/alerts/rule/getActionErrorLog", + "alerting:apm.transaction_error_rate/alerts/rule/find", + "alerting:apm.transaction_error_rate/alerts/rule/getRuleExecutionKPI", + "alerting:apm.transaction_error_rate/alerts/rule/getBackfill", + "alerting:apm.transaction_error_rate/alerts/rule/findBackfill", + "alerting:apm.transaction_error_rate/alerts/rule/create", + "alerting:apm.transaction_error_rate/alerts/rule/delete", + "alerting:apm.transaction_error_rate/alerts/rule/update", + "alerting:apm.transaction_error_rate/alerts/rule/updateApiKey", + "alerting:apm.transaction_error_rate/alerts/rule/enable", + "alerting:apm.transaction_error_rate/alerts/rule/disable", + "alerting:apm.transaction_error_rate/alerts/rule/muteAll", + "alerting:apm.transaction_error_rate/alerts/rule/unmuteAll", + "alerting:apm.transaction_error_rate/alerts/rule/muteAlert", + "alerting:apm.transaction_error_rate/alerts/rule/unmuteAlert", + "alerting:apm.transaction_error_rate/alerts/rule/snooze", + "alerting:apm.transaction_error_rate/alerts/rule/bulkEdit", + "alerting:apm.transaction_error_rate/alerts/rule/bulkDelete", + "alerting:apm.transaction_error_rate/alerts/rule/bulkEnable", + "alerting:apm.transaction_error_rate/alerts/rule/bulkDisable", + "alerting:apm.transaction_error_rate/alerts/rule/unsnooze", + "alerting:apm.transaction_error_rate/alerts/rule/runSoon", + "alerting:apm.transaction_error_rate/alerts/rule/scheduleBackfill", + "alerting:apm.transaction_error_rate/alerts/rule/deleteBackfill", "alerting:apm.transaction_duration/observability/rule/get", "alerting:apm.transaction_duration/observability/rule/getRuleState", "alerting:apm.transaction_duration/observability/rule/getAlertSummary", @@ -5673,6 +10388,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.transaction_duration/observability/rule/runSoon", "alerting:apm.transaction_duration/observability/rule/scheduleBackfill", "alerting:apm.transaction_duration/observability/rule/deleteBackfill", + "alerting:apm.transaction_duration/alerts/rule/get", + "alerting:apm.transaction_duration/alerts/rule/getRuleState", + "alerting:apm.transaction_duration/alerts/rule/getAlertSummary", + "alerting:apm.transaction_duration/alerts/rule/getExecutionLog", + "alerting:apm.transaction_duration/alerts/rule/getActionErrorLog", + "alerting:apm.transaction_duration/alerts/rule/find", + "alerting:apm.transaction_duration/alerts/rule/getRuleExecutionKPI", + "alerting:apm.transaction_duration/alerts/rule/getBackfill", + "alerting:apm.transaction_duration/alerts/rule/findBackfill", + "alerting:apm.transaction_duration/alerts/rule/create", + "alerting:apm.transaction_duration/alerts/rule/delete", + "alerting:apm.transaction_duration/alerts/rule/update", + "alerting:apm.transaction_duration/alerts/rule/updateApiKey", + "alerting:apm.transaction_duration/alerts/rule/enable", + "alerting:apm.transaction_duration/alerts/rule/disable", + "alerting:apm.transaction_duration/alerts/rule/muteAll", + "alerting:apm.transaction_duration/alerts/rule/unmuteAll", + "alerting:apm.transaction_duration/alerts/rule/muteAlert", + "alerting:apm.transaction_duration/alerts/rule/unmuteAlert", + "alerting:apm.transaction_duration/alerts/rule/snooze", + "alerting:apm.transaction_duration/alerts/rule/bulkEdit", + "alerting:apm.transaction_duration/alerts/rule/bulkDelete", + "alerting:apm.transaction_duration/alerts/rule/bulkEnable", + "alerting:apm.transaction_duration/alerts/rule/bulkDisable", + "alerting:apm.transaction_duration/alerts/rule/unsnooze", + "alerting:apm.transaction_duration/alerts/rule/runSoon", + "alerting:apm.transaction_duration/alerts/rule/scheduleBackfill", + "alerting:apm.transaction_duration/alerts/rule/deleteBackfill", "alerting:apm.anomaly/observability/rule/get", "alerting:apm.anomaly/observability/rule/getRuleState", "alerting:apm.anomaly/observability/rule/getAlertSummary", @@ -5701,6 +10444,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.anomaly/observability/rule/runSoon", "alerting:apm.anomaly/observability/rule/scheduleBackfill", "alerting:apm.anomaly/observability/rule/deleteBackfill", + "alerting:apm.anomaly/alerts/rule/get", + "alerting:apm.anomaly/alerts/rule/getRuleState", + "alerting:apm.anomaly/alerts/rule/getAlertSummary", + "alerting:apm.anomaly/alerts/rule/getExecutionLog", + "alerting:apm.anomaly/alerts/rule/getActionErrorLog", + "alerting:apm.anomaly/alerts/rule/find", + "alerting:apm.anomaly/alerts/rule/getRuleExecutionKPI", + "alerting:apm.anomaly/alerts/rule/getBackfill", + "alerting:apm.anomaly/alerts/rule/findBackfill", + "alerting:apm.anomaly/alerts/rule/create", + "alerting:apm.anomaly/alerts/rule/delete", + "alerting:apm.anomaly/alerts/rule/update", + "alerting:apm.anomaly/alerts/rule/updateApiKey", + "alerting:apm.anomaly/alerts/rule/enable", + "alerting:apm.anomaly/alerts/rule/disable", + "alerting:apm.anomaly/alerts/rule/muteAll", + "alerting:apm.anomaly/alerts/rule/unmuteAll", + "alerting:apm.anomaly/alerts/rule/muteAlert", + "alerting:apm.anomaly/alerts/rule/unmuteAlert", + "alerting:apm.anomaly/alerts/rule/snooze", + "alerting:apm.anomaly/alerts/rule/bulkEdit", + "alerting:apm.anomaly/alerts/rule/bulkDelete", + "alerting:apm.anomaly/alerts/rule/bulkEnable", + "alerting:apm.anomaly/alerts/rule/bulkDisable", + "alerting:apm.anomaly/alerts/rule/unsnooze", + "alerting:apm.anomaly/alerts/rule/runSoon", + "alerting:apm.anomaly/alerts/rule/scheduleBackfill", + "alerting:apm.anomaly/alerts/rule/deleteBackfill", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/get", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/getRuleState", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/getAlertSummary", @@ -5729,6 +10500,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/runSoon", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/scheduleBackfill", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/deleteBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/get", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getRuleState", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getAlertSummary", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getExecutionLog", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getActionErrorLog", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/find", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/findBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/create", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/delete", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/update", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/updateApiKey", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/enable", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/disable", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/muteAll", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/unmuteAll", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/muteAlert", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/unmuteAlert", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/snooze", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/bulkEdit", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/bulkDelete", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/bulkEnable", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/bulkDisable", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/unsnooze", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/runSoon", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/scheduleBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/deleteBackfill", "alerting:xpack.synthetics.alerts.tls/observability/rule/get", "alerting:xpack.synthetics.alerts.tls/observability/rule/getRuleState", "alerting:xpack.synthetics.alerts.tls/observability/rule/getAlertSummary", @@ -5757,61 +10556,622 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.synthetics.alerts.tls/observability/rule/runSoon", "alerting:xpack.synthetics.alerts.tls/observability/rule/scheduleBackfill", "alerting:xpack.synthetics.alerts.tls/observability/rule/deleteBackfill", - "alerting:slo.rules.burnRate/observability/alert/get", - "alerting:slo.rules.burnRate/observability/alert/find", - "alerting:slo.rules.burnRate/observability/alert/getAuthorizedAlertsIndices", - "alerting:slo.rules.burnRate/observability/alert/getAlertSummary", - "alerting:slo.rules.burnRate/observability/alert/update", - "alerting:observability.rules.custom_threshold/observability/alert/get", - "alerting:observability.rules.custom_threshold/observability/alert/find", - "alerting:observability.rules.custom_threshold/observability/alert/getAuthorizedAlertsIndices", - "alerting:observability.rules.custom_threshold/observability/alert/getAlertSummary", - "alerting:observability.rules.custom_threshold/observability/alert/update", - "alerting:.es-query/observability/alert/get", - "alerting:.es-query/observability/alert/find", - "alerting:.es-query/observability/alert/getAuthorizedAlertsIndices", - "alerting:.es-query/observability/alert/getAlertSummary", - "alerting:.es-query/observability/alert/update", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/get", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/find", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAuthorizedAlertsIndices", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAlertSummary", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/update", - "alerting:metrics.alert.inventory.threshold/observability/alert/get", - "alerting:metrics.alert.inventory.threshold/observability/alert/find", - "alerting:metrics.alert.inventory.threshold/observability/alert/getAuthorizedAlertsIndices", - "alerting:metrics.alert.inventory.threshold/observability/alert/getAlertSummary", - "alerting:metrics.alert.inventory.threshold/observability/alert/update", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/get", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getRuleState", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getAlertSummary", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getExecutionLog", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getActionErrorLog", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/find", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getBackfill", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/findBackfill", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/create", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/delete", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/update", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/updateApiKey", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/enable", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/disable", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/muteAll", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/unmuteAll", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/muteAlert", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/unmuteAlert", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/snooze", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/bulkEdit", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/bulkDelete", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/bulkEnable", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/bulkDisable", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/unsnooze", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/runSoon", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/scheduleBackfill", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/deleteBackfill", + "alerting:metrics.alert.threshold/observability/rule/get", + "alerting:metrics.alert.threshold/observability/rule/getRuleState", + "alerting:metrics.alert.threshold/observability/rule/getAlertSummary", + "alerting:metrics.alert.threshold/observability/rule/getExecutionLog", + "alerting:metrics.alert.threshold/observability/rule/getActionErrorLog", + "alerting:metrics.alert.threshold/observability/rule/find", + "alerting:metrics.alert.threshold/observability/rule/getRuleExecutionKPI", + "alerting:metrics.alert.threshold/observability/rule/getBackfill", + "alerting:metrics.alert.threshold/observability/rule/findBackfill", + "alerting:metrics.alert.threshold/observability/rule/create", + "alerting:metrics.alert.threshold/observability/rule/delete", + "alerting:metrics.alert.threshold/observability/rule/update", + "alerting:metrics.alert.threshold/observability/rule/updateApiKey", + "alerting:metrics.alert.threshold/observability/rule/enable", + "alerting:metrics.alert.threshold/observability/rule/disable", + "alerting:metrics.alert.threshold/observability/rule/muteAll", + "alerting:metrics.alert.threshold/observability/rule/unmuteAll", + "alerting:metrics.alert.threshold/observability/rule/muteAlert", + "alerting:metrics.alert.threshold/observability/rule/unmuteAlert", + "alerting:metrics.alert.threshold/observability/rule/snooze", + "alerting:metrics.alert.threshold/observability/rule/bulkEdit", + "alerting:metrics.alert.threshold/observability/rule/bulkDelete", + "alerting:metrics.alert.threshold/observability/rule/bulkEnable", + "alerting:metrics.alert.threshold/observability/rule/bulkDisable", + "alerting:metrics.alert.threshold/observability/rule/unsnooze", + "alerting:metrics.alert.threshold/observability/rule/runSoon", + "alerting:metrics.alert.threshold/observability/rule/scheduleBackfill", + "alerting:metrics.alert.threshold/observability/rule/deleteBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/get", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleState", + "alerting:metrics.alert.inventory.threshold/observability/rule/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/rule/getExecutionLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/getActionErrorLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/find", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleExecutionKPI", + "alerting:metrics.alert.inventory.threshold/observability/rule/getBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/findBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/create", + "alerting:metrics.alert.inventory.threshold/observability/rule/delete", + "alerting:metrics.alert.inventory.threshold/observability/rule/update", + "alerting:metrics.alert.inventory.threshold/observability/rule/updateApiKey", + "alerting:metrics.alert.inventory.threshold/observability/rule/enable", + "alerting:metrics.alert.inventory.threshold/observability/rule/disable", + "alerting:metrics.alert.inventory.threshold/observability/rule/muteAll", + "alerting:metrics.alert.inventory.threshold/observability/rule/unmuteAll", + "alerting:metrics.alert.inventory.threshold/observability/rule/muteAlert", + "alerting:metrics.alert.inventory.threshold/observability/rule/unmuteAlert", + "alerting:metrics.alert.inventory.threshold/observability/rule/snooze", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkEdit", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkDelete", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkEnable", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkDisable", + "alerting:metrics.alert.inventory.threshold/observability/rule/unsnooze", + "alerting:metrics.alert.inventory.threshold/observability/rule/runSoon", + "alerting:metrics.alert.inventory.threshold/observability/rule/scheduleBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.tls/observability/rule/get", + "alerting:xpack.uptime.alerts.tls/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.tls/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tls/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tls/observability/rule/find", + "alerting:xpack.uptime.alerts.tls/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tls/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.tls/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.tls/observability/rule/create", + "alerting:xpack.uptime.alerts.tls/observability/rule/delete", + "alerting:xpack.uptime.alerts.tls/observability/rule/update", + "alerting:xpack.uptime.alerts.tls/observability/rule/updateApiKey", + "alerting:xpack.uptime.alerts.tls/observability/rule/enable", + "alerting:xpack.uptime.alerts.tls/observability/rule/disable", + "alerting:xpack.uptime.alerts.tls/observability/rule/muteAll", + "alerting:xpack.uptime.alerts.tls/observability/rule/unmuteAll", + "alerting:xpack.uptime.alerts.tls/observability/rule/muteAlert", + "alerting:xpack.uptime.alerts.tls/observability/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.tls/observability/rule/snooze", + "alerting:xpack.uptime.alerts.tls/observability/rule/bulkEdit", + "alerting:xpack.uptime.alerts.tls/observability/rule/bulkDelete", + "alerting:xpack.uptime.alerts.tls/observability/rule/bulkEnable", + "alerting:xpack.uptime.alerts.tls/observability/rule/bulkDisable", + "alerting:xpack.uptime.alerts.tls/observability/rule/unsnooze", + "alerting:xpack.uptime.alerts.tls/observability/rule/runSoon", + "alerting:xpack.uptime.alerts.tls/observability/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.tls/observability/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.tls/alerts/rule/get", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tls/alerts/rule/find", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.tls/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.tls/alerts/rule/create", + "alerting:xpack.uptime.alerts.tls/alerts/rule/delete", + "alerting:xpack.uptime.alerts.tls/alerts/rule/update", + "alerting:xpack.uptime.alerts.tls/alerts/rule/updateApiKey", + "alerting:xpack.uptime.alerts.tls/alerts/rule/enable", + "alerting:xpack.uptime.alerts.tls/alerts/rule/disable", + "alerting:xpack.uptime.alerts.tls/alerts/rule/muteAll", + "alerting:xpack.uptime.alerts.tls/alerts/rule/unmuteAll", + "alerting:xpack.uptime.alerts.tls/alerts/rule/muteAlert", + "alerting:xpack.uptime.alerts.tls/alerts/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.tls/alerts/rule/snooze", + "alerting:xpack.uptime.alerts.tls/alerts/rule/bulkEdit", + "alerting:xpack.uptime.alerts.tls/alerts/rule/bulkDelete", + "alerting:xpack.uptime.alerts.tls/alerts/rule/bulkEnable", + "alerting:xpack.uptime.alerts.tls/alerts/rule/bulkDisable", + "alerting:xpack.uptime.alerts.tls/alerts/rule/unsnooze", + "alerting:xpack.uptime.alerts.tls/alerts/rule/runSoon", + "alerting:xpack.uptime.alerts.tls/alerts/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.tls/alerts/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/get", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/find", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/create", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/delete", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/update", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/updateApiKey", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/enable", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/disable", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/muteAll", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/unmuteAll", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/muteAlert", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/snooze", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/bulkEdit", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/bulkDelete", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/bulkEnable", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/bulkDisable", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/unsnooze", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/runSoon", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/get", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/find", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/create", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/delete", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/update", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/updateApiKey", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/enable", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/disable", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/muteAll", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/unmuteAll", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/muteAlert", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/snooze", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/bulkEdit", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/bulkDelete", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/bulkEnable", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/bulkDisable", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/unsnooze", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/runSoon", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/get", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/find", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/create", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/delete", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/update", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/updateApiKey", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/enable", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/disable", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/muteAll", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/unmuteAll", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/muteAlert", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/snooze", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/bulkEdit", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/bulkDelete", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/bulkEnable", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/bulkDisable", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/unsnooze", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/runSoon", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/get", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/find", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/create", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/delete", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/update", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/updateApiKey", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/enable", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/disable", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/muteAll", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/unmuteAll", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/muteAlert", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/snooze", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/bulkEdit", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/bulkDelete", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/bulkEnable", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/bulkDisable", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/unsnooze", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/runSoon", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/get", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/find", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/create", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/delete", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/update", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/updateApiKey", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/enable", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/disable", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/muteAll", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/unmuteAll", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/muteAlert", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/snooze", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/bulkEdit", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/bulkDelete", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/bulkEnable", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/bulkDisable", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/unsnooze", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/runSoon", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/get", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/find", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/create", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/delete", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/update", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/updateApiKey", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/enable", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/disable", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/muteAll", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/unmuteAll", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/muteAlert", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/snooze", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/bulkEdit", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/bulkDelete", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/bulkEnable", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/bulkDisable", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/unsnooze", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/runSoon", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/deleteBackfill", + "alerting:logs.alert.document.count/observability/rule/get", + "alerting:logs.alert.document.count/observability/rule/getRuleState", + "alerting:logs.alert.document.count/observability/rule/getAlertSummary", + "alerting:logs.alert.document.count/observability/rule/getExecutionLog", + "alerting:logs.alert.document.count/observability/rule/getActionErrorLog", + "alerting:logs.alert.document.count/observability/rule/find", + "alerting:logs.alert.document.count/observability/rule/getRuleExecutionKPI", + "alerting:logs.alert.document.count/observability/rule/getBackfill", + "alerting:logs.alert.document.count/observability/rule/findBackfill", + "alerting:logs.alert.document.count/observability/rule/create", + "alerting:logs.alert.document.count/observability/rule/delete", + "alerting:logs.alert.document.count/observability/rule/update", + "alerting:logs.alert.document.count/observability/rule/updateApiKey", + "alerting:logs.alert.document.count/observability/rule/enable", + "alerting:logs.alert.document.count/observability/rule/disable", + "alerting:logs.alert.document.count/observability/rule/muteAll", + "alerting:logs.alert.document.count/observability/rule/unmuteAll", + "alerting:logs.alert.document.count/observability/rule/muteAlert", + "alerting:logs.alert.document.count/observability/rule/unmuteAlert", + "alerting:logs.alert.document.count/observability/rule/snooze", + "alerting:logs.alert.document.count/observability/rule/bulkEdit", + "alerting:logs.alert.document.count/observability/rule/bulkDelete", + "alerting:logs.alert.document.count/observability/rule/bulkEnable", + "alerting:logs.alert.document.count/observability/rule/bulkDisable", + "alerting:logs.alert.document.count/observability/rule/unsnooze", + "alerting:logs.alert.document.count/observability/rule/runSoon", + "alerting:logs.alert.document.count/observability/rule/scheduleBackfill", + "alerting:logs.alert.document.count/observability/rule/deleteBackfill", + "alerting:slo.rules.burnRate/observability/rule/get", + "alerting:slo.rules.burnRate/observability/rule/getRuleState", + "alerting:slo.rules.burnRate/observability/rule/getAlertSummary", + "alerting:slo.rules.burnRate/observability/rule/getExecutionLog", + "alerting:slo.rules.burnRate/observability/rule/getActionErrorLog", + "alerting:slo.rules.burnRate/observability/rule/find", + "alerting:slo.rules.burnRate/observability/rule/getRuleExecutionKPI", + "alerting:slo.rules.burnRate/observability/rule/getBackfill", + "alerting:slo.rules.burnRate/observability/rule/findBackfill", + "alerting:slo.rules.burnRate/observability/rule/create", + "alerting:slo.rules.burnRate/observability/rule/delete", + "alerting:slo.rules.burnRate/observability/rule/update", + "alerting:slo.rules.burnRate/observability/rule/updateApiKey", + "alerting:slo.rules.burnRate/observability/rule/enable", + "alerting:slo.rules.burnRate/observability/rule/disable", + "alerting:slo.rules.burnRate/observability/rule/muteAll", + "alerting:slo.rules.burnRate/observability/rule/unmuteAll", + "alerting:slo.rules.burnRate/observability/rule/muteAlert", + "alerting:slo.rules.burnRate/observability/rule/unmuteAlert", + "alerting:slo.rules.burnRate/observability/rule/snooze", + "alerting:slo.rules.burnRate/observability/rule/bulkEdit", + "alerting:slo.rules.burnRate/observability/rule/bulkDelete", + "alerting:slo.rules.burnRate/observability/rule/bulkEnable", + "alerting:slo.rules.burnRate/observability/rule/bulkDisable", + "alerting:slo.rules.burnRate/observability/rule/unsnooze", + "alerting:slo.rules.burnRate/observability/rule/runSoon", + "alerting:slo.rules.burnRate/observability/rule/scheduleBackfill", + "alerting:slo.rules.burnRate/observability/rule/deleteBackfill", + "alerting:slo.rules.burnRate/alerts/rule/get", + "alerting:slo.rules.burnRate/alerts/rule/getRuleState", + "alerting:slo.rules.burnRate/alerts/rule/getAlertSummary", + "alerting:slo.rules.burnRate/alerts/rule/getExecutionLog", + "alerting:slo.rules.burnRate/alerts/rule/getActionErrorLog", + "alerting:slo.rules.burnRate/alerts/rule/find", + "alerting:slo.rules.burnRate/alerts/rule/getRuleExecutionKPI", + "alerting:slo.rules.burnRate/alerts/rule/getBackfill", + "alerting:slo.rules.burnRate/alerts/rule/findBackfill", + "alerting:slo.rules.burnRate/alerts/rule/create", + "alerting:slo.rules.burnRate/alerts/rule/delete", + "alerting:slo.rules.burnRate/alerts/rule/update", + "alerting:slo.rules.burnRate/alerts/rule/updateApiKey", + "alerting:slo.rules.burnRate/alerts/rule/enable", + "alerting:slo.rules.burnRate/alerts/rule/disable", + "alerting:slo.rules.burnRate/alerts/rule/muteAll", + "alerting:slo.rules.burnRate/alerts/rule/unmuteAll", + "alerting:slo.rules.burnRate/alerts/rule/muteAlert", + "alerting:slo.rules.burnRate/alerts/rule/unmuteAlert", + "alerting:slo.rules.burnRate/alerts/rule/snooze", + "alerting:slo.rules.burnRate/alerts/rule/bulkEdit", + "alerting:slo.rules.burnRate/alerts/rule/bulkDelete", + "alerting:slo.rules.burnRate/alerts/rule/bulkEnable", + "alerting:slo.rules.burnRate/alerts/rule/bulkDisable", + "alerting:slo.rules.burnRate/alerts/rule/unsnooze", + "alerting:slo.rules.burnRate/alerts/rule/runSoon", + "alerting:slo.rules.burnRate/alerts/rule/scheduleBackfill", + "alerting:slo.rules.burnRate/alerts/rule/deleteBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/get", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleState", + "alerting:observability.rules.custom_threshold/observability/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/observability/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/observability/rule/find", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/observability/rule/getBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/findBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/create", + "alerting:observability.rules.custom_threshold/observability/rule/delete", + "alerting:observability.rules.custom_threshold/observability/rule/update", + "alerting:observability.rules.custom_threshold/observability/rule/updateApiKey", + "alerting:observability.rules.custom_threshold/observability/rule/enable", + "alerting:observability.rules.custom_threshold/observability/rule/disable", + "alerting:observability.rules.custom_threshold/observability/rule/muteAll", + "alerting:observability.rules.custom_threshold/observability/rule/unmuteAll", + "alerting:observability.rules.custom_threshold/observability/rule/muteAlert", + "alerting:observability.rules.custom_threshold/observability/rule/unmuteAlert", + "alerting:observability.rules.custom_threshold/observability/rule/snooze", + "alerting:observability.rules.custom_threshold/observability/rule/bulkEdit", + "alerting:observability.rules.custom_threshold/observability/rule/bulkDelete", + "alerting:observability.rules.custom_threshold/observability/rule/bulkEnable", + "alerting:observability.rules.custom_threshold/observability/rule/bulkDisable", + "alerting:observability.rules.custom_threshold/observability/rule/unsnooze", + "alerting:observability.rules.custom_threshold/observability/rule/runSoon", + "alerting:observability.rules.custom_threshold/observability/rule/scheduleBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/deleteBackfill", + "alerting:.es-query/observability/rule/get", + "alerting:.es-query/observability/rule/getRuleState", + "alerting:.es-query/observability/rule/getAlertSummary", + "alerting:.es-query/observability/rule/getExecutionLog", + "alerting:.es-query/observability/rule/getActionErrorLog", + "alerting:.es-query/observability/rule/find", + "alerting:.es-query/observability/rule/getRuleExecutionKPI", + "alerting:.es-query/observability/rule/getBackfill", + "alerting:.es-query/observability/rule/findBackfill", + "alerting:.es-query/observability/rule/create", + "alerting:.es-query/observability/rule/delete", + "alerting:.es-query/observability/rule/update", + "alerting:.es-query/observability/rule/updateApiKey", + "alerting:.es-query/observability/rule/enable", + "alerting:.es-query/observability/rule/disable", + "alerting:.es-query/observability/rule/muteAll", + "alerting:.es-query/observability/rule/unmuteAll", + "alerting:.es-query/observability/rule/muteAlert", + "alerting:.es-query/observability/rule/unmuteAlert", + "alerting:.es-query/observability/rule/snooze", + "alerting:.es-query/observability/rule/bulkEdit", + "alerting:.es-query/observability/rule/bulkDelete", + "alerting:.es-query/observability/rule/bulkEnable", + "alerting:.es-query/observability/rule/bulkDisable", + "alerting:.es-query/observability/rule/unsnooze", + "alerting:.es-query/observability/rule/runSoon", + "alerting:.es-query/observability/rule/scheduleBackfill", + "alerting:.es-query/observability/rule/deleteBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/create", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/delete", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/update", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/updateApiKey", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/enable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/disable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/muteAll", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unmuteAll", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/muteAlert", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unmuteAlert", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/snooze", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkEdit", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkDelete", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkEnable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkDisable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unsnooze", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/runSoon", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/scheduleBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/deleteBackfill", "alerting:apm.error_rate/observability/alert/get", "alerting:apm.error_rate/observability/alert/find", "alerting:apm.error_rate/observability/alert/getAuthorizedAlertsIndices", "alerting:apm.error_rate/observability/alert/getAlertSummary", "alerting:apm.error_rate/observability/alert/update", + "alerting:apm.error_rate/alerts/alert/get", + "alerting:apm.error_rate/alerts/alert/find", + "alerting:apm.error_rate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.error_rate/alerts/alert/getAlertSummary", + "alerting:apm.error_rate/alerts/alert/update", "alerting:apm.transaction_error_rate/observability/alert/get", "alerting:apm.transaction_error_rate/observability/alert/find", "alerting:apm.transaction_error_rate/observability/alert/getAuthorizedAlertsIndices", "alerting:apm.transaction_error_rate/observability/alert/getAlertSummary", "alerting:apm.transaction_error_rate/observability/alert/update", + "alerting:apm.transaction_error_rate/alerts/alert/get", + "alerting:apm.transaction_error_rate/alerts/alert/find", + "alerting:apm.transaction_error_rate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_error_rate/alerts/alert/getAlertSummary", + "alerting:apm.transaction_error_rate/alerts/alert/update", "alerting:apm.transaction_duration/observability/alert/get", "alerting:apm.transaction_duration/observability/alert/find", "alerting:apm.transaction_duration/observability/alert/getAuthorizedAlertsIndices", "alerting:apm.transaction_duration/observability/alert/getAlertSummary", "alerting:apm.transaction_duration/observability/alert/update", + "alerting:apm.transaction_duration/alerts/alert/get", + "alerting:apm.transaction_duration/alerts/alert/find", + "alerting:apm.transaction_duration/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_duration/alerts/alert/getAlertSummary", + "alerting:apm.transaction_duration/alerts/alert/update", "alerting:apm.anomaly/observability/alert/get", "alerting:apm.anomaly/observability/alert/find", "alerting:apm.anomaly/observability/alert/getAuthorizedAlertsIndices", "alerting:apm.anomaly/observability/alert/getAlertSummary", "alerting:apm.anomaly/observability/alert/update", + "alerting:apm.anomaly/alerts/alert/get", + "alerting:apm.anomaly/alerts/alert/find", + "alerting:apm.anomaly/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.anomaly/alerts/alert/getAlertSummary", + "alerting:apm.anomaly/alerts/alert/update", "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/get", "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/find", "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/getAuthorizedAlertsIndices", "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/getAlertSummary", "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/update", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/get", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/find", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/getAlertSummary", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/update", "alerting:xpack.synthetics.alerts.tls/observability/alert/get", "alerting:xpack.synthetics.alerts.tls/observability/alert/find", "alerting:xpack.synthetics.alerts.tls/observability/alert/getAuthorizedAlertsIndices", "alerting:xpack.synthetics.alerts.tls/observability/alert/getAlertSummary", "alerting:xpack.synthetics.alerts.tls/observability/alert/update", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/get", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/find", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/getAlertSummary", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/update", + "alerting:metrics.alert.threshold/observability/alert/get", + "alerting:metrics.alert.threshold/observability/alert/find", + "alerting:metrics.alert.threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.threshold/observability/alert/getAlertSummary", + "alerting:metrics.alert.threshold/observability/alert/update", + "alerting:metrics.alert.inventory.threshold/observability/alert/get", + "alerting:metrics.alert.inventory.threshold/observability/alert/find", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/alert/update", + "alerting:xpack.uptime.alerts.tls/observability/alert/get", + "alerting:xpack.uptime.alerts.tls/observability/alert/find", + "alerting:xpack.uptime.alerts.tls/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tls/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/observability/alert/update", + "alerting:xpack.uptime.alerts.tls/alerts/alert/get", + "alerting:xpack.uptime.alerts.tls/alerts/alert/find", + "alerting:xpack.uptime.alerts.tls/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tls/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/alerts/alert/update", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/get", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/find", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/update", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/get", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/find", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/update", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/get", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/find", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/update", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/get", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/find", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/update", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/get", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/find", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/update", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/get", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/find", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/update", + "alerting:logs.alert.document.count/observability/alert/get", + "alerting:logs.alert.document.count/observability/alert/find", + "alerting:logs.alert.document.count/observability/alert/getAuthorizedAlertsIndices", + "alerting:logs.alert.document.count/observability/alert/getAlertSummary", + "alerting:logs.alert.document.count/observability/alert/update", + "alerting:slo.rules.burnRate/observability/alert/get", + "alerting:slo.rules.burnRate/observability/alert/find", + "alerting:slo.rules.burnRate/observability/alert/getAuthorizedAlertsIndices", + "alerting:slo.rules.burnRate/observability/alert/getAlertSummary", + "alerting:slo.rules.burnRate/observability/alert/update", + "alerting:slo.rules.burnRate/alerts/alert/get", + "alerting:slo.rules.burnRate/alerts/alert/find", + "alerting:slo.rules.burnRate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:slo.rules.burnRate/alerts/alert/getAlertSummary", + "alerting:slo.rules.burnRate/alerts/alert/update", + "alerting:observability.rules.custom_threshold/observability/alert/get", + "alerting:observability.rules.custom_threshold/observability/alert/find", + "alerting:observability.rules.custom_threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/observability/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/alert/update", + "alerting:.es-query/observability/alert/get", + "alerting:.es-query/observability/alert/find", + "alerting:.es-query/observability/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/observability/alert/getAlertSummary", + "alerting:.es-query/observability/alert/update", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/update", ], "minimal_all": Array [ "login:", @@ -5913,6 +11273,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:metrics.alert.threshold/infrastructure/rule/runSoon", "alerting:metrics.alert.threshold/infrastructure/rule/scheduleBackfill", "alerting:metrics.alert.threshold/infrastructure/rule/deleteBackfill", + "alerting:metrics.alert.threshold/alerts/rule/get", + "alerting:metrics.alert.threshold/alerts/rule/getRuleState", + "alerting:metrics.alert.threshold/alerts/rule/getAlertSummary", + "alerting:metrics.alert.threshold/alerts/rule/getExecutionLog", + "alerting:metrics.alert.threshold/alerts/rule/getActionErrorLog", + "alerting:metrics.alert.threshold/alerts/rule/find", + "alerting:metrics.alert.threshold/alerts/rule/getRuleExecutionKPI", + "alerting:metrics.alert.threshold/alerts/rule/getBackfill", + "alerting:metrics.alert.threshold/alerts/rule/findBackfill", + "alerting:metrics.alert.threshold/alerts/rule/create", + "alerting:metrics.alert.threshold/alerts/rule/delete", + "alerting:metrics.alert.threshold/alerts/rule/update", + "alerting:metrics.alert.threshold/alerts/rule/updateApiKey", + "alerting:metrics.alert.threshold/alerts/rule/enable", + "alerting:metrics.alert.threshold/alerts/rule/disable", + "alerting:metrics.alert.threshold/alerts/rule/muteAll", + "alerting:metrics.alert.threshold/alerts/rule/unmuteAll", + "alerting:metrics.alert.threshold/alerts/rule/muteAlert", + "alerting:metrics.alert.threshold/alerts/rule/unmuteAlert", + "alerting:metrics.alert.threshold/alerts/rule/snooze", + "alerting:metrics.alert.threshold/alerts/rule/bulkEdit", + "alerting:metrics.alert.threshold/alerts/rule/bulkDelete", + "alerting:metrics.alert.threshold/alerts/rule/bulkEnable", + "alerting:metrics.alert.threshold/alerts/rule/bulkDisable", + "alerting:metrics.alert.threshold/alerts/rule/unsnooze", + "alerting:metrics.alert.threshold/alerts/rule/runSoon", + "alerting:metrics.alert.threshold/alerts/rule/scheduleBackfill", + "alerting:metrics.alert.threshold/alerts/rule/deleteBackfill", "alerting:metrics.alert.inventory.threshold/infrastructure/rule/get", "alerting:metrics.alert.inventory.threshold/infrastructure/rule/getRuleState", "alerting:metrics.alert.inventory.threshold/infrastructure/rule/getAlertSummary", @@ -5941,6 +11329,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:metrics.alert.inventory.threshold/infrastructure/rule/runSoon", "alerting:metrics.alert.inventory.threshold/infrastructure/rule/scheduleBackfill", "alerting:metrics.alert.inventory.threshold/infrastructure/rule/deleteBackfill", + "alerting:metrics.alert.inventory.threshold/alerts/rule/get", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getRuleState", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getExecutionLog", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getActionErrorLog", + "alerting:metrics.alert.inventory.threshold/alerts/rule/find", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getRuleExecutionKPI", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getBackfill", + "alerting:metrics.alert.inventory.threshold/alerts/rule/findBackfill", + "alerting:metrics.alert.inventory.threshold/alerts/rule/create", + "alerting:metrics.alert.inventory.threshold/alerts/rule/delete", + "alerting:metrics.alert.inventory.threshold/alerts/rule/update", + "alerting:metrics.alert.inventory.threshold/alerts/rule/updateApiKey", + "alerting:metrics.alert.inventory.threshold/alerts/rule/enable", + "alerting:metrics.alert.inventory.threshold/alerts/rule/disable", + "alerting:metrics.alert.inventory.threshold/alerts/rule/muteAll", + "alerting:metrics.alert.inventory.threshold/alerts/rule/unmuteAll", + "alerting:metrics.alert.inventory.threshold/alerts/rule/muteAlert", + "alerting:metrics.alert.inventory.threshold/alerts/rule/unmuteAlert", + "alerting:metrics.alert.inventory.threshold/alerts/rule/snooze", + "alerting:metrics.alert.inventory.threshold/alerts/rule/bulkEdit", + "alerting:metrics.alert.inventory.threshold/alerts/rule/bulkDelete", + "alerting:metrics.alert.inventory.threshold/alerts/rule/bulkEnable", + "alerting:metrics.alert.inventory.threshold/alerts/rule/bulkDisable", + "alerting:metrics.alert.inventory.threshold/alerts/rule/unsnooze", + "alerting:metrics.alert.inventory.threshold/alerts/rule/runSoon", + "alerting:metrics.alert.inventory.threshold/alerts/rule/scheduleBackfill", + "alerting:metrics.alert.inventory.threshold/alerts/rule/deleteBackfill", "alerting:.es-query/infrastructure/rule/get", "alerting:.es-query/infrastructure/rule/getRuleState", "alerting:.es-query/infrastructure/rule/getAlertSummary", @@ -5969,6 +11385,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:.es-query/infrastructure/rule/runSoon", "alerting:.es-query/infrastructure/rule/scheduleBackfill", "alerting:.es-query/infrastructure/rule/deleteBackfill", + "alerting:.es-query/alerts/rule/get", + "alerting:.es-query/alerts/rule/getRuleState", + "alerting:.es-query/alerts/rule/getAlertSummary", + "alerting:.es-query/alerts/rule/getExecutionLog", + "alerting:.es-query/alerts/rule/getActionErrorLog", + "alerting:.es-query/alerts/rule/find", + "alerting:.es-query/alerts/rule/getRuleExecutionKPI", + "alerting:.es-query/alerts/rule/getBackfill", + "alerting:.es-query/alerts/rule/findBackfill", + "alerting:.es-query/alerts/rule/create", + "alerting:.es-query/alerts/rule/delete", + "alerting:.es-query/alerts/rule/update", + "alerting:.es-query/alerts/rule/updateApiKey", + "alerting:.es-query/alerts/rule/enable", + "alerting:.es-query/alerts/rule/disable", + "alerting:.es-query/alerts/rule/muteAll", + "alerting:.es-query/alerts/rule/unmuteAll", + "alerting:.es-query/alerts/rule/muteAlert", + "alerting:.es-query/alerts/rule/unmuteAlert", + "alerting:.es-query/alerts/rule/snooze", + "alerting:.es-query/alerts/rule/bulkEdit", + "alerting:.es-query/alerts/rule/bulkDelete", + "alerting:.es-query/alerts/rule/bulkEnable", + "alerting:.es-query/alerts/rule/bulkDisable", + "alerting:.es-query/alerts/rule/unsnooze", + "alerting:.es-query/alerts/rule/runSoon", + "alerting:.es-query/alerts/rule/scheduleBackfill", + "alerting:.es-query/alerts/rule/deleteBackfill", "alerting:observability.rules.custom_threshold/infrastructure/rule/get", "alerting:observability.rules.custom_threshold/infrastructure/rule/getRuleState", "alerting:observability.rules.custom_threshold/infrastructure/rule/getAlertSummary", @@ -5997,6 +11441,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:observability.rules.custom_threshold/infrastructure/rule/runSoon", "alerting:observability.rules.custom_threshold/infrastructure/rule/scheduleBackfill", "alerting:observability.rules.custom_threshold/infrastructure/rule/deleteBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/get", + "alerting:observability.rules.custom_threshold/alerts/rule/getRuleState", + "alerting:observability.rules.custom_threshold/alerts/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/alerts/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/alerts/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/alerts/rule/find", + "alerting:observability.rules.custom_threshold/alerts/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/alerts/rule/getBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/findBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/create", + "alerting:observability.rules.custom_threshold/alerts/rule/delete", + "alerting:observability.rules.custom_threshold/alerts/rule/update", + "alerting:observability.rules.custom_threshold/alerts/rule/updateApiKey", + "alerting:observability.rules.custom_threshold/alerts/rule/enable", + "alerting:observability.rules.custom_threshold/alerts/rule/disable", + "alerting:observability.rules.custom_threshold/alerts/rule/muteAll", + "alerting:observability.rules.custom_threshold/alerts/rule/unmuteAll", + "alerting:observability.rules.custom_threshold/alerts/rule/muteAlert", + "alerting:observability.rules.custom_threshold/alerts/rule/unmuteAlert", + "alerting:observability.rules.custom_threshold/alerts/rule/snooze", + "alerting:observability.rules.custom_threshold/alerts/rule/bulkEdit", + "alerting:observability.rules.custom_threshold/alerts/rule/bulkDelete", + "alerting:observability.rules.custom_threshold/alerts/rule/bulkEnable", + "alerting:observability.rules.custom_threshold/alerts/rule/bulkDisable", + "alerting:observability.rules.custom_threshold/alerts/rule/unsnooze", + "alerting:observability.rules.custom_threshold/alerts/rule/runSoon", + "alerting:observability.rules.custom_threshold/alerts/rule/scheduleBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/deleteBackfill", "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/get", "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/getRuleState", "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/getAlertSummary", @@ -6025,31 +11497,84 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/runSoon", "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/scheduleBackfill", "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/deleteBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/create", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/delete", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/update", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/updateApiKey", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/enable", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/disable", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/muteAll", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/unmuteAll", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/muteAlert", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/unmuteAlert", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/snooze", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/bulkEdit", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/bulkDelete", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/bulkEnable", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/bulkDisable", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/unsnooze", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/runSoon", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/scheduleBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/deleteBackfill", "alerting:metrics.alert.threshold/infrastructure/alert/get", "alerting:metrics.alert.threshold/infrastructure/alert/find", "alerting:metrics.alert.threshold/infrastructure/alert/getAuthorizedAlertsIndices", "alerting:metrics.alert.threshold/infrastructure/alert/getAlertSummary", "alerting:metrics.alert.threshold/infrastructure/alert/update", + "alerting:metrics.alert.threshold/alerts/alert/get", + "alerting:metrics.alert.threshold/alerts/alert/find", + "alerting:metrics.alert.threshold/alerts/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.threshold/alerts/alert/getAlertSummary", + "alerting:metrics.alert.threshold/alerts/alert/update", "alerting:metrics.alert.inventory.threshold/infrastructure/alert/get", "alerting:metrics.alert.inventory.threshold/infrastructure/alert/find", "alerting:metrics.alert.inventory.threshold/infrastructure/alert/getAuthorizedAlertsIndices", "alerting:metrics.alert.inventory.threshold/infrastructure/alert/getAlertSummary", "alerting:metrics.alert.inventory.threshold/infrastructure/alert/update", + "alerting:metrics.alert.inventory.threshold/alerts/alert/get", + "alerting:metrics.alert.inventory.threshold/alerts/alert/find", + "alerting:metrics.alert.inventory.threshold/alerts/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.inventory.threshold/alerts/alert/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/alerts/alert/update", "alerting:.es-query/infrastructure/alert/get", "alerting:.es-query/infrastructure/alert/find", "alerting:.es-query/infrastructure/alert/getAuthorizedAlertsIndices", "alerting:.es-query/infrastructure/alert/getAlertSummary", "alerting:.es-query/infrastructure/alert/update", + "alerting:.es-query/alerts/alert/get", + "alerting:.es-query/alerts/alert/find", + "alerting:.es-query/alerts/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/alerts/alert/getAlertSummary", + "alerting:.es-query/alerts/alert/update", "alerting:observability.rules.custom_threshold/infrastructure/alert/get", "alerting:observability.rules.custom_threshold/infrastructure/alert/find", "alerting:observability.rules.custom_threshold/infrastructure/alert/getAuthorizedAlertsIndices", "alerting:observability.rules.custom_threshold/infrastructure/alert/getAlertSummary", "alerting:observability.rules.custom_threshold/infrastructure/alert/update", + "alerting:observability.rules.custom_threshold/alerts/alert/get", + "alerting:observability.rules.custom_threshold/alerts/alert/find", + "alerting:observability.rules.custom_threshold/alerts/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/alerts/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/alerts/alert/update", "alerting:xpack.ml.anomaly_detection_alert/infrastructure/alert/get", "alerting:xpack.ml.anomaly_detection_alert/infrastructure/alert/find", "alerting:xpack.ml.anomaly_detection_alert/infrastructure/alert/getAuthorizedAlertsIndices", "alerting:xpack.ml.anomaly_detection_alert/infrastructure/alert/getAlertSummary", "alerting:xpack.ml.anomaly_detection_alert/infrastructure/alert/update", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/update", "app:logs", "app:observability-logs-explorer", "ui:catalogue/infralogging", @@ -6099,6 +11624,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:logs.alert.document.count/logs/rule/runSoon", "alerting:logs.alert.document.count/logs/rule/scheduleBackfill", "alerting:logs.alert.document.count/logs/rule/deleteBackfill", + "alerting:logs.alert.document.count/alerts/rule/get", + "alerting:logs.alert.document.count/alerts/rule/getRuleState", + "alerting:logs.alert.document.count/alerts/rule/getAlertSummary", + "alerting:logs.alert.document.count/alerts/rule/getExecutionLog", + "alerting:logs.alert.document.count/alerts/rule/getActionErrorLog", + "alerting:logs.alert.document.count/alerts/rule/find", + "alerting:logs.alert.document.count/alerts/rule/getRuleExecutionKPI", + "alerting:logs.alert.document.count/alerts/rule/getBackfill", + "alerting:logs.alert.document.count/alerts/rule/findBackfill", + "alerting:logs.alert.document.count/alerts/rule/create", + "alerting:logs.alert.document.count/alerts/rule/delete", + "alerting:logs.alert.document.count/alerts/rule/update", + "alerting:logs.alert.document.count/alerts/rule/updateApiKey", + "alerting:logs.alert.document.count/alerts/rule/enable", + "alerting:logs.alert.document.count/alerts/rule/disable", + "alerting:logs.alert.document.count/alerts/rule/muteAll", + "alerting:logs.alert.document.count/alerts/rule/unmuteAll", + "alerting:logs.alert.document.count/alerts/rule/muteAlert", + "alerting:logs.alert.document.count/alerts/rule/unmuteAlert", + "alerting:logs.alert.document.count/alerts/rule/snooze", + "alerting:logs.alert.document.count/alerts/rule/bulkEdit", + "alerting:logs.alert.document.count/alerts/rule/bulkDelete", + "alerting:logs.alert.document.count/alerts/rule/bulkEnable", + "alerting:logs.alert.document.count/alerts/rule/bulkDisable", + "alerting:logs.alert.document.count/alerts/rule/unsnooze", + "alerting:logs.alert.document.count/alerts/rule/runSoon", + "alerting:logs.alert.document.count/alerts/rule/scheduleBackfill", + "alerting:logs.alert.document.count/alerts/rule/deleteBackfill", "alerting:.es-query/logs/rule/get", "alerting:.es-query/logs/rule/getRuleState", "alerting:.es-query/logs/rule/getAlertSummary", @@ -6108,246 +11661,111 @@ export default function ({ getService }: FtrProviderContext) { "alerting:.es-query/logs/rule/getRuleExecutionKPI", "alerting:.es-query/logs/rule/getBackfill", "alerting:.es-query/logs/rule/findBackfill", - "alerting:.es-query/logs/rule/create", - "alerting:.es-query/logs/rule/delete", - "alerting:.es-query/logs/rule/update", - "alerting:.es-query/logs/rule/updateApiKey", - "alerting:.es-query/logs/rule/enable", - "alerting:.es-query/logs/rule/disable", - "alerting:.es-query/logs/rule/muteAll", - "alerting:.es-query/logs/rule/unmuteAll", - "alerting:.es-query/logs/rule/muteAlert", - "alerting:.es-query/logs/rule/unmuteAlert", - "alerting:.es-query/logs/rule/snooze", - "alerting:.es-query/logs/rule/bulkEdit", - "alerting:.es-query/logs/rule/bulkDelete", - "alerting:.es-query/logs/rule/bulkEnable", - "alerting:.es-query/logs/rule/bulkDisable", - "alerting:.es-query/logs/rule/unsnooze", - "alerting:.es-query/logs/rule/runSoon", - "alerting:.es-query/logs/rule/scheduleBackfill", - "alerting:.es-query/logs/rule/deleteBackfill", - "alerting:observability.rules.custom_threshold/logs/rule/get", - "alerting:observability.rules.custom_threshold/logs/rule/getRuleState", - "alerting:observability.rules.custom_threshold/logs/rule/getAlertSummary", - "alerting:observability.rules.custom_threshold/logs/rule/getExecutionLog", - "alerting:observability.rules.custom_threshold/logs/rule/getActionErrorLog", - "alerting:observability.rules.custom_threshold/logs/rule/find", - "alerting:observability.rules.custom_threshold/logs/rule/getRuleExecutionKPI", - "alerting:observability.rules.custom_threshold/logs/rule/getBackfill", - "alerting:observability.rules.custom_threshold/logs/rule/findBackfill", - "alerting:observability.rules.custom_threshold/logs/rule/create", - "alerting:observability.rules.custom_threshold/logs/rule/delete", - "alerting:observability.rules.custom_threshold/logs/rule/update", - "alerting:observability.rules.custom_threshold/logs/rule/updateApiKey", - "alerting:observability.rules.custom_threshold/logs/rule/enable", - "alerting:observability.rules.custom_threshold/logs/rule/disable", - "alerting:observability.rules.custom_threshold/logs/rule/muteAll", - "alerting:observability.rules.custom_threshold/logs/rule/unmuteAll", - "alerting:observability.rules.custom_threshold/logs/rule/muteAlert", - "alerting:observability.rules.custom_threshold/logs/rule/unmuteAlert", - "alerting:observability.rules.custom_threshold/logs/rule/snooze", - "alerting:observability.rules.custom_threshold/logs/rule/bulkEdit", - "alerting:observability.rules.custom_threshold/logs/rule/bulkDelete", - "alerting:observability.rules.custom_threshold/logs/rule/bulkEnable", - "alerting:observability.rules.custom_threshold/logs/rule/bulkDisable", - "alerting:observability.rules.custom_threshold/logs/rule/unsnooze", - "alerting:observability.rules.custom_threshold/logs/rule/runSoon", - "alerting:observability.rules.custom_threshold/logs/rule/scheduleBackfill", - "alerting:observability.rules.custom_threshold/logs/rule/deleteBackfill", - "alerting:xpack.ml.anomaly_detection_alert/logs/rule/get", - "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getRuleState", - "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getAlertSummary", - "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getExecutionLog", - "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getActionErrorLog", - "alerting:xpack.ml.anomaly_detection_alert/logs/rule/find", - "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getRuleExecutionKPI", - "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getBackfill", - "alerting:xpack.ml.anomaly_detection_alert/logs/rule/findBackfill", - "alerting:xpack.ml.anomaly_detection_alert/logs/rule/create", - "alerting:xpack.ml.anomaly_detection_alert/logs/rule/delete", - "alerting:xpack.ml.anomaly_detection_alert/logs/rule/update", - "alerting:xpack.ml.anomaly_detection_alert/logs/rule/updateApiKey", - "alerting:xpack.ml.anomaly_detection_alert/logs/rule/enable", - "alerting:xpack.ml.anomaly_detection_alert/logs/rule/disable", - "alerting:xpack.ml.anomaly_detection_alert/logs/rule/muteAll", - "alerting:xpack.ml.anomaly_detection_alert/logs/rule/unmuteAll", - "alerting:xpack.ml.anomaly_detection_alert/logs/rule/muteAlert", - "alerting:xpack.ml.anomaly_detection_alert/logs/rule/unmuteAlert", - "alerting:xpack.ml.anomaly_detection_alert/logs/rule/snooze", - "alerting:xpack.ml.anomaly_detection_alert/logs/rule/bulkEdit", - "alerting:xpack.ml.anomaly_detection_alert/logs/rule/bulkDelete", - "alerting:xpack.ml.anomaly_detection_alert/logs/rule/bulkEnable", - "alerting:xpack.ml.anomaly_detection_alert/logs/rule/bulkDisable", - "alerting:xpack.ml.anomaly_detection_alert/logs/rule/unsnooze", - "alerting:xpack.ml.anomaly_detection_alert/logs/rule/runSoon", - "alerting:xpack.ml.anomaly_detection_alert/logs/rule/scheduleBackfill", - "alerting:xpack.ml.anomaly_detection_alert/logs/rule/deleteBackfill", - "alerting:logs.alert.document.count/logs/alert/get", - "alerting:logs.alert.document.count/logs/alert/find", - "alerting:logs.alert.document.count/logs/alert/getAuthorizedAlertsIndices", - "alerting:logs.alert.document.count/logs/alert/getAlertSummary", - "alerting:logs.alert.document.count/logs/alert/update", - "alerting:.es-query/logs/alert/get", - "alerting:.es-query/logs/alert/find", - "alerting:.es-query/logs/alert/getAuthorizedAlertsIndices", - "alerting:.es-query/logs/alert/getAlertSummary", - "alerting:.es-query/logs/alert/update", - "alerting:observability.rules.custom_threshold/logs/alert/get", - "alerting:observability.rules.custom_threshold/logs/alert/find", - "alerting:observability.rules.custom_threshold/logs/alert/getAuthorizedAlertsIndices", - "alerting:observability.rules.custom_threshold/logs/alert/getAlertSummary", - "alerting:observability.rules.custom_threshold/logs/alert/update", - "alerting:xpack.ml.anomaly_detection_alert/logs/alert/get", - "alerting:xpack.ml.anomaly_detection_alert/logs/alert/find", - "alerting:xpack.ml.anomaly_detection_alert/logs/alert/getAuthorizedAlertsIndices", - "alerting:xpack.ml.anomaly_detection_alert/logs/alert/getAlertSummary", - "alerting:xpack.ml.anomaly_detection_alert/logs/alert/update", - "app:observability", - "ui:catalogue/observability", - "ui:navLinks/observability", - "ui:observability/read", - "ui:observability/write", - "alerting:slo.rules.burnRate/observability/rule/get", - "alerting:slo.rules.burnRate/observability/rule/getRuleState", - "alerting:slo.rules.burnRate/observability/rule/getAlertSummary", - "alerting:slo.rules.burnRate/observability/rule/getExecutionLog", - "alerting:slo.rules.burnRate/observability/rule/getActionErrorLog", - "alerting:slo.rules.burnRate/observability/rule/find", - "alerting:slo.rules.burnRate/observability/rule/getRuleExecutionKPI", - "alerting:slo.rules.burnRate/observability/rule/getBackfill", - "alerting:slo.rules.burnRate/observability/rule/findBackfill", - "alerting:slo.rules.burnRate/observability/rule/create", - "alerting:slo.rules.burnRate/observability/rule/delete", - "alerting:slo.rules.burnRate/observability/rule/update", - "alerting:slo.rules.burnRate/observability/rule/updateApiKey", - "alerting:slo.rules.burnRate/observability/rule/enable", - "alerting:slo.rules.burnRate/observability/rule/disable", - "alerting:slo.rules.burnRate/observability/rule/muteAll", - "alerting:slo.rules.burnRate/observability/rule/unmuteAll", - "alerting:slo.rules.burnRate/observability/rule/muteAlert", - "alerting:slo.rules.burnRate/observability/rule/unmuteAlert", - "alerting:slo.rules.burnRate/observability/rule/snooze", - "alerting:slo.rules.burnRate/observability/rule/bulkEdit", - "alerting:slo.rules.burnRate/observability/rule/bulkDelete", - "alerting:slo.rules.burnRate/observability/rule/bulkEnable", - "alerting:slo.rules.burnRate/observability/rule/bulkDisable", - "alerting:slo.rules.burnRate/observability/rule/unsnooze", - "alerting:slo.rules.burnRate/observability/rule/runSoon", - "alerting:slo.rules.burnRate/observability/rule/scheduleBackfill", - "alerting:slo.rules.burnRate/observability/rule/deleteBackfill", - "alerting:observability.rules.custom_threshold/observability/rule/get", - "alerting:observability.rules.custom_threshold/observability/rule/getRuleState", - "alerting:observability.rules.custom_threshold/observability/rule/getAlertSummary", - "alerting:observability.rules.custom_threshold/observability/rule/getExecutionLog", - "alerting:observability.rules.custom_threshold/observability/rule/getActionErrorLog", - "alerting:observability.rules.custom_threshold/observability/rule/find", - "alerting:observability.rules.custom_threshold/observability/rule/getRuleExecutionKPI", - "alerting:observability.rules.custom_threshold/observability/rule/getBackfill", - "alerting:observability.rules.custom_threshold/observability/rule/findBackfill", - "alerting:observability.rules.custom_threshold/observability/rule/create", - "alerting:observability.rules.custom_threshold/observability/rule/delete", - "alerting:observability.rules.custom_threshold/observability/rule/update", - "alerting:observability.rules.custom_threshold/observability/rule/updateApiKey", - "alerting:observability.rules.custom_threshold/observability/rule/enable", - "alerting:observability.rules.custom_threshold/observability/rule/disable", - "alerting:observability.rules.custom_threshold/observability/rule/muteAll", - "alerting:observability.rules.custom_threshold/observability/rule/unmuteAll", - "alerting:observability.rules.custom_threshold/observability/rule/muteAlert", - "alerting:observability.rules.custom_threshold/observability/rule/unmuteAlert", - "alerting:observability.rules.custom_threshold/observability/rule/snooze", - "alerting:observability.rules.custom_threshold/observability/rule/bulkEdit", - "alerting:observability.rules.custom_threshold/observability/rule/bulkDelete", - "alerting:observability.rules.custom_threshold/observability/rule/bulkEnable", - "alerting:observability.rules.custom_threshold/observability/rule/bulkDisable", - "alerting:observability.rules.custom_threshold/observability/rule/unsnooze", - "alerting:observability.rules.custom_threshold/observability/rule/runSoon", - "alerting:observability.rules.custom_threshold/observability/rule/scheduleBackfill", - "alerting:observability.rules.custom_threshold/observability/rule/deleteBackfill", - "alerting:.es-query/observability/rule/get", - "alerting:.es-query/observability/rule/getRuleState", - "alerting:.es-query/observability/rule/getAlertSummary", - "alerting:.es-query/observability/rule/getExecutionLog", - "alerting:.es-query/observability/rule/getActionErrorLog", - "alerting:.es-query/observability/rule/find", - "alerting:.es-query/observability/rule/getRuleExecutionKPI", - "alerting:.es-query/observability/rule/getBackfill", - "alerting:.es-query/observability/rule/findBackfill", - "alerting:.es-query/observability/rule/create", - "alerting:.es-query/observability/rule/delete", - "alerting:.es-query/observability/rule/update", - "alerting:.es-query/observability/rule/updateApiKey", - "alerting:.es-query/observability/rule/enable", - "alerting:.es-query/observability/rule/disable", - "alerting:.es-query/observability/rule/muteAll", - "alerting:.es-query/observability/rule/unmuteAll", - "alerting:.es-query/observability/rule/muteAlert", - "alerting:.es-query/observability/rule/unmuteAlert", - "alerting:.es-query/observability/rule/snooze", - "alerting:.es-query/observability/rule/bulkEdit", - "alerting:.es-query/observability/rule/bulkDelete", - "alerting:.es-query/observability/rule/bulkEnable", - "alerting:.es-query/observability/rule/bulkDisable", - "alerting:.es-query/observability/rule/unsnooze", - "alerting:.es-query/observability/rule/runSoon", - "alerting:.es-query/observability/rule/scheduleBackfill", - "alerting:.es-query/observability/rule/deleteBackfill", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/get", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleState", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getAlertSummary", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getExecutionLog", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getActionErrorLog", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/find", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleExecutionKPI", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getBackfill", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/findBackfill", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/create", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/delete", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/update", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/updateApiKey", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/enable", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/disable", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/muteAll", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unmuteAll", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/muteAlert", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unmuteAlert", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/snooze", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkEdit", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkDelete", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkEnable", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkDisable", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unsnooze", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/runSoon", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/scheduleBackfill", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/deleteBackfill", - "alerting:metrics.alert.inventory.threshold/observability/rule/get", - "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleState", - "alerting:metrics.alert.inventory.threshold/observability/rule/getAlertSummary", - "alerting:metrics.alert.inventory.threshold/observability/rule/getExecutionLog", - "alerting:metrics.alert.inventory.threshold/observability/rule/getActionErrorLog", - "alerting:metrics.alert.inventory.threshold/observability/rule/find", - "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleExecutionKPI", - "alerting:metrics.alert.inventory.threshold/observability/rule/getBackfill", - "alerting:metrics.alert.inventory.threshold/observability/rule/findBackfill", - "alerting:metrics.alert.inventory.threshold/observability/rule/create", - "alerting:metrics.alert.inventory.threshold/observability/rule/delete", - "alerting:metrics.alert.inventory.threshold/observability/rule/update", - "alerting:metrics.alert.inventory.threshold/observability/rule/updateApiKey", - "alerting:metrics.alert.inventory.threshold/observability/rule/enable", - "alerting:metrics.alert.inventory.threshold/observability/rule/disable", - "alerting:metrics.alert.inventory.threshold/observability/rule/muteAll", - "alerting:metrics.alert.inventory.threshold/observability/rule/unmuteAll", - "alerting:metrics.alert.inventory.threshold/observability/rule/muteAlert", - "alerting:metrics.alert.inventory.threshold/observability/rule/unmuteAlert", - "alerting:metrics.alert.inventory.threshold/observability/rule/snooze", - "alerting:metrics.alert.inventory.threshold/observability/rule/bulkEdit", - "alerting:metrics.alert.inventory.threshold/observability/rule/bulkDelete", - "alerting:metrics.alert.inventory.threshold/observability/rule/bulkEnable", - "alerting:metrics.alert.inventory.threshold/observability/rule/bulkDisable", - "alerting:metrics.alert.inventory.threshold/observability/rule/unsnooze", - "alerting:metrics.alert.inventory.threshold/observability/rule/runSoon", - "alerting:metrics.alert.inventory.threshold/observability/rule/scheduleBackfill", - "alerting:metrics.alert.inventory.threshold/observability/rule/deleteBackfill", + "alerting:.es-query/logs/rule/create", + "alerting:.es-query/logs/rule/delete", + "alerting:.es-query/logs/rule/update", + "alerting:.es-query/logs/rule/updateApiKey", + "alerting:.es-query/logs/rule/enable", + "alerting:.es-query/logs/rule/disable", + "alerting:.es-query/logs/rule/muteAll", + "alerting:.es-query/logs/rule/unmuteAll", + "alerting:.es-query/logs/rule/muteAlert", + "alerting:.es-query/logs/rule/unmuteAlert", + "alerting:.es-query/logs/rule/snooze", + "alerting:.es-query/logs/rule/bulkEdit", + "alerting:.es-query/logs/rule/bulkDelete", + "alerting:.es-query/logs/rule/bulkEnable", + "alerting:.es-query/logs/rule/bulkDisable", + "alerting:.es-query/logs/rule/unsnooze", + "alerting:.es-query/logs/rule/runSoon", + "alerting:.es-query/logs/rule/scheduleBackfill", + "alerting:.es-query/logs/rule/deleteBackfill", + "alerting:observability.rules.custom_threshold/logs/rule/get", + "alerting:observability.rules.custom_threshold/logs/rule/getRuleState", + "alerting:observability.rules.custom_threshold/logs/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/logs/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/logs/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/logs/rule/find", + "alerting:observability.rules.custom_threshold/logs/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/logs/rule/getBackfill", + "alerting:observability.rules.custom_threshold/logs/rule/findBackfill", + "alerting:observability.rules.custom_threshold/logs/rule/create", + "alerting:observability.rules.custom_threshold/logs/rule/delete", + "alerting:observability.rules.custom_threshold/logs/rule/update", + "alerting:observability.rules.custom_threshold/logs/rule/updateApiKey", + "alerting:observability.rules.custom_threshold/logs/rule/enable", + "alerting:observability.rules.custom_threshold/logs/rule/disable", + "alerting:observability.rules.custom_threshold/logs/rule/muteAll", + "alerting:observability.rules.custom_threshold/logs/rule/unmuteAll", + "alerting:observability.rules.custom_threshold/logs/rule/muteAlert", + "alerting:observability.rules.custom_threshold/logs/rule/unmuteAlert", + "alerting:observability.rules.custom_threshold/logs/rule/snooze", + "alerting:observability.rules.custom_threshold/logs/rule/bulkEdit", + "alerting:observability.rules.custom_threshold/logs/rule/bulkDelete", + "alerting:observability.rules.custom_threshold/logs/rule/bulkEnable", + "alerting:observability.rules.custom_threshold/logs/rule/bulkDisable", + "alerting:observability.rules.custom_threshold/logs/rule/unsnooze", + "alerting:observability.rules.custom_threshold/logs/rule/runSoon", + "alerting:observability.rules.custom_threshold/logs/rule/scheduleBackfill", + "alerting:observability.rules.custom_threshold/logs/rule/deleteBackfill", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/create", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/delete", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/update", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/updateApiKey", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/enable", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/disable", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/muteAll", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/unmuteAll", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/muteAlert", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/unmuteAlert", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/snooze", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/bulkEdit", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/bulkDelete", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/bulkEnable", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/bulkDisable", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/unsnooze", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/runSoon", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/scheduleBackfill", + "alerting:xpack.ml.anomaly_detection_alert/logs/rule/deleteBackfill", + "alerting:logs.alert.document.count/logs/alert/get", + "alerting:logs.alert.document.count/logs/alert/find", + "alerting:logs.alert.document.count/logs/alert/getAuthorizedAlertsIndices", + "alerting:logs.alert.document.count/logs/alert/getAlertSummary", + "alerting:logs.alert.document.count/logs/alert/update", + "alerting:logs.alert.document.count/alerts/alert/get", + "alerting:logs.alert.document.count/alerts/alert/find", + "alerting:logs.alert.document.count/alerts/alert/getAuthorizedAlertsIndices", + "alerting:logs.alert.document.count/alerts/alert/getAlertSummary", + "alerting:logs.alert.document.count/alerts/alert/update", + "alerting:.es-query/logs/alert/get", + "alerting:.es-query/logs/alert/find", + "alerting:.es-query/logs/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/logs/alert/getAlertSummary", + "alerting:.es-query/logs/alert/update", + "alerting:observability.rules.custom_threshold/logs/alert/get", + "alerting:observability.rules.custom_threshold/logs/alert/find", + "alerting:observability.rules.custom_threshold/logs/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/logs/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/logs/alert/update", + "alerting:xpack.ml.anomaly_detection_alert/logs/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/logs/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/logs/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/logs/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/logs/alert/update", + "app:observability", + "ui:catalogue/observability", + "ui:navLinks/observability", + "ui:observability/read", + "ui:observability/write", "alerting:apm.error_rate/observability/rule/get", "alerting:apm.error_rate/observability/rule/getRuleState", "alerting:apm.error_rate/observability/rule/getAlertSummary", @@ -6376,6 +11794,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.error_rate/observability/rule/runSoon", "alerting:apm.error_rate/observability/rule/scheduleBackfill", "alerting:apm.error_rate/observability/rule/deleteBackfill", + "alerting:apm.error_rate/alerts/rule/get", + "alerting:apm.error_rate/alerts/rule/getRuleState", + "alerting:apm.error_rate/alerts/rule/getAlertSummary", + "alerting:apm.error_rate/alerts/rule/getExecutionLog", + "alerting:apm.error_rate/alerts/rule/getActionErrorLog", + "alerting:apm.error_rate/alerts/rule/find", + "alerting:apm.error_rate/alerts/rule/getRuleExecutionKPI", + "alerting:apm.error_rate/alerts/rule/getBackfill", + "alerting:apm.error_rate/alerts/rule/findBackfill", + "alerting:apm.error_rate/alerts/rule/create", + "alerting:apm.error_rate/alerts/rule/delete", + "alerting:apm.error_rate/alerts/rule/update", + "alerting:apm.error_rate/alerts/rule/updateApiKey", + "alerting:apm.error_rate/alerts/rule/enable", + "alerting:apm.error_rate/alerts/rule/disable", + "alerting:apm.error_rate/alerts/rule/muteAll", + "alerting:apm.error_rate/alerts/rule/unmuteAll", + "alerting:apm.error_rate/alerts/rule/muteAlert", + "alerting:apm.error_rate/alerts/rule/unmuteAlert", + "alerting:apm.error_rate/alerts/rule/snooze", + "alerting:apm.error_rate/alerts/rule/bulkEdit", + "alerting:apm.error_rate/alerts/rule/bulkDelete", + "alerting:apm.error_rate/alerts/rule/bulkEnable", + "alerting:apm.error_rate/alerts/rule/bulkDisable", + "alerting:apm.error_rate/alerts/rule/unsnooze", + "alerting:apm.error_rate/alerts/rule/runSoon", + "alerting:apm.error_rate/alerts/rule/scheduleBackfill", + "alerting:apm.error_rate/alerts/rule/deleteBackfill", "alerting:apm.transaction_error_rate/observability/rule/get", "alerting:apm.transaction_error_rate/observability/rule/getRuleState", "alerting:apm.transaction_error_rate/observability/rule/getAlertSummary", @@ -6404,6 +11850,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.transaction_error_rate/observability/rule/runSoon", "alerting:apm.transaction_error_rate/observability/rule/scheduleBackfill", "alerting:apm.transaction_error_rate/observability/rule/deleteBackfill", + "alerting:apm.transaction_error_rate/alerts/rule/get", + "alerting:apm.transaction_error_rate/alerts/rule/getRuleState", + "alerting:apm.transaction_error_rate/alerts/rule/getAlertSummary", + "alerting:apm.transaction_error_rate/alerts/rule/getExecutionLog", + "alerting:apm.transaction_error_rate/alerts/rule/getActionErrorLog", + "alerting:apm.transaction_error_rate/alerts/rule/find", + "alerting:apm.transaction_error_rate/alerts/rule/getRuleExecutionKPI", + "alerting:apm.transaction_error_rate/alerts/rule/getBackfill", + "alerting:apm.transaction_error_rate/alerts/rule/findBackfill", + "alerting:apm.transaction_error_rate/alerts/rule/create", + "alerting:apm.transaction_error_rate/alerts/rule/delete", + "alerting:apm.transaction_error_rate/alerts/rule/update", + "alerting:apm.transaction_error_rate/alerts/rule/updateApiKey", + "alerting:apm.transaction_error_rate/alerts/rule/enable", + "alerting:apm.transaction_error_rate/alerts/rule/disable", + "alerting:apm.transaction_error_rate/alerts/rule/muteAll", + "alerting:apm.transaction_error_rate/alerts/rule/unmuteAll", + "alerting:apm.transaction_error_rate/alerts/rule/muteAlert", + "alerting:apm.transaction_error_rate/alerts/rule/unmuteAlert", + "alerting:apm.transaction_error_rate/alerts/rule/snooze", + "alerting:apm.transaction_error_rate/alerts/rule/bulkEdit", + "alerting:apm.transaction_error_rate/alerts/rule/bulkDelete", + "alerting:apm.transaction_error_rate/alerts/rule/bulkEnable", + "alerting:apm.transaction_error_rate/alerts/rule/bulkDisable", + "alerting:apm.transaction_error_rate/alerts/rule/unsnooze", + "alerting:apm.transaction_error_rate/alerts/rule/runSoon", + "alerting:apm.transaction_error_rate/alerts/rule/scheduleBackfill", + "alerting:apm.transaction_error_rate/alerts/rule/deleteBackfill", "alerting:apm.transaction_duration/observability/rule/get", "alerting:apm.transaction_duration/observability/rule/getRuleState", "alerting:apm.transaction_duration/observability/rule/getAlertSummary", @@ -6432,6 +11906,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.transaction_duration/observability/rule/runSoon", "alerting:apm.transaction_duration/observability/rule/scheduleBackfill", "alerting:apm.transaction_duration/observability/rule/deleteBackfill", + "alerting:apm.transaction_duration/alerts/rule/get", + "alerting:apm.transaction_duration/alerts/rule/getRuleState", + "alerting:apm.transaction_duration/alerts/rule/getAlertSummary", + "alerting:apm.transaction_duration/alerts/rule/getExecutionLog", + "alerting:apm.transaction_duration/alerts/rule/getActionErrorLog", + "alerting:apm.transaction_duration/alerts/rule/find", + "alerting:apm.transaction_duration/alerts/rule/getRuleExecutionKPI", + "alerting:apm.transaction_duration/alerts/rule/getBackfill", + "alerting:apm.transaction_duration/alerts/rule/findBackfill", + "alerting:apm.transaction_duration/alerts/rule/create", + "alerting:apm.transaction_duration/alerts/rule/delete", + "alerting:apm.transaction_duration/alerts/rule/update", + "alerting:apm.transaction_duration/alerts/rule/updateApiKey", + "alerting:apm.transaction_duration/alerts/rule/enable", + "alerting:apm.transaction_duration/alerts/rule/disable", + "alerting:apm.transaction_duration/alerts/rule/muteAll", + "alerting:apm.transaction_duration/alerts/rule/unmuteAll", + "alerting:apm.transaction_duration/alerts/rule/muteAlert", + "alerting:apm.transaction_duration/alerts/rule/unmuteAlert", + "alerting:apm.transaction_duration/alerts/rule/snooze", + "alerting:apm.transaction_duration/alerts/rule/bulkEdit", + "alerting:apm.transaction_duration/alerts/rule/bulkDelete", + "alerting:apm.transaction_duration/alerts/rule/bulkEnable", + "alerting:apm.transaction_duration/alerts/rule/bulkDisable", + "alerting:apm.transaction_duration/alerts/rule/unsnooze", + "alerting:apm.transaction_duration/alerts/rule/runSoon", + "alerting:apm.transaction_duration/alerts/rule/scheduleBackfill", + "alerting:apm.transaction_duration/alerts/rule/deleteBackfill", "alerting:apm.anomaly/observability/rule/get", "alerting:apm.anomaly/observability/rule/getRuleState", "alerting:apm.anomaly/observability/rule/getAlertSummary", @@ -6460,6 +11962,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.anomaly/observability/rule/runSoon", "alerting:apm.anomaly/observability/rule/scheduleBackfill", "alerting:apm.anomaly/observability/rule/deleteBackfill", + "alerting:apm.anomaly/alerts/rule/get", + "alerting:apm.anomaly/alerts/rule/getRuleState", + "alerting:apm.anomaly/alerts/rule/getAlertSummary", + "alerting:apm.anomaly/alerts/rule/getExecutionLog", + "alerting:apm.anomaly/alerts/rule/getActionErrorLog", + "alerting:apm.anomaly/alerts/rule/find", + "alerting:apm.anomaly/alerts/rule/getRuleExecutionKPI", + "alerting:apm.anomaly/alerts/rule/getBackfill", + "alerting:apm.anomaly/alerts/rule/findBackfill", + "alerting:apm.anomaly/alerts/rule/create", + "alerting:apm.anomaly/alerts/rule/delete", + "alerting:apm.anomaly/alerts/rule/update", + "alerting:apm.anomaly/alerts/rule/updateApiKey", + "alerting:apm.anomaly/alerts/rule/enable", + "alerting:apm.anomaly/alerts/rule/disable", + "alerting:apm.anomaly/alerts/rule/muteAll", + "alerting:apm.anomaly/alerts/rule/unmuteAll", + "alerting:apm.anomaly/alerts/rule/muteAlert", + "alerting:apm.anomaly/alerts/rule/unmuteAlert", + "alerting:apm.anomaly/alerts/rule/snooze", + "alerting:apm.anomaly/alerts/rule/bulkEdit", + "alerting:apm.anomaly/alerts/rule/bulkDelete", + "alerting:apm.anomaly/alerts/rule/bulkEnable", + "alerting:apm.anomaly/alerts/rule/bulkDisable", + "alerting:apm.anomaly/alerts/rule/unsnooze", + "alerting:apm.anomaly/alerts/rule/runSoon", + "alerting:apm.anomaly/alerts/rule/scheduleBackfill", + "alerting:apm.anomaly/alerts/rule/deleteBackfill", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/get", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/getRuleState", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/getAlertSummary", @@ -6488,6 +12018,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/runSoon", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/scheduleBackfill", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/deleteBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/get", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getRuleState", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getAlertSummary", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getExecutionLog", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getActionErrorLog", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/find", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/findBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/create", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/delete", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/update", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/updateApiKey", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/enable", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/disable", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/muteAll", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/unmuteAll", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/muteAlert", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/unmuteAlert", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/snooze", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/bulkEdit", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/bulkDelete", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/bulkEnable", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/bulkDisable", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/unsnooze", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/runSoon", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/scheduleBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/deleteBackfill", "alerting:xpack.synthetics.alerts.tls/observability/rule/get", "alerting:xpack.synthetics.alerts.tls/observability/rule/getRuleState", "alerting:xpack.synthetics.alerts.tls/observability/rule/getAlertSummary", @@ -6516,61 +12074,622 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.synthetics.alerts.tls/observability/rule/runSoon", "alerting:xpack.synthetics.alerts.tls/observability/rule/scheduleBackfill", "alerting:xpack.synthetics.alerts.tls/observability/rule/deleteBackfill", - "alerting:slo.rules.burnRate/observability/alert/get", - "alerting:slo.rules.burnRate/observability/alert/find", - "alerting:slo.rules.burnRate/observability/alert/getAuthorizedAlertsIndices", - "alerting:slo.rules.burnRate/observability/alert/getAlertSummary", - "alerting:slo.rules.burnRate/observability/alert/update", - "alerting:observability.rules.custom_threshold/observability/alert/get", - "alerting:observability.rules.custom_threshold/observability/alert/find", - "alerting:observability.rules.custom_threshold/observability/alert/getAuthorizedAlertsIndices", - "alerting:observability.rules.custom_threshold/observability/alert/getAlertSummary", - "alerting:observability.rules.custom_threshold/observability/alert/update", - "alerting:.es-query/observability/alert/get", - "alerting:.es-query/observability/alert/find", - "alerting:.es-query/observability/alert/getAuthorizedAlertsIndices", - "alerting:.es-query/observability/alert/getAlertSummary", - "alerting:.es-query/observability/alert/update", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/get", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/find", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAuthorizedAlertsIndices", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAlertSummary", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/update", - "alerting:metrics.alert.inventory.threshold/observability/alert/get", - "alerting:metrics.alert.inventory.threshold/observability/alert/find", - "alerting:metrics.alert.inventory.threshold/observability/alert/getAuthorizedAlertsIndices", - "alerting:metrics.alert.inventory.threshold/observability/alert/getAlertSummary", - "alerting:metrics.alert.inventory.threshold/observability/alert/update", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/get", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getRuleState", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getAlertSummary", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getExecutionLog", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getActionErrorLog", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/find", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getBackfill", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/findBackfill", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/create", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/delete", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/update", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/updateApiKey", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/enable", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/disable", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/muteAll", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/unmuteAll", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/muteAlert", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/unmuteAlert", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/snooze", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/bulkEdit", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/bulkDelete", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/bulkEnable", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/bulkDisable", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/unsnooze", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/runSoon", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/scheduleBackfill", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/deleteBackfill", + "alerting:metrics.alert.threshold/observability/rule/get", + "alerting:metrics.alert.threshold/observability/rule/getRuleState", + "alerting:metrics.alert.threshold/observability/rule/getAlertSummary", + "alerting:metrics.alert.threshold/observability/rule/getExecutionLog", + "alerting:metrics.alert.threshold/observability/rule/getActionErrorLog", + "alerting:metrics.alert.threshold/observability/rule/find", + "alerting:metrics.alert.threshold/observability/rule/getRuleExecutionKPI", + "alerting:metrics.alert.threshold/observability/rule/getBackfill", + "alerting:metrics.alert.threshold/observability/rule/findBackfill", + "alerting:metrics.alert.threshold/observability/rule/create", + "alerting:metrics.alert.threshold/observability/rule/delete", + "alerting:metrics.alert.threshold/observability/rule/update", + "alerting:metrics.alert.threshold/observability/rule/updateApiKey", + "alerting:metrics.alert.threshold/observability/rule/enable", + "alerting:metrics.alert.threshold/observability/rule/disable", + "alerting:metrics.alert.threshold/observability/rule/muteAll", + "alerting:metrics.alert.threshold/observability/rule/unmuteAll", + "alerting:metrics.alert.threshold/observability/rule/muteAlert", + "alerting:metrics.alert.threshold/observability/rule/unmuteAlert", + "alerting:metrics.alert.threshold/observability/rule/snooze", + "alerting:metrics.alert.threshold/observability/rule/bulkEdit", + "alerting:metrics.alert.threshold/observability/rule/bulkDelete", + "alerting:metrics.alert.threshold/observability/rule/bulkEnable", + "alerting:metrics.alert.threshold/observability/rule/bulkDisable", + "alerting:metrics.alert.threshold/observability/rule/unsnooze", + "alerting:metrics.alert.threshold/observability/rule/runSoon", + "alerting:metrics.alert.threshold/observability/rule/scheduleBackfill", + "alerting:metrics.alert.threshold/observability/rule/deleteBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/get", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleState", + "alerting:metrics.alert.inventory.threshold/observability/rule/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/rule/getExecutionLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/getActionErrorLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/find", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleExecutionKPI", + "alerting:metrics.alert.inventory.threshold/observability/rule/getBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/findBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/create", + "alerting:metrics.alert.inventory.threshold/observability/rule/delete", + "alerting:metrics.alert.inventory.threshold/observability/rule/update", + "alerting:metrics.alert.inventory.threshold/observability/rule/updateApiKey", + "alerting:metrics.alert.inventory.threshold/observability/rule/enable", + "alerting:metrics.alert.inventory.threshold/observability/rule/disable", + "alerting:metrics.alert.inventory.threshold/observability/rule/muteAll", + "alerting:metrics.alert.inventory.threshold/observability/rule/unmuteAll", + "alerting:metrics.alert.inventory.threshold/observability/rule/muteAlert", + "alerting:metrics.alert.inventory.threshold/observability/rule/unmuteAlert", + "alerting:metrics.alert.inventory.threshold/observability/rule/snooze", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkEdit", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkDelete", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkEnable", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkDisable", + "alerting:metrics.alert.inventory.threshold/observability/rule/unsnooze", + "alerting:metrics.alert.inventory.threshold/observability/rule/runSoon", + "alerting:metrics.alert.inventory.threshold/observability/rule/scheduleBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.tls/observability/rule/get", + "alerting:xpack.uptime.alerts.tls/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.tls/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tls/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tls/observability/rule/find", + "alerting:xpack.uptime.alerts.tls/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tls/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.tls/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.tls/observability/rule/create", + "alerting:xpack.uptime.alerts.tls/observability/rule/delete", + "alerting:xpack.uptime.alerts.tls/observability/rule/update", + "alerting:xpack.uptime.alerts.tls/observability/rule/updateApiKey", + "alerting:xpack.uptime.alerts.tls/observability/rule/enable", + "alerting:xpack.uptime.alerts.tls/observability/rule/disable", + "alerting:xpack.uptime.alerts.tls/observability/rule/muteAll", + "alerting:xpack.uptime.alerts.tls/observability/rule/unmuteAll", + "alerting:xpack.uptime.alerts.tls/observability/rule/muteAlert", + "alerting:xpack.uptime.alerts.tls/observability/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.tls/observability/rule/snooze", + "alerting:xpack.uptime.alerts.tls/observability/rule/bulkEdit", + "alerting:xpack.uptime.alerts.tls/observability/rule/bulkDelete", + "alerting:xpack.uptime.alerts.tls/observability/rule/bulkEnable", + "alerting:xpack.uptime.alerts.tls/observability/rule/bulkDisable", + "alerting:xpack.uptime.alerts.tls/observability/rule/unsnooze", + "alerting:xpack.uptime.alerts.tls/observability/rule/runSoon", + "alerting:xpack.uptime.alerts.tls/observability/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.tls/observability/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.tls/alerts/rule/get", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tls/alerts/rule/find", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.tls/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.tls/alerts/rule/create", + "alerting:xpack.uptime.alerts.tls/alerts/rule/delete", + "alerting:xpack.uptime.alerts.tls/alerts/rule/update", + "alerting:xpack.uptime.alerts.tls/alerts/rule/updateApiKey", + "alerting:xpack.uptime.alerts.tls/alerts/rule/enable", + "alerting:xpack.uptime.alerts.tls/alerts/rule/disable", + "alerting:xpack.uptime.alerts.tls/alerts/rule/muteAll", + "alerting:xpack.uptime.alerts.tls/alerts/rule/unmuteAll", + "alerting:xpack.uptime.alerts.tls/alerts/rule/muteAlert", + "alerting:xpack.uptime.alerts.tls/alerts/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.tls/alerts/rule/snooze", + "alerting:xpack.uptime.alerts.tls/alerts/rule/bulkEdit", + "alerting:xpack.uptime.alerts.tls/alerts/rule/bulkDelete", + "alerting:xpack.uptime.alerts.tls/alerts/rule/bulkEnable", + "alerting:xpack.uptime.alerts.tls/alerts/rule/bulkDisable", + "alerting:xpack.uptime.alerts.tls/alerts/rule/unsnooze", + "alerting:xpack.uptime.alerts.tls/alerts/rule/runSoon", + "alerting:xpack.uptime.alerts.tls/alerts/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.tls/alerts/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/get", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/find", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/create", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/delete", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/update", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/updateApiKey", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/enable", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/disable", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/muteAll", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/unmuteAll", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/muteAlert", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/snooze", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/bulkEdit", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/bulkDelete", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/bulkEnable", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/bulkDisable", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/unsnooze", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/runSoon", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/get", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/find", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/create", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/delete", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/update", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/updateApiKey", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/enable", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/disable", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/muteAll", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/unmuteAll", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/muteAlert", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/snooze", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/bulkEdit", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/bulkDelete", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/bulkEnable", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/bulkDisable", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/unsnooze", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/runSoon", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/get", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/find", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/create", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/delete", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/update", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/updateApiKey", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/enable", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/disable", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/muteAll", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/unmuteAll", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/muteAlert", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/snooze", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/bulkEdit", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/bulkDelete", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/bulkEnable", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/bulkDisable", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/unsnooze", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/runSoon", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/get", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/find", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/create", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/delete", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/update", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/updateApiKey", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/enable", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/disable", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/muteAll", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/unmuteAll", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/muteAlert", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/snooze", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/bulkEdit", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/bulkDelete", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/bulkEnable", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/bulkDisable", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/unsnooze", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/runSoon", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/get", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/find", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/create", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/delete", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/update", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/updateApiKey", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/enable", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/disable", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/muteAll", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/unmuteAll", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/muteAlert", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/snooze", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/bulkEdit", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/bulkDelete", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/bulkEnable", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/bulkDisable", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/unsnooze", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/runSoon", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/get", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/find", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/create", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/delete", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/update", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/updateApiKey", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/enable", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/disable", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/muteAll", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/unmuteAll", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/muteAlert", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/snooze", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/bulkEdit", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/bulkDelete", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/bulkEnable", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/bulkDisable", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/unsnooze", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/runSoon", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/deleteBackfill", + "alerting:logs.alert.document.count/observability/rule/get", + "alerting:logs.alert.document.count/observability/rule/getRuleState", + "alerting:logs.alert.document.count/observability/rule/getAlertSummary", + "alerting:logs.alert.document.count/observability/rule/getExecutionLog", + "alerting:logs.alert.document.count/observability/rule/getActionErrorLog", + "alerting:logs.alert.document.count/observability/rule/find", + "alerting:logs.alert.document.count/observability/rule/getRuleExecutionKPI", + "alerting:logs.alert.document.count/observability/rule/getBackfill", + "alerting:logs.alert.document.count/observability/rule/findBackfill", + "alerting:logs.alert.document.count/observability/rule/create", + "alerting:logs.alert.document.count/observability/rule/delete", + "alerting:logs.alert.document.count/observability/rule/update", + "alerting:logs.alert.document.count/observability/rule/updateApiKey", + "alerting:logs.alert.document.count/observability/rule/enable", + "alerting:logs.alert.document.count/observability/rule/disable", + "alerting:logs.alert.document.count/observability/rule/muteAll", + "alerting:logs.alert.document.count/observability/rule/unmuteAll", + "alerting:logs.alert.document.count/observability/rule/muteAlert", + "alerting:logs.alert.document.count/observability/rule/unmuteAlert", + "alerting:logs.alert.document.count/observability/rule/snooze", + "alerting:logs.alert.document.count/observability/rule/bulkEdit", + "alerting:logs.alert.document.count/observability/rule/bulkDelete", + "alerting:logs.alert.document.count/observability/rule/bulkEnable", + "alerting:logs.alert.document.count/observability/rule/bulkDisable", + "alerting:logs.alert.document.count/observability/rule/unsnooze", + "alerting:logs.alert.document.count/observability/rule/runSoon", + "alerting:logs.alert.document.count/observability/rule/scheduleBackfill", + "alerting:logs.alert.document.count/observability/rule/deleteBackfill", + "alerting:slo.rules.burnRate/observability/rule/get", + "alerting:slo.rules.burnRate/observability/rule/getRuleState", + "alerting:slo.rules.burnRate/observability/rule/getAlertSummary", + "alerting:slo.rules.burnRate/observability/rule/getExecutionLog", + "alerting:slo.rules.burnRate/observability/rule/getActionErrorLog", + "alerting:slo.rules.burnRate/observability/rule/find", + "alerting:slo.rules.burnRate/observability/rule/getRuleExecutionKPI", + "alerting:slo.rules.burnRate/observability/rule/getBackfill", + "alerting:slo.rules.burnRate/observability/rule/findBackfill", + "alerting:slo.rules.burnRate/observability/rule/create", + "alerting:slo.rules.burnRate/observability/rule/delete", + "alerting:slo.rules.burnRate/observability/rule/update", + "alerting:slo.rules.burnRate/observability/rule/updateApiKey", + "alerting:slo.rules.burnRate/observability/rule/enable", + "alerting:slo.rules.burnRate/observability/rule/disable", + "alerting:slo.rules.burnRate/observability/rule/muteAll", + "alerting:slo.rules.burnRate/observability/rule/unmuteAll", + "alerting:slo.rules.burnRate/observability/rule/muteAlert", + "alerting:slo.rules.burnRate/observability/rule/unmuteAlert", + "alerting:slo.rules.burnRate/observability/rule/snooze", + "alerting:slo.rules.burnRate/observability/rule/bulkEdit", + "alerting:slo.rules.burnRate/observability/rule/bulkDelete", + "alerting:slo.rules.burnRate/observability/rule/bulkEnable", + "alerting:slo.rules.burnRate/observability/rule/bulkDisable", + "alerting:slo.rules.burnRate/observability/rule/unsnooze", + "alerting:slo.rules.burnRate/observability/rule/runSoon", + "alerting:slo.rules.burnRate/observability/rule/scheduleBackfill", + "alerting:slo.rules.burnRate/observability/rule/deleteBackfill", + "alerting:slo.rules.burnRate/alerts/rule/get", + "alerting:slo.rules.burnRate/alerts/rule/getRuleState", + "alerting:slo.rules.burnRate/alerts/rule/getAlertSummary", + "alerting:slo.rules.burnRate/alerts/rule/getExecutionLog", + "alerting:slo.rules.burnRate/alerts/rule/getActionErrorLog", + "alerting:slo.rules.burnRate/alerts/rule/find", + "alerting:slo.rules.burnRate/alerts/rule/getRuleExecutionKPI", + "alerting:slo.rules.burnRate/alerts/rule/getBackfill", + "alerting:slo.rules.burnRate/alerts/rule/findBackfill", + "alerting:slo.rules.burnRate/alerts/rule/create", + "alerting:slo.rules.burnRate/alerts/rule/delete", + "alerting:slo.rules.burnRate/alerts/rule/update", + "alerting:slo.rules.burnRate/alerts/rule/updateApiKey", + "alerting:slo.rules.burnRate/alerts/rule/enable", + "alerting:slo.rules.burnRate/alerts/rule/disable", + "alerting:slo.rules.burnRate/alerts/rule/muteAll", + "alerting:slo.rules.burnRate/alerts/rule/unmuteAll", + "alerting:slo.rules.burnRate/alerts/rule/muteAlert", + "alerting:slo.rules.burnRate/alerts/rule/unmuteAlert", + "alerting:slo.rules.burnRate/alerts/rule/snooze", + "alerting:slo.rules.burnRate/alerts/rule/bulkEdit", + "alerting:slo.rules.burnRate/alerts/rule/bulkDelete", + "alerting:slo.rules.burnRate/alerts/rule/bulkEnable", + "alerting:slo.rules.burnRate/alerts/rule/bulkDisable", + "alerting:slo.rules.burnRate/alerts/rule/unsnooze", + "alerting:slo.rules.burnRate/alerts/rule/runSoon", + "alerting:slo.rules.burnRate/alerts/rule/scheduleBackfill", + "alerting:slo.rules.burnRate/alerts/rule/deleteBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/get", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleState", + "alerting:observability.rules.custom_threshold/observability/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/observability/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/observability/rule/find", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/observability/rule/getBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/findBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/create", + "alerting:observability.rules.custom_threshold/observability/rule/delete", + "alerting:observability.rules.custom_threshold/observability/rule/update", + "alerting:observability.rules.custom_threshold/observability/rule/updateApiKey", + "alerting:observability.rules.custom_threshold/observability/rule/enable", + "alerting:observability.rules.custom_threshold/observability/rule/disable", + "alerting:observability.rules.custom_threshold/observability/rule/muteAll", + "alerting:observability.rules.custom_threshold/observability/rule/unmuteAll", + "alerting:observability.rules.custom_threshold/observability/rule/muteAlert", + "alerting:observability.rules.custom_threshold/observability/rule/unmuteAlert", + "alerting:observability.rules.custom_threshold/observability/rule/snooze", + "alerting:observability.rules.custom_threshold/observability/rule/bulkEdit", + "alerting:observability.rules.custom_threshold/observability/rule/bulkDelete", + "alerting:observability.rules.custom_threshold/observability/rule/bulkEnable", + "alerting:observability.rules.custom_threshold/observability/rule/bulkDisable", + "alerting:observability.rules.custom_threshold/observability/rule/unsnooze", + "alerting:observability.rules.custom_threshold/observability/rule/runSoon", + "alerting:observability.rules.custom_threshold/observability/rule/scheduleBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/deleteBackfill", + "alerting:.es-query/observability/rule/get", + "alerting:.es-query/observability/rule/getRuleState", + "alerting:.es-query/observability/rule/getAlertSummary", + "alerting:.es-query/observability/rule/getExecutionLog", + "alerting:.es-query/observability/rule/getActionErrorLog", + "alerting:.es-query/observability/rule/find", + "alerting:.es-query/observability/rule/getRuleExecutionKPI", + "alerting:.es-query/observability/rule/getBackfill", + "alerting:.es-query/observability/rule/findBackfill", + "alerting:.es-query/observability/rule/create", + "alerting:.es-query/observability/rule/delete", + "alerting:.es-query/observability/rule/update", + "alerting:.es-query/observability/rule/updateApiKey", + "alerting:.es-query/observability/rule/enable", + "alerting:.es-query/observability/rule/disable", + "alerting:.es-query/observability/rule/muteAll", + "alerting:.es-query/observability/rule/unmuteAll", + "alerting:.es-query/observability/rule/muteAlert", + "alerting:.es-query/observability/rule/unmuteAlert", + "alerting:.es-query/observability/rule/snooze", + "alerting:.es-query/observability/rule/bulkEdit", + "alerting:.es-query/observability/rule/bulkDelete", + "alerting:.es-query/observability/rule/bulkEnable", + "alerting:.es-query/observability/rule/bulkDisable", + "alerting:.es-query/observability/rule/unsnooze", + "alerting:.es-query/observability/rule/runSoon", + "alerting:.es-query/observability/rule/scheduleBackfill", + "alerting:.es-query/observability/rule/deleteBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/create", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/delete", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/update", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/updateApiKey", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/enable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/disable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/muteAll", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unmuteAll", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/muteAlert", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unmuteAlert", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/snooze", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkEdit", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkDelete", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkEnable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkDisable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unsnooze", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/runSoon", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/scheduleBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/deleteBackfill", "alerting:apm.error_rate/observability/alert/get", "alerting:apm.error_rate/observability/alert/find", "alerting:apm.error_rate/observability/alert/getAuthorizedAlertsIndices", "alerting:apm.error_rate/observability/alert/getAlertSummary", "alerting:apm.error_rate/observability/alert/update", + "alerting:apm.error_rate/alerts/alert/get", + "alerting:apm.error_rate/alerts/alert/find", + "alerting:apm.error_rate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.error_rate/alerts/alert/getAlertSummary", + "alerting:apm.error_rate/alerts/alert/update", "alerting:apm.transaction_error_rate/observability/alert/get", "alerting:apm.transaction_error_rate/observability/alert/find", "alerting:apm.transaction_error_rate/observability/alert/getAuthorizedAlertsIndices", "alerting:apm.transaction_error_rate/observability/alert/getAlertSummary", "alerting:apm.transaction_error_rate/observability/alert/update", + "alerting:apm.transaction_error_rate/alerts/alert/get", + "alerting:apm.transaction_error_rate/alerts/alert/find", + "alerting:apm.transaction_error_rate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_error_rate/alerts/alert/getAlertSummary", + "alerting:apm.transaction_error_rate/alerts/alert/update", "alerting:apm.transaction_duration/observability/alert/get", "alerting:apm.transaction_duration/observability/alert/find", "alerting:apm.transaction_duration/observability/alert/getAuthorizedAlertsIndices", "alerting:apm.transaction_duration/observability/alert/getAlertSummary", "alerting:apm.transaction_duration/observability/alert/update", + "alerting:apm.transaction_duration/alerts/alert/get", + "alerting:apm.transaction_duration/alerts/alert/find", + "alerting:apm.transaction_duration/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_duration/alerts/alert/getAlertSummary", + "alerting:apm.transaction_duration/alerts/alert/update", "alerting:apm.anomaly/observability/alert/get", "alerting:apm.anomaly/observability/alert/find", "alerting:apm.anomaly/observability/alert/getAuthorizedAlertsIndices", "alerting:apm.anomaly/observability/alert/getAlertSummary", "alerting:apm.anomaly/observability/alert/update", + "alerting:apm.anomaly/alerts/alert/get", + "alerting:apm.anomaly/alerts/alert/find", + "alerting:apm.anomaly/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.anomaly/alerts/alert/getAlertSummary", + "alerting:apm.anomaly/alerts/alert/update", "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/get", "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/find", "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/getAuthorizedAlertsIndices", "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/getAlertSummary", "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/update", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/get", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/find", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/getAlertSummary", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/update", "alerting:xpack.synthetics.alerts.tls/observability/alert/get", "alerting:xpack.synthetics.alerts.tls/observability/alert/find", "alerting:xpack.synthetics.alerts.tls/observability/alert/getAuthorizedAlertsIndices", "alerting:xpack.synthetics.alerts.tls/observability/alert/getAlertSummary", "alerting:xpack.synthetics.alerts.tls/observability/alert/update", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/get", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/find", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/getAlertSummary", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/update", + "alerting:metrics.alert.threshold/observability/alert/get", + "alerting:metrics.alert.threshold/observability/alert/find", + "alerting:metrics.alert.threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.threshold/observability/alert/getAlertSummary", + "alerting:metrics.alert.threshold/observability/alert/update", + "alerting:metrics.alert.inventory.threshold/observability/alert/get", + "alerting:metrics.alert.inventory.threshold/observability/alert/find", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/alert/update", + "alerting:xpack.uptime.alerts.tls/observability/alert/get", + "alerting:xpack.uptime.alerts.tls/observability/alert/find", + "alerting:xpack.uptime.alerts.tls/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tls/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/observability/alert/update", + "alerting:xpack.uptime.alerts.tls/alerts/alert/get", + "alerting:xpack.uptime.alerts.tls/alerts/alert/find", + "alerting:xpack.uptime.alerts.tls/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tls/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/alerts/alert/update", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/get", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/find", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/update", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/get", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/find", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/update", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/get", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/find", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/update", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/get", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/find", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/update", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/get", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/find", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/update", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/get", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/find", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/update", + "alerting:logs.alert.document.count/observability/alert/get", + "alerting:logs.alert.document.count/observability/alert/find", + "alerting:logs.alert.document.count/observability/alert/getAuthorizedAlertsIndices", + "alerting:logs.alert.document.count/observability/alert/getAlertSummary", + "alerting:logs.alert.document.count/observability/alert/update", + "alerting:slo.rules.burnRate/observability/alert/get", + "alerting:slo.rules.burnRate/observability/alert/find", + "alerting:slo.rules.burnRate/observability/alert/getAuthorizedAlertsIndices", + "alerting:slo.rules.burnRate/observability/alert/getAlertSummary", + "alerting:slo.rules.burnRate/observability/alert/update", + "alerting:slo.rules.burnRate/alerts/alert/get", + "alerting:slo.rules.burnRate/alerts/alert/find", + "alerting:slo.rules.burnRate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:slo.rules.burnRate/alerts/alert/getAlertSummary", + "alerting:slo.rules.burnRate/alerts/alert/update", + "alerting:observability.rules.custom_threshold/observability/alert/get", + "alerting:observability.rules.custom_threshold/observability/alert/find", + "alerting:observability.rules.custom_threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/observability/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/alert/update", + "alerting:.es-query/observability/alert/get", + "alerting:.es-query/observability/alert/find", + "alerting:.es-query/observability/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/observability/alert/getAlertSummary", + "alerting:.es-query/observability/alert/update", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/update", ], "minimal_read": Array [ "login:", @@ -6630,6 +12749,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:metrics.alert.threshold/infrastructure/rule/getRuleExecutionKPI", "alerting:metrics.alert.threshold/infrastructure/rule/getBackfill", "alerting:metrics.alert.threshold/infrastructure/rule/findBackfill", + "alerting:metrics.alert.threshold/alerts/rule/get", + "alerting:metrics.alert.threshold/alerts/rule/getRuleState", + "alerting:metrics.alert.threshold/alerts/rule/getAlertSummary", + "alerting:metrics.alert.threshold/alerts/rule/getExecutionLog", + "alerting:metrics.alert.threshold/alerts/rule/getActionErrorLog", + "alerting:metrics.alert.threshold/alerts/rule/find", + "alerting:metrics.alert.threshold/alerts/rule/getRuleExecutionKPI", + "alerting:metrics.alert.threshold/alerts/rule/getBackfill", + "alerting:metrics.alert.threshold/alerts/rule/findBackfill", "alerting:metrics.alert.inventory.threshold/infrastructure/rule/get", "alerting:metrics.alert.inventory.threshold/infrastructure/rule/getRuleState", "alerting:metrics.alert.inventory.threshold/infrastructure/rule/getAlertSummary", @@ -6639,6 +12767,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:metrics.alert.inventory.threshold/infrastructure/rule/getRuleExecutionKPI", "alerting:metrics.alert.inventory.threshold/infrastructure/rule/getBackfill", "alerting:metrics.alert.inventory.threshold/infrastructure/rule/findBackfill", + "alerting:metrics.alert.inventory.threshold/alerts/rule/get", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getRuleState", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getExecutionLog", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getActionErrorLog", + "alerting:metrics.alert.inventory.threshold/alerts/rule/find", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getRuleExecutionKPI", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getBackfill", + "alerting:metrics.alert.inventory.threshold/alerts/rule/findBackfill", "alerting:.es-query/infrastructure/rule/get", "alerting:.es-query/infrastructure/rule/getRuleState", "alerting:.es-query/infrastructure/rule/getAlertSummary", @@ -6648,6 +12785,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:.es-query/infrastructure/rule/getRuleExecutionKPI", "alerting:.es-query/infrastructure/rule/getBackfill", "alerting:.es-query/infrastructure/rule/findBackfill", + "alerting:.es-query/alerts/rule/get", + "alerting:.es-query/alerts/rule/getRuleState", + "alerting:.es-query/alerts/rule/getAlertSummary", + "alerting:.es-query/alerts/rule/getExecutionLog", + "alerting:.es-query/alerts/rule/getActionErrorLog", + "alerting:.es-query/alerts/rule/find", + "alerting:.es-query/alerts/rule/getRuleExecutionKPI", + "alerting:.es-query/alerts/rule/getBackfill", + "alerting:.es-query/alerts/rule/findBackfill", "alerting:observability.rules.custom_threshold/infrastructure/rule/get", "alerting:observability.rules.custom_threshold/infrastructure/rule/getRuleState", "alerting:observability.rules.custom_threshold/infrastructure/rule/getAlertSummary", @@ -6657,6 +12803,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:observability.rules.custom_threshold/infrastructure/rule/getRuleExecutionKPI", "alerting:observability.rules.custom_threshold/infrastructure/rule/getBackfill", "alerting:observability.rules.custom_threshold/infrastructure/rule/findBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/get", + "alerting:observability.rules.custom_threshold/alerts/rule/getRuleState", + "alerting:observability.rules.custom_threshold/alerts/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/alerts/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/alerts/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/alerts/rule/find", + "alerting:observability.rules.custom_threshold/alerts/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/alerts/rule/getBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/findBackfill", "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/get", "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/getRuleState", "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/getAlertSummary", @@ -6666,26 +12821,55 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/getRuleExecutionKPI", "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/getBackfill", "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/findBackfill", "alerting:metrics.alert.threshold/infrastructure/alert/get", "alerting:metrics.alert.threshold/infrastructure/alert/find", "alerting:metrics.alert.threshold/infrastructure/alert/getAuthorizedAlertsIndices", "alerting:metrics.alert.threshold/infrastructure/alert/getAlertSummary", + "alerting:metrics.alert.threshold/alerts/alert/get", + "alerting:metrics.alert.threshold/alerts/alert/find", + "alerting:metrics.alert.threshold/alerts/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.threshold/alerts/alert/getAlertSummary", "alerting:metrics.alert.inventory.threshold/infrastructure/alert/get", "alerting:metrics.alert.inventory.threshold/infrastructure/alert/find", "alerting:metrics.alert.inventory.threshold/infrastructure/alert/getAuthorizedAlertsIndices", "alerting:metrics.alert.inventory.threshold/infrastructure/alert/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/alerts/alert/get", + "alerting:metrics.alert.inventory.threshold/alerts/alert/find", + "alerting:metrics.alert.inventory.threshold/alerts/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.inventory.threshold/alerts/alert/getAlertSummary", "alerting:.es-query/infrastructure/alert/get", "alerting:.es-query/infrastructure/alert/find", "alerting:.es-query/infrastructure/alert/getAuthorizedAlertsIndices", "alerting:.es-query/infrastructure/alert/getAlertSummary", + "alerting:.es-query/alerts/alert/get", + "alerting:.es-query/alerts/alert/find", + "alerting:.es-query/alerts/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/alerts/alert/getAlertSummary", "alerting:observability.rules.custom_threshold/infrastructure/alert/get", "alerting:observability.rules.custom_threshold/infrastructure/alert/find", "alerting:observability.rules.custom_threshold/infrastructure/alert/getAuthorizedAlertsIndices", "alerting:observability.rules.custom_threshold/infrastructure/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/alerts/alert/get", + "alerting:observability.rules.custom_threshold/alerts/alert/find", + "alerting:observability.rules.custom_threshold/alerts/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/alerts/alert/getAlertSummary", "alerting:xpack.ml.anomaly_detection_alert/infrastructure/alert/get", "alerting:xpack.ml.anomaly_detection_alert/infrastructure/alert/find", "alerting:xpack.ml.anomaly_detection_alert/infrastructure/alert/getAuthorizedAlertsIndices", "alerting:xpack.ml.anomaly_detection_alert/infrastructure/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/getAlertSummary", "app:logs", "app:observability-logs-explorer", "ui:catalogue/infralogging", @@ -6707,6 +12891,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:logs.alert.document.count/logs/rule/getRuleExecutionKPI", "alerting:logs.alert.document.count/logs/rule/getBackfill", "alerting:logs.alert.document.count/logs/rule/findBackfill", + "alerting:logs.alert.document.count/alerts/rule/get", + "alerting:logs.alert.document.count/alerts/rule/getRuleState", + "alerting:logs.alert.document.count/alerts/rule/getAlertSummary", + "alerting:logs.alert.document.count/alerts/rule/getExecutionLog", + "alerting:logs.alert.document.count/alerts/rule/getActionErrorLog", + "alerting:logs.alert.document.count/alerts/rule/find", + "alerting:logs.alert.document.count/alerts/rule/getRuleExecutionKPI", + "alerting:logs.alert.document.count/alerts/rule/getBackfill", + "alerting:logs.alert.document.count/alerts/rule/findBackfill", "alerting:.es-query/logs/rule/get", "alerting:.es-query/logs/rule/getRuleState", "alerting:.es-query/logs/rule/getAlertSummary", @@ -6738,6 +12931,10 @@ export default function ({ getService }: FtrProviderContext) { "alerting:logs.alert.document.count/logs/alert/find", "alerting:logs.alert.document.count/logs/alert/getAuthorizedAlertsIndices", "alerting:logs.alert.document.count/logs/alert/getAlertSummary", + "alerting:logs.alert.document.count/alerts/alert/get", + "alerting:logs.alert.document.count/alerts/alert/find", + "alerting:logs.alert.document.count/alerts/alert/getAuthorizedAlertsIndices", + "alerting:logs.alert.document.count/alerts/alert/getAlertSummary", "alerting:.es-query/logs/alert/get", "alerting:.es-query/logs/alert/find", "alerting:.es-query/logs/alert/getAuthorizedAlertsIndices", @@ -6754,51 +12951,6 @@ export default function ({ getService }: FtrProviderContext) { "ui:catalogue/observability", "ui:navLinks/observability", "ui:observability/read", - "alerting:slo.rules.burnRate/observability/rule/get", - "alerting:slo.rules.burnRate/observability/rule/getRuleState", - "alerting:slo.rules.burnRate/observability/rule/getAlertSummary", - "alerting:slo.rules.burnRate/observability/rule/getExecutionLog", - "alerting:slo.rules.burnRate/observability/rule/getActionErrorLog", - "alerting:slo.rules.burnRate/observability/rule/find", - "alerting:slo.rules.burnRate/observability/rule/getRuleExecutionKPI", - "alerting:slo.rules.burnRate/observability/rule/getBackfill", - "alerting:slo.rules.burnRate/observability/rule/findBackfill", - "alerting:observability.rules.custom_threshold/observability/rule/get", - "alerting:observability.rules.custom_threshold/observability/rule/getRuleState", - "alerting:observability.rules.custom_threshold/observability/rule/getAlertSummary", - "alerting:observability.rules.custom_threshold/observability/rule/getExecutionLog", - "alerting:observability.rules.custom_threshold/observability/rule/getActionErrorLog", - "alerting:observability.rules.custom_threshold/observability/rule/find", - "alerting:observability.rules.custom_threshold/observability/rule/getRuleExecutionKPI", - "alerting:observability.rules.custom_threshold/observability/rule/getBackfill", - "alerting:observability.rules.custom_threshold/observability/rule/findBackfill", - "alerting:.es-query/observability/rule/get", - "alerting:.es-query/observability/rule/getRuleState", - "alerting:.es-query/observability/rule/getAlertSummary", - "alerting:.es-query/observability/rule/getExecutionLog", - "alerting:.es-query/observability/rule/getActionErrorLog", - "alerting:.es-query/observability/rule/find", - "alerting:.es-query/observability/rule/getRuleExecutionKPI", - "alerting:.es-query/observability/rule/getBackfill", - "alerting:.es-query/observability/rule/findBackfill", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/get", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleState", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getAlertSummary", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getExecutionLog", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getActionErrorLog", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/find", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleExecutionKPI", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getBackfill", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/findBackfill", - "alerting:metrics.alert.inventory.threshold/observability/rule/get", - "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleState", - "alerting:metrics.alert.inventory.threshold/observability/rule/getAlertSummary", - "alerting:metrics.alert.inventory.threshold/observability/rule/getExecutionLog", - "alerting:metrics.alert.inventory.threshold/observability/rule/getActionErrorLog", - "alerting:metrics.alert.inventory.threshold/observability/rule/find", - "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleExecutionKPI", - "alerting:metrics.alert.inventory.threshold/observability/rule/getBackfill", - "alerting:metrics.alert.inventory.threshold/observability/rule/findBackfill", "alerting:apm.error_rate/observability/rule/get", "alerting:apm.error_rate/observability/rule/getRuleState", "alerting:apm.error_rate/observability/rule/getAlertSummary", @@ -6808,6 +12960,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.error_rate/observability/rule/getRuleExecutionKPI", "alerting:apm.error_rate/observability/rule/getBackfill", "alerting:apm.error_rate/observability/rule/findBackfill", + "alerting:apm.error_rate/alerts/rule/get", + "alerting:apm.error_rate/alerts/rule/getRuleState", + "alerting:apm.error_rate/alerts/rule/getAlertSummary", + "alerting:apm.error_rate/alerts/rule/getExecutionLog", + "alerting:apm.error_rate/alerts/rule/getActionErrorLog", + "alerting:apm.error_rate/alerts/rule/find", + "alerting:apm.error_rate/alerts/rule/getRuleExecutionKPI", + "alerting:apm.error_rate/alerts/rule/getBackfill", + "alerting:apm.error_rate/alerts/rule/findBackfill", "alerting:apm.transaction_error_rate/observability/rule/get", "alerting:apm.transaction_error_rate/observability/rule/getRuleState", "alerting:apm.transaction_error_rate/observability/rule/getAlertSummary", @@ -6817,6 +12978,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.transaction_error_rate/observability/rule/getRuleExecutionKPI", "alerting:apm.transaction_error_rate/observability/rule/getBackfill", "alerting:apm.transaction_error_rate/observability/rule/findBackfill", + "alerting:apm.transaction_error_rate/alerts/rule/get", + "alerting:apm.transaction_error_rate/alerts/rule/getRuleState", + "alerting:apm.transaction_error_rate/alerts/rule/getAlertSummary", + "alerting:apm.transaction_error_rate/alerts/rule/getExecutionLog", + "alerting:apm.transaction_error_rate/alerts/rule/getActionErrorLog", + "alerting:apm.transaction_error_rate/alerts/rule/find", + "alerting:apm.transaction_error_rate/alerts/rule/getRuleExecutionKPI", + "alerting:apm.transaction_error_rate/alerts/rule/getBackfill", + "alerting:apm.transaction_error_rate/alerts/rule/findBackfill", "alerting:apm.transaction_duration/observability/rule/get", "alerting:apm.transaction_duration/observability/rule/getRuleState", "alerting:apm.transaction_duration/observability/rule/getAlertSummary", @@ -6826,6 +12996,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.transaction_duration/observability/rule/getRuleExecutionKPI", "alerting:apm.transaction_duration/observability/rule/getBackfill", "alerting:apm.transaction_duration/observability/rule/findBackfill", + "alerting:apm.transaction_duration/alerts/rule/get", + "alerting:apm.transaction_duration/alerts/rule/getRuleState", + "alerting:apm.transaction_duration/alerts/rule/getAlertSummary", + "alerting:apm.transaction_duration/alerts/rule/getExecutionLog", + "alerting:apm.transaction_duration/alerts/rule/getActionErrorLog", + "alerting:apm.transaction_duration/alerts/rule/find", + "alerting:apm.transaction_duration/alerts/rule/getRuleExecutionKPI", + "alerting:apm.transaction_duration/alerts/rule/getBackfill", + "alerting:apm.transaction_duration/alerts/rule/findBackfill", "alerting:apm.anomaly/observability/rule/get", "alerting:apm.anomaly/observability/rule/getRuleState", "alerting:apm.anomaly/observability/rule/getAlertSummary", @@ -6835,6 +13014,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.anomaly/observability/rule/getRuleExecutionKPI", "alerting:apm.anomaly/observability/rule/getBackfill", "alerting:apm.anomaly/observability/rule/findBackfill", + "alerting:apm.anomaly/alerts/rule/get", + "alerting:apm.anomaly/alerts/rule/getRuleState", + "alerting:apm.anomaly/alerts/rule/getAlertSummary", + "alerting:apm.anomaly/alerts/rule/getExecutionLog", + "alerting:apm.anomaly/alerts/rule/getActionErrorLog", + "alerting:apm.anomaly/alerts/rule/find", + "alerting:apm.anomaly/alerts/rule/getRuleExecutionKPI", + "alerting:apm.anomaly/alerts/rule/getBackfill", + "alerting:apm.anomaly/alerts/rule/findBackfill", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/get", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/getRuleState", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/getAlertSummary", @@ -6844,6 +13032,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/getRuleExecutionKPI", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/getBackfill", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/findBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/get", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getRuleState", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getAlertSummary", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getExecutionLog", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getActionErrorLog", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/find", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/findBackfill", "alerting:xpack.synthetics.alerts.tls/observability/rule/get", "alerting:xpack.synthetics.alerts.tls/observability/rule/getRuleState", "alerting:xpack.synthetics.alerts.tls/observability/rule/getAlertSummary", @@ -6853,50 +13050,271 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.synthetics.alerts.tls/observability/rule/getRuleExecutionKPI", "alerting:xpack.synthetics.alerts.tls/observability/rule/getBackfill", "alerting:xpack.synthetics.alerts.tls/observability/rule/findBackfill", - "alerting:slo.rules.burnRate/observability/alert/get", - "alerting:slo.rules.burnRate/observability/alert/find", - "alerting:slo.rules.burnRate/observability/alert/getAuthorizedAlertsIndices", - "alerting:slo.rules.burnRate/observability/alert/getAlertSummary", - "alerting:observability.rules.custom_threshold/observability/alert/get", - "alerting:observability.rules.custom_threshold/observability/alert/find", - "alerting:observability.rules.custom_threshold/observability/alert/getAuthorizedAlertsIndices", - "alerting:observability.rules.custom_threshold/observability/alert/getAlertSummary", - "alerting:.es-query/observability/alert/get", - "alerting:.es-query/observability/alert/find", - "alerting:.es-query/observability/alert/getAuthorizedAlertsIndices", - "alerting:.es-query/observability/alert/getAlertSummary", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/get", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/find", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAuthorizedAlertsIndices", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAlertSummary", - "alerting:metrics.alert.inventory.threshold/observability/alert/get", - "alerting:metrics.alert.inventory.threshold/observability/alert/find", - "alerting:metrics.alert.inventory.threshold/observability/alert/getAuthorizedAlertsIndices", - "alerting:metrics.alert.inventory.threshold/observability/alert/getAlertSummary", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/get", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getRuleState", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getAlertSummary", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getExecutionLog", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getActionErrorLog", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/find", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getBackfill", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/findBackfill", + "alerting:metrics.alert.threshold/observability/rule/get", + "alerting:metrics.alert.threshold/observability/rule/getRuleState", + "alerting:metrics.alert.threshold/observability/rule/getAlertSummary", + "alerting:metrics.alert.threshold/observability/rule/getExecutionLog", + "alerting:metrics.alert.threshold/observability/rule/getActionErrorLog", + "alerting:metrics.alert.threshold/observability/rule/find", + "alerting:metrics.alert.threshold/observability/rule/getRuleExecutionKPI", + "alerting:metrics.alert.threshold/observability/rule/getBackfill", + "alerting:metrics.alert.threshold/observability/rule/findBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/get", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleState", + "alerting:metrics.alert.inventory.threshold/observability/rule/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/rule/getExecutionLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/getActionErrorLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/find", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleExecutionKPI", + "alerting:metrics.alert.inventory.threshold/observability/rule/getBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.tls/observability/rule/get", + "alerting:xpack.uptime.alerts.tls/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.tls/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tls/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tls/observability/rule/find", + "alerting:xpack.uptime.alerts.tls/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tls/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.tls/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.tls/alerts/rule/get", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tls/alerts/rule/find", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.tls/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/get", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/find", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/get", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/find", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/get", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/find", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/get", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/find", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/get", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/find", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/get", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/find", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/findBackfill", + "alerting:logs.alert.document.count/observability/rule/get", + "alerting:logs.alert.document.count/observability/rule/getRuleState", + "alerting:logs.alert.document.count/observability/rule/getAlertSummary", + "alerting:logs.alert.document.count/observability/rule/getExecutionLog", + "alerting:logs.alert.document.count/observability/rule/getActionErrorLog", + "alerting:logs.alert.document.count/observability/rule/find", + "alerting:logs.alert.document.count/observability/rule/getRuleExecutionKPI", + "alerting:logs.alert.document.count/observability/rule/getBackfill", + "alerting:logs.alert.document.count/observability/rule/findBackfill", + "alerting:slo.rules.burnRate/observability/rule/get", + "alerting:slo.rules.burnRate/observability/rule/getRuleState", + "alerting:slo.rules.burnRate/observability/rule/getAlertSummary", + "alerting:slo.rules.burnRate/observability/rule/getExecutionLog", + "alerting:slo.rules.burnRate/observability/rule/getActionErrorLog", + "alerting:slo.rules.burnRate/observability/rule/find", + "alerting:slo.rules.burnRate/observability/rule/getRuleExecutionKPI", + "alerting:slo.rules.burnRate/observability/rule/getBackfill", + "alerting:slo.rules.burnRate/observability/rule/findBackfill", + "alerting:slo.rules.burnRate/alerts/rule/get", + "alerting:slo.rules.burnRate/alerts/rule/getRuleState", + "alerting:slo.rules.burnRate/alerts/rule/getAlertSummary", + "alerting:slo.rules.burnRate/alerts/rule/getExecutionLog", + "alerting:slo.rules.burnRate/alerts/rule/getActionErrorLog", + "alerting:slo.rules.burnRate/alerts/rule/find", + "alerting:slo.rules.burnRate/alerts/rule/getRuleExecutionKPI", + "alerting:slo.rules.burnRate/alerts/rule/getBackfill", + "alerting:slo.rules.burnRate/alerts/rule/findBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/get", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleState", + "alerting:observability.rules.custom_threshold/observability/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/observability/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/observability/rule/find", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/observability/rule/getBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/findBackfill", + "alerting:.es-query/observability/rule/get", + "alerting:.es-query/observability/rule/getRuleState", + "alerting:.es-query/observability/rule/getAlertSummary", + "alerting:.es-query/observability/rule/getExecutionLog", + "alerting:.es-query/observability/rule/getActionErrorLog", + "alerting:.es-query/observability/rule/find", + "alerting:.es-query/observability/rule/getRuleExecutionKPI", + "alerting:.es-query/observability/rule/getBackfill", + "alerting:.es-query/observability/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/findBackfill", "alerting:apm.error_rate/observability/alert/get", "alerting:apm.error_rate/observability/alert/find", "alerting:apm.error_rate/observability/alert/getAuthorizedAlertsIndices", "alerting:apm.error_rate/observability/alert/getAlertSummary", + "alerting:apm.error_rate/alerts/alert/get", + "alerting:apm.error_rate/alerts/alert/find", + "alerting:apm.error_rate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.error_rate/alerts/alert/getAlertSummary", "alerting:apm.transaction_error_rate/observability/alert/get", "alerting:apm.transaction_error_rate/observability/alert/find", "alerting:apm.transaction_error_rate/observability/alert/getAuthorizedAlertsIndices", "alerting:apm.transaction_error_rate/observability/alert/getAlertSummary", + "alerting:apm.transaction_error_rate/alerts/alert/get", + "alerting:apm.transaction_error_rate/alerts/alert/find", + "alerting:apm.transaction_error_rate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_error_rate/alerts/alert/getAlertSummary", "alerting:apm.transaction_duration/observability/alert/get", "alerting:apm.transaction_duration/observability/alert/find", "alerting:apm.transaction_duration/observability/alert/getAuthorizedAlertsIndices", "alerting:apm.transaction_duration/observability/alert/getAlertSummary", + "alerting:apm.transaction_duration/alerts/alert/get", + "alerting:apm.transaction_duration/alerts/alert/find", + "alerting:apm.transaction_duration/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_duration/alerts/alert/getAlertSummary", "alerting:apm.anomaly/observability/alert/get", "alerting:apm.anomaly/observability/alert/find", "alerting:apm.anomaly/observability/alert/getAuthorizedAlertsIndices", "alerting:apm.anomaly/observability/alert/getAlertSummary", + "alerting:apm.anomaly/alerts/alert/get", + "alerting:apm.anomaly/alerts/alert/find", + "alerting:apm.anomaly/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.anomaly/alerts/alert/getAlertSummary", "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/get", "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/find", "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/getAuthorizedAlertsIndices", "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/getAlertSummary", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/get", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/find", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/getAlertSummary", "alerting:xpack.synthetics.alerts.tls/observability/alert/get", "alerting:xpack.synthetics.alerts.tls/observability/alert/find", "alerting:xpack.synthetics.alerts.tls/observability/alert/getAuthorizedAlertsIndices", "alerting:xpack.synthetics.alerts.tls/observability/alert/getAlertSummary", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/get", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/find", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/getAlertSummary", + "alerting:metrics.alert.threshold/observability/alert/get", + "alerting:metrics.alert.threshold/observability/alert/find", + "alerting:metrics.alert.threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.threshold/observability/alert/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/alert/get", + "alerting:metrics.alert.inventory.threshold/observability/alert/find", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/observability/alert/get", + "alerting:xpack.uptime.alerts.tls/observability/alert/find", + "alerting:xpack.uptime.alerts.tls/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tls/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/alerts/alert/get", + "alerting:xpack.uptime.alerts.tls/alerts/alert/find", + "alerting:xpack.uptime.alerts.tls/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tls/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/get", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/find", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/get", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/find", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/get", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/find", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/get", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/find", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/get", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/find", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/get", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/find", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/getAlertSummary", + "alerting:logs.alert.document.count/observability/alert/get", + "alerting:logs.alert.document.count/observability/alert/find", + "alerting:logs.alert.document.count/observability/alert/getAuthorizedAlertsIndices", + "alerting:logs.alert.document.count/observability/alert/getAlertSummary", + "alerting:slo.rules.burnRate/observability/alert/get", + "alerting:slo.rules.burnRate/observability/alert/find", + "alerting:slo.rules.burnRate/observability/alert/getAuthorizedAlertsIndices", + "alerting:slo.rules.burnRate/observability/alert/getAlertSummary", + "alerting:slo.rules.burnRate/alerts/alert/get", + "alerting:slo.rules.burnRate/alerts/alert/find", + "alerting:slo.rules.burnRate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:slo.rules.burnRate/alerts/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/alert/get", + "alerting:observability.rules.custom_threshold/observability/alert/find", + "alerting:observability.rules.custom_threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/observability/alert/getAlertSummary", + "alerting:.es-query/observability/alert/get", + "alerting:.es-query/observability/alert/find", + "alerting:.es-query/observability/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/observability/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAlertSummary", ], "read": Array [ "login:", @@ -6956,6 +13374,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:metrics.alert.threshold/infrastructure/rule/getRuleExecutionKPI", "alerting:metrics.alert.threshold/infrastructure/rule/getBackfill", "alerting:metrics.alert.threshold/infrastructure/rule/findBackfill", + "alerting:metrics.alert.threshold/alerts/rule/get", + "alerting:metrics.alert.threshold/alerts/rule/getRuleState", + "alerting:metrics.alert.threshold/alerts/rule/getAlertSummary", + "alerting:metrics.alert.threshold/alerts/rule/getExecutionLog", + "alerting:metrics.alert.threshold/alerts/rule/getActionErrorLog", + "alerting:metrics.alert.threshold/alerts/rule/find", + "alerting:metrics.alert.threshold/alerts/rule/getRuleExecutionKPI", + "alerting:metrics.alert.threshold/alerts/rule/getBackfill", + "alerting:metrics.alert.threshold/alerts/rule/findBackfill", "alerting:metrics.alert.inventory.threshold/infrastructure/rule/get", "alerting:metrics.alert.inventory.threshold/infrastructure/rule/getRuleState", "alerting:metrics.alert.inventory.threshold/infrastructure/rule/getAlertSummary", @@ -6965,6 +13392,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:metrics.alert.inventory.threshold/infrastructure/rule/getRuleExecutionKPI", "alerting:metrics.alert.inventory.threshold/infrastructure/rule/getBackfill", "alerting:metrics.alert.inventory.threshold/infrastructure/rule/findBackfill", + "alerting:metrics.alert.inventory.threshold/alerts/rule/get", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getRuleState", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getExecutionLog", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getActionErrorLog", + "alerting:metrics.alert.inventory.threshold/alerts/rule/find", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getRuleExecutionKPI", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getBackfill", + "alerting:metrics.alert.inventory.threshold/alerts/rule/findBackfill", "alerting:.es-query/infrastructure/rule/get", "alerting:.es-query/infrastructure/rule/getRuleState", "alerting:.es-query/infrastructure/rule/getAlertSummary", @@ -6974,6 +13410,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:.es-query/infrastructure/rule/getRuleExecutionKPI", "alerting:.es-query/infrastructure/rule/getBackfill", "alerting:.es-query/infrastructure/rule/findBackfill", + "alerting:.es-query/alerts/rule/get", + "alerting:.es-query/alerts/rule/getRuleState", + "alerting:.es-query/alerts/rule/getAlertSummary", + "alerting:.es-query/alerts/rule/getExecutionLog", + "alerting:.es-query/alerts/rule/getActionErrorLog", + "alerting:.es-query/alerts/rule/find", + "alerting:.es-query/alerts/rule/getRuleExecutionKPI", + "alerting:.es-query/alerts/rule/getBackfill", + "alerting:.es-query/alerts/rule/findBackfill", "alerting:observability.rules.custom_threshold/infrastructure/rule/get", "alerting:observability.rules.custom_threshold/infrastructure/rule/getRuleState", "alerting:observability.rules.custom_threshold/infrastructure/rule/getAlertSummary", @@ -6983,6 +13428,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:observability.rules.custom_threshold/infrastructure/rule/getRuleExecutionKPI", "alerting:observability.rules.custom_threshold/infrastructure/rule/getBackfill", "alerting:observability.rules.custom_threshold/infrastructure/rule/findBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/get", + "alerting:observability.rules.custom_threshold/alerts/rule/getRuleState", + "alerting:observability.rules.custom_threshold/alerts/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/alerts/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/alerts/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/alerts/rule/find", + "alerting:observability.rules.custom_threshold/alerts/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/alerts/rule/getBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/findBackfill", "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/get", "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/getRuleState", "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/getAlertSummary", @@ -6992,26 +13446,55 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/getRuleExecutionKPI", "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/getBackfill", "alerting:xpack.ml.anomaly_detection_alert/infrastructure/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/findBackfill", "alerting:metrics.alert.threshold/infrastructure/alert/get", "alerting:metrics.alert.threshold/infrastructure/alert/find", "alerting:metrics.alert.threshold/infrastructure/alert/getAuthorizedAlertsIndices", "alerting:metrics.alert.threshold/infrastructure/alert/getAlertSummary", + "alerting:metrics.alert.threshold/alerts/alert/get", + "alerting:metrics.alert.threshold/alerts/alert/find", + "alerting:metrics.alert.threshold/alerts/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.threshold/alerts/alert/getAlertSummary", "alerting:metrics.alert.inventory.threshold/infrastructure/alert/get", "alerting:metrics.alert.inventory.threshold/infrastructure/alert/find", "alerting:metrics.alert.inventory.threshold/infrastructure/alert/getAuthorizedAlertsIndices", "alerting:metrics.alert.inventory.threshold/infrastructure/alert/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/alerts/alert/get", + "alerting:metrics.alert.inventory.threshold/alerts/alert/find", + "alerting:metrics.alert.inventory.threshold/alerts/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.inventory.threshold/alerts/alert/getAlertSummary", "alerting:.es-query/infrastructure/alert/get", "alerting:.es-query/infrastructure/alert/find", "alerting:.es-query/infrastructure/alert/getAuthorizedAlertsIndices", "alerting:.es-query/infrastructure/alert/getAlertSummary", + "alerting:.es-query/alerts/alert/get", + "alerting:.es-query/alerts/alert/find", + "alerting:.es-query/alerts/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/alerts/alert/getAlertSummary", "alerting:observability.rules.custom_threshold/infrastructure/alert/get", "alerting:observability.rules.custom_threshold/infrastructure/alert/find", "alerting:observability.rules.custom_threshold/infrastructure/alert/getAuthorizedAlertsIndices", "alerting:observability.rules.custom_threshold/infrastructure/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/alerts/alert/get", + "alerting:observability.rules.custom_threshold/alerts/alert/find", + "alerting:observability.rules.custom_threshold/alerts/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/alerts/alert/getAlertSummary", "alerting:xpack.ml.anomaly_detection_alert/infrastructure/alert/get", "alerting:xpack.ml.anomaly_detection_alert/infrastructure/alert/find", "alerting:xpack.ml.anomaly_detection_alert/infrastructure/alert/getAuthorizedAlertsIndices", "alerting:xpack.ml.anomaly_detection_alert/infrastructure/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/getAlertSummary", "app:logs", "app:observability-logs-explorer", "ui:catalogue/infralogging", @@ -7033,6 +13516,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:logs.alert.document.count/logs/rule/getRuleExecutionKPI", "alerting:logs.alert.document.count/logs/rule/getBackfill", "alerting:logs.alert.document.count/logs/rule/findBackfill", + "alerting:logs.alert.document.count/alerts/rule/get", + "alerting:logs.alert.document.count/alerts/rule/getRuleState", + "alerting:logs.alert.document.count/alerts/rule/getAlertSummary", + "alerting:logs.alert.document.count/alerts/rule/getExecutionLog", + "alerting:logs.alert.document.count/alerts/rule/getActionErrorLog", + "alerting:logs.alert.document.count/alerts/rule/find", + "alerting:logs.alert.document.count/alerts/rule/getRuleExecutionKPI", + "alerting:logs.alert.document.count/alerts/rule/getBackfill", + "alerting:logs.alert.document.count/alerts/rule/findBackfill", "alerting:.es-query/logs/rule/get", "alerting:.es-query/logs/rule/getRuleState", "alerting:.es-query/logs/rule/getAlertSummary", @@ -7064,6 +13556,10 @@ export default function ({ getService }: FtrProviderContext) { "alerting:logs.alert.document.count/logs/alert/find", "alerting:logs.alert.document.count/logs/alert/getAuthorizedAlertsIndices", "alerting:logs.alert.document.count/logs/alert/getAlertSummary", + "alerting:logs.alert.document.count/alerts/alert/get", + "alerting:logs.alert.document.count/alerts/alert/find", + "alerting:logs.alert.document.count/alerts/alert/getAuthorizedAlertsIndices", + "alerting:logs.alert.document.count/alerts/alert/getAlertSummary", "alerting:.es-query/logs/alert/get", "alerting:.es-query/logs/alert/find", "alerting:.es-query/logs/alert/getAuthorizedAlertsIndices", @@ -7080,51 +13576,6 @@ export default function ({ getService }: FtrProviderContext) { "ui:catalogue/observability", "ui:navLinks/observability", "ui:observability/read", - "alerting:slo.rules.burnRate/observability/rule/get", - "alerting:slo.rules.burnRate/observability/rule/getRuleState", - "alerting:slo.rules.burnRate/observability/rule/getAlertSummary", - "alerting:slo.rules.burnRate/observability/rule/getExecutionLog", - "alerting:slo.rules.burnRate/observability/rule/getActionErrorLog", - "alerting:slo.rules.burnRate/observability/rule/find", - "alerting:slo.rules.burnRate/observability/rule/getRuleExecutionKPI", - "alerting:slo.rules.burnRate/observability/rule/getBackfill", - "alerting:slo.rules.burnRate/observability/rule/findBackfill", - "alerting:observability.rules.custom_threshold/observability/rule/get", - "alerting:observability.rules.custom_threshold/observability/rule/getRuleState", - "alerting:observability.rules.custom_threshold/observability/rule/getAlertSummary", - "alerting:observability.rules.custom_threshold/observability/rule/getExecutionLog", - "alerting:observability.rules.custom_threshold/observability/rule/getActionErrorLog", - "alerting:observability.rules.custom_threshold/observability/rule/find", - "alerting:observability.rules.custom_threshold/observability/rule/getRuleExecutionKPI", - "alerting:observability.rules.custom_threshold/observability/rule/getBackfill", - "alerting:observability.rules.custom_threshold/observability/rule/findBackfill", - "alerting:.es-query/observability/rule/get", - "alerting:.es-query/observability/rule/getRuleState", - "alerting:.es-query/observability/rule/getAlertSummary", - "alerting:.es-query/observability/rule/getExecutionLog", - "alerting:.es-query/observability/rule/getActionErrorLog", - "alerting:.es-query/observability/rule/find", - "alerting:.es-query/observability/rule/getRuleExecutionKPI", - "alerting:.es-query/observability/rule/getBackfill", - "alerting:.es-query/observability/rule/findBackfill", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/get", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleState", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getAlertSummary", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getExecutionLog", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getActionErrorLog", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/find", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleExecutionKPI", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getBackfill", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/findBackfill", - "alerting:metrics.alert.inventory.threshold/observability/rule/get", - "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleState", - "alerting:metrics.alert.inventory.threshold/observability/rule/getAlertSummary", - "alerting:metrics.alert.inventory.threshold/observability/rule/getExecutionLog", - "alerting:metrics.alert.inventory.threshold/observability/rule/getActionErrorLog", - "alerting:metrics.alert.inventory.threshold/observability/rule/find", - "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleExecutionKPI", - "alerting:metrics.alert.inventory.threshold/observability/rule/getBackfill", - "alerting:metrics.alert.inventory.threshold/observability/rule/findBackfill", "alerting:apm.error_rate/observability/rule/get", "alerting:apm.error_rate/observability/rule/getRuleState", "alerting:apm.error_rate/observability/rule/getAlertSummary", @@ -7134,6 +13585,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.error_rate/observability/rule/getRuleExecutionKPI", "alerting:apm.error_rate/observability/rule/getBackfill", "alerting:apm.error_rate/observability/rule/findBackfill", + "alerting:apm.error_rate/alerts/rule/get", + "alerting:apm.error_rate/alerts/rule/getRuleState", + "alerting:apm.error_rate/alerts/rule/getAlertSummary", + "alerting:apm.error_rate/alerts/rule/getExecutionLog", + "alerting:apm.error_rate/alerts/rule/getActionErrorLog", + "alerting:apm.error_rate/alerts/rule/find", + "alerting:apm.error_rate/alerts/rule/getRuleExecutionKPI", + "alerting:apm.error_rate/alerts/rule/getBackfill", + "alerting:apm.error_rate/alerts/rule/findBackfill", "alerting:apm.transaction_error_rate/observability/rule/get", "alerting:apm.transaction_error_rate/observability/rule/getRuleState", "alerting:apm.transaction_error_rate/observability/rule/getAlertSummary", @@ -7143,6 +13603,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.transaction_error_rate/observability/rule/getRuleExecutionKPI", "alerting:apm.transaction_error_rate/observability/rule/getBackfill", "alerting:apm.transaction_error_rate/observability/rule/findBackfill", + "alerting:apm.transaction_error_rate/alerts/rule/get", + "alerting:apm.transaction_error_rate/alerts/rule/getRuleState", + "alerting:apm.transaction_error_rate/alerts/rule/getAlertSummary", + "alerting:apm.transaction_error_rate/alerts/rule/getExecutionLog", + "alerting:apm.transaction_error_rate/alerts/rule/getActionErrorLog", + "alerting:apm.transaction_error_rate/alerts/rule/find", + "alerting:apm.transaction_error_rate/alerts/rule/getRuleExecutionKPI", + "alerting:apm.transaction_error_rate/alerts/rule/getBackfill", + "alerting:apm.transaction_error_rate/alerts/rule/findBackfill", "alerting:apm.transaction_duration/observability/rule/get", "alerting:apm.transaction_duration/observability/rule/getRuleState", "alerting:apm.transaction_duration/observability/rule/getAlertSummary", @@ -7152,6 +13621,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.transaction_duration/observability/rule/getRuleExecutionKPI", "alerting:apm.transaction_duration/observability/rule/getBackfill", "alerting:apm.transaction_duration/observability/rule/findBackfill", + "alerting:apm.transaction_duration/alerts/rule/get", + "alerting:apm.transaction_duration/alerts/rule/getRuleState", + "alerting:apm.transaction_duration/alerts/rule/getAlertSummary", + "alerting:apm.transaction_duration/alerts/rule/getExecutionLog", + "alerting:apm.transaction_duration/alerts/rule/getActionErrorLog", + "alerting:apm.transaction_duration/alerts/rule/find", + "alerting:apm.transaction_duration/alerts/rule/getRuleExecutionKPI", + "alerting:apm.transaction_duration/alerts/rule/getBackfill", + "alerting:apm.transaction_duration/alerts/rule/findBackfill", "alerting:apm.anomaly/observability/rule/get", "alerting:apm.anomaly/observability/rule/getRuleState", "alerting:apm.anomaly/observability/rule/getAlertSummary", @@ -7161,6 +13639,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.anomaly/observability/rule/getRuleExecutionKPI", "alerting:apm.anomaly/observability/rule/getBackfill", "alerting:apm.anomaly/observability/rule/findBackfill", + "alerting:apm.anomaly/alerts/rule/get", + "alerting:apm.anomaly/alerts/rule/getRuleState", + "alerting:apm.anomaly/alerts/rule/getAlertSummary", + "alerting:apm.anomaly/alerts/rule/getExecutionLog", + "alerting:apm.anomaly/alerts/rule/getActionErrorLog", + "alerting:apm.anomaly/alerts/rule/find", + "alerting:apm.anomaly/alerts/rule/getRuleExecutionKPI", + "alerting:apm.anomaly/alerts/rule/getBackfill", + "alerting:apm.anomaly/alerts/rule/findBackfill", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/get", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/getRuleState", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/getAlertSummary", @@ -7170,6 +13657,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/getRuleExecutionKPI", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/getBackfill", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/findBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/get", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getRuleState", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getAlertSummary", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getExecutionLog", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getActionErrorLog", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/find", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/findBackfill", "alerting:xpack.synthetics.alerts.tls/observability/rule/get", "alerting:xpack.synthetics.alerts.tls/observability/rule/getRuleState", "alerting:xpack.synthetics.alerts.tls/observability/rule/getAlertSummary", @@ -7179,50 +13675,271 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.synthetics.alerts.tls/observability/rule/getRuleExecutionKPI", "alerting:xpack.synthetics.alerts.tls/observability/rule/getBackfill", "alerting:xpack.synthetics.alerts.tls/observability/rule/findBackfill", - "alerting:slo.rules.burnRate/observability/alert/get", - "alerting:slo.rules.burnRate/observability/alert/find", - "alerting:slo.rules.burnRate/observability/alert/getAuthorizedAlertsIndices", - "alerting:slo.rules.burnRate/observability/alert/getAlertSummary", - "alerting:observability.rules.custom_threshold/observability/alert/get", - "alerting:observability.rules.custom_threshold/observability/alert/find", - "alerting:observability.rules.custom_threshold/observability/alert/getAuthorizedAlertsIndices", - "alerting:observability.rules.custom_threshold/observability/alert/getAlertSummary", - "alerting:.es-query/observability/alert/get", - "alerting:.es-query/observability/alert/find", - "alerting:.es-query/observability/alert/getAuthorizedAlertsIndices", - "alerting:.es-query/observability/alert/getAlertSummary", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/get", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/find", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAuthorizedAlertsIndices", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAlertSummary", - "alerting:metrics.alert.inventory.threshold/observability/alert/get", - "alerting:metrics.alert.inventory.threshold/observability/alert/find", - "alerting:metrics.alert.inventory.threshold/observability/alert/getAuthorizedAlertsIndices", - "alerting:metrics.alert.inventory.threshold/observability/alert/getAlertSummary", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/get", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getRuleState", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getAlertSummary", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getExecutionLog", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getActionErrorLog", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/find", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getBackfill", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/findBackfill", + "alerting:metrics.alert.threshold/observability/rule/get", + "alerting:metrics.alert.threshold/observability/rule/getRuleState", + "alerting:metrics.alert.threshold/observability/rule/getAlertSummary", + "alerting:metrics.alert.threshold/observability/rule/getExecutionLog", + "alerting:metrics.alert.threshold/observability/rule/getActionErrorLog", + "alerting:metrics.alert.threshold/observability/rule/find", + "alerting:metrics.alert.threshold/observability/rule/getRuleExecutionKPI", + "alerting:metrics.alert.threshold/observability/rule/getBackfill", + "alerting:metrics.alert.threshold/observability/rule/findBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/get", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleState", + "alerting:metrics.alert.inventory.threshold/observability/rule/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/rule/getExecutionLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/getActionErrorLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/find", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleExecutionKPI", + "alerting:metrics.alert.inventory.threshold/observability/rule/getBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.tls/observability/rule/get", + "alerting:xpack.uptime.alerts.tls/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.tls/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tls/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tls/observability/rule/find", + "alerting:xpack.uptime.alerts.tls/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tls/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.tls/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.tls/alerts/rule/get", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tls/alerts/rule/find", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.tls/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/get", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/find", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/get", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/find", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/get", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/find", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/get", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/find", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/get", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/find", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/get", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/find", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/findBackfill", + "alerting:logs.alert.document.count/observability/rule/get", + "alerting:logs.alert.document.count/observability/rule/getRuleState", + "alerting:logs.alert.document.count/observability/rule/getAlertSummary", + "alerting:logs.alert.document.count/observability/rule/getExecutionLog", + "alerting:logs.alert.document.count/observability/rule/getActionErrorLog", + "alerting:logs.alert.document.count/observability/rule/find", + "alerting:logs.alert.document.count/observability/rule/getRuleExecutionKPI", + "alerting:logs.alert.document.count/observability/rule/getBackfill", + "alerting:logs.alert.document.count/observability/rule/findBackfill", + "alerting:slo.rules.burnRate/observability/rule/get", + "alerting:slo.rules.burnRate/observability/rule/getRuleState", + "alerting:slo.rules.burnRate/observability/rule/getAlertSummary", + "alerting:slo.rules.burnRate/observability/rule/getExecutionLog", + "alerting:slo.rules.burnRate/observability/rule/getActionErrorLog", + "alerting:slo.rules.burnRate/observability/rule/find", + "alerting:slo.rules.burnRate/observability/rule/getRuleExecutionKPI", + "alerting:slo.rules.burnRate/observability/rule/getBackfill", + "alerting:slo.rules.burnRate/observability/rule/findBackfill", + "alerting:slo.rules.burnRate/alerts/rule/get", + "alerting:slo.rules.burnRate/alerts/rule/getRuleState", + "alerting:slo.rules.burnRate/alerts/rule/getAlertSummary", + "alerting:slo.rules.burnRate/alerts/rule/getExecutionLog", + "alerting:slo.rules.burnRate/alerts/rule/getActionErrorLog", + "alerting:slo.rules.burnRate/alerts/rule/find", + "alerting:slo.rules.burnRate/alerts/rule/getRuleExecutionKPI", + "alerting:slo.rules.burnRate/alerts/rule/getBackfill", + "alerting:slo.rules.burnRate/alerts/rule/findBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/get", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleState", + "alerting:observability.rules.custom_threshold/observability/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/observability/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/observability/rule/find", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/observability/rule/getBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/findBackfill", + "alerting:.es-query/observability/rule/get", + "alerting:.es-query/observability/rule/getRuleState", + "alerting:.es-query/observability/rule/getAlertSummary", + "alerting:.es-query/observability/rule/getExecutionLog", + "alerting:.es-query/observability/rule/getActionErrorLog", + "alerting:.es-query/observability/rule/find", + "alerting:.es-query/observability/rule/getRuleExecutionKPI", + "alerting:.es-query/observability/rule/getBackfill", + "alerting:.es-query/observability/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/findBackfill", "alerting:apm.error_rate/observability/alert/get", "alerting:apm.error_rate/observability/alert/find", "alerting:apm.error_rate/observability/alert/getAuthorizedAlertsIndices", "alerting:apm.error_rate/observability/alert/getAlertSummary", + "alerting:apm.error_rate/alerts/alert/get", + "alerting:apm.error_rate/alerts/alert/find", + "alerting:apm.error_rate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.error_rate/alerts/alert/getAlertSummary", "alerting:apm.transaction_error_rate/observability/alert/get", "alerting:apm.transaction_error_rate/observability/alert/find", "alerting:apm.transaction_error_rate/observability/alert/getAuthorizedAlertsIndices", "alerting:apm.transaction_error_rate/observability/alert/getAlertSummary", + "alerting:apm.transaction_error_rate/alerts/alert/get", + "alerting:apm.transaction_error_rate/alerts/alert/find", + "alerting:apm.transaction_error_rate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_error_rate/alerts/alert/getAlertSummary", "alerting:apm.transaction_duration/observability/alert/get", "alerting:apm.transaction_duration/observability/alert/find", "alerting:apm.transaction_duration/observability/alert/getAuthorizedAlertsIndices", "alerting:apm.transaction_duration/observability/alert/getAlertSummary", + "alerting:apm.transaction_duration/alerts/alert/get", + "alerting:apm.transaction_duration/alerts/alert/find", + "alerting:apm.transaction_duration/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_duration/alerts/alert/getAlertSummary", "alerting:apm.anomaly/observability/alert/get", "alerting:apm.anomaly/observability/alert/find", "alerting:apm.anomaly/observability/alert/getAuthorizedAlertsIndices", "alerting:apm.anomaly/observability/alert/getAlertSummary", + "alerting:apm.anomaly/alerts/alert/get", + "alerting:apm.anomaly/alerts/alert/find", + "alerting:apm.anomaly/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.anomaly/alerts/alert/getAlertSummary", "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/get", "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/find", "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/getAuthorizedAlertsIndices", "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/getAlertSummary", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/get", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/find", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/getAlertSummary", "alerting:xpack.synthetics.alerts.tls/observability/alert/get", "alerting:xpack.synthetics.alerts.tls/observability/alert/find", "alerting:xpack.synthetics.alerts.tls/observability/alert/getAuthorizedAlertsIndices", "alerting:xpack.synthetics.alerts.tls/observability/alert/getAlertSummary", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/get", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/find", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/getAlertSummary", + "alerting:metrics.alert.threshold/observability/alert/get", + "alerting:metrics.alert.threshold/observability/alert/find", + "alerting:metrics.alert.threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.threshold/observability/alert/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/alert/get", + "alerting:metrics.alert.inventory.threshold/observability/alert/find", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/observability/alert/get", + "alerting:xpack.uptime.alerts.tls/observability/alert/find", + "alerting:xpack.uptime.alerts.tls/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tls/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/alerts/alert/get", + "alerting:xpack.uptime.alerts.tls/alerts/alert/find", + "alerting:xpack.uptime.alerts.tls/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tls/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/get", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/find", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/get", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/find", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/get", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/find", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/get", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/find", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/get", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/find", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/get", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/find", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/getAlertSummary", + "alerting:logs.alert.document.count/observability/alert/get", + "alerting:logs.alert.document.count/observability/alert/find", + "alerting:logs.alert.document.count/observability/alert/getAuthorizedAlertsIndices", + "alerting:logs.alert.document.count/observability/alert/getAlertSummary", + "alerting:slo.rules.burnRate/observability/alert/get", + "alerting:slo.rules.burnRate/observability/alert/find", + "alerting:slo.rules.burnRate/observability/alert/getAuthorizedAlertsIndices", + "alerting:slo.rules.burnRate/observability/alert/getAlertSummary", + "alerting:slo.rules.burnRate/alerts/alert/get", + "alerting:slo.rules.burnRate/alerts/alert/find", + "alerting:slo.rules.burnRate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:slo.rules.burnRate/alerts/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/alert/get", + "alerting:observability.rules.custom_threshold/observability/alert/find", + "alerting:observability.rules.custom_threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/observability/alert/getAlertSummary", + "alerting:.es-query/observability/alert/get", + "alerting:.es-query/observability/alert/find", + "alerting:.es-query/observability/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/observability/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAlertSummary", ], }, "reporting": Object { @@ -7436,155 +14153,48 @@ export default function ({ getService }: FtrProviderContext) { "alerting:slo.rules.burnRate/slo/rule/runSoon", "alerting:slo.rules.burnRate/slo/rule/scheduleBackfill", "alerting:slo.rules.burnRate/slo/rule/deleteBackfill", + "alerting:slo.rules.burnRate/alerts/rule/get", + "alerting:slo.rules.burnRate/alerts/rule/getRuleState", + "alerting:slo.rules.burnRate/alerts/rule/getAlertSummary", + "alerting:slo.rules.burnRate/alerts/rule/getExecutionLog", + "alerting:slo.rules.burnRate/alerts/rule/getActionErrorLog", + "alerting:slo.rules.burnRate/alerts/rule/find", + "alerting:slo.rules.burnRate/alerts/rule/getRuleExecutionKPI", + "alerting:slo.rules.burnRate/alerts/rule/getBackfill", + "alerting:slo.rules.burnRate/alerts/rule/findBackfill", + "alerting:slo.rules.burnRate/alerts/rule/create", + "alerting:slo.rules.burnRate/alerts/rule/delete", + "alerting:slo.rules.burnRate/alerts/rule/update", + "alerting:slo.rules.burnRate/alerts/rule/updateApiKey", + "alerting:slo.rules.burnRate/alerts/rule/enable", + "alerting:slo.rules.burnRate/alerts/rule/disable", + "alerting:slo.rules.burnRate/alerts/rule/muteAll", + "alerting:slo.rules.burnRate/alerts/rule/unmuteAll", + "alerting:slo.rules.burnRate/alerts/rule/muteAlert", + "alerting:slo.rules.burnRate/alerts/rule/unmuteAlert", + "alerting:slo.rules.burnRate/alerts/rule/snooze", + "alerting:slo.rules.burnRate/alerts/rule/bulkEdit", + "alerting:slo.rules.burnRate/alerts/rule/bulkDelete", + "alerting:slo.rules.burnRate/alerts/rule/bulkEnable", + "alerting:slo.rules.burnRate/alerts/rule/bulkDisable", + "alerting:slo.rules.burnRate/alerts/rule/unsnooze", + "alerting:slo.rules.burnRate/alerts/rule/runSoon", + "alerting:slo.rules.burnRate/alerts/rule/scheduleBackfill", + "alerting:slo.rules.burnRate/alerts/rule/deleteBackfill", "alerting:slo.rules.burnRate/slo/alert/get", "alerting:slo.rules.burnRate/slo/alert/find", "alerting:slo.rules.burnRate/slo/alert/getAuthorizedAlertsIndices", "alerting:slo.rules.burnRate/slo/alert/getAlertSummary", "alerting:slo.rules.burnRate/slo/alert/update", + "alerting:slo.rules.burnRate/alerts/alert/get", + "alerting:slo.rules.burnRate/alerts/alert/find", + "alerting:slo.rules.burnRate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:slo.rules.burnRate/alerts/alert/getAlertSummary", + "alerting:slo.rules.burnRate/alerts/alert/update", "app:observability", "ui:navLinks/observability", "ui:observability/read", "ui:observability/write", - "alerting:slo.rules.burnRate/observability/rule/get", - "alerting:slo.rules.burnRate/observability/rule/getRuleState", - "alerting:slo.rules.burnRate/observability/rule/getAlertSummary", - "alerting:slo.rules.burnRate/observability/rule/getExecutionLog", - "alerting:slo.rules.burnRate/observability/rule/getActionErrorLog", - "alerting:slo.rules.burnRate/observability/rule/find", - "alerting:slo.rules.burnRate/observability/rule/getRuleExecutionKPI", - "alerting:slo.rules.burnRate/observability/rule/getBackfill", - "alerting:slo.rules.burnRate/observability/rule/findBackfill", - "alerting:slo.rules.burnRate/observability/rule/create", - "alerting:slo.rules.burnRate/observability/rule/delete", - "alerting:slo.rules.burnRate/observability/rule/update", - "alerting:slo.rules.burnRate/observability/rule/updateApiKey", - "alerting:slo.rules.burnRate/observability/rule/enable", - "alerting:slo.rules.burnRate/observability/rule/disable", - "alerting:slo.rules.burnRate/observability/rule/muteAll", - "alerting:slo.rules.burnRate/observability/rule/unmuteAll", - "alerting:slo.rules.burnRate/observability/rule/muteAlert", - "alerting:slo.rules.burnRate/observability/rule/unmuteAlert", - "alerting:slo.rules.burnRate/observability/rule/snooze", - "alerting:slo.rules.burnRate/observability/rule/bulkEdit", - "alerting:slo.rules.burnRate/observability/rule/bulkDelete", - "alerting:slo.rules.burnRate/observability/rule/bulkEnable", - "alerting:slo.rules.burnRate/observability/rule/bulkDisable", - "alerting:slo.rules.burnRate/observability/rule/unsnooze", - "alerting:slo.rules.burnRate/observability/rule/runSoon", - "alerting:slo.rules.burnRate/observability/rule/scheduleBackfill", - "alerting:slo.rules.burnRate/observability/rule/deleteBackfill", - "alerting:observability.rules.custom_threshold/observability/rule/get", - "alerting:observability.rules.custom_threshold/observability/rule/getRuleState", - "alerting:observability.rules.custom_threshold/observability/rule/getAlertSummary", - "alerting:observability.rules.custom_threshold/observability/rule/getExecutionLog", - "alerting:observability.rules.custom_threshold/observability/rule/getActionErrorLog", - "alerting:observability.rules.custom_threshold/observability/rule/find", - "alerting:observability.rules.custom_threshold/observability/rule/getRuleExecutionKPI", - "alerting:observability.rules.custom_threshold/observability/rule/getBackfill", - "alerting:observability.rules.custom_threshold/observability/rule/findBackfill", - "alerting:observability.rules.custom_threshold/observability/rule/create", - "alerting:observability.rules.custom_threshold/observability/rule/delete", - "alerting:observability.rules.custom_threshold/observability/rule/update", - "alerting:observability.rules.custom_threshold/observability/rule/updateApiKey", - "alerting:observability.rules.custom_threshold/observability/rule/enable", - "alerting:observability.rules.custom_threshold/observability/rule/disable", - "alerting:observability.rules.custom_threshold/observability/rule/muteAll", - "alerting:observability.rules.custom_threshold/observability/rule/unmuteAll", - "alerting:observability.rules.custom_threshold/observability/rule/muteAlert", - "alerting:observability.rules.custom_threshold/observability/rule/unmuteAlert", - "alerting:observability.rules.custom_threshold/observability/rule/snooze", - "alerting:observability.rules.custom_threshold/observability/rule/bulkEdit", - "alerting:observability.rules.custom_threshold/observability/rule/bulkDelete", - "alerting:observability.rules.custom_threshold/observability/rule/bulkEnable", - "alerting:observability.rules.custom_threshold/observability/rule/bulkDisable", - "alerting:observability.rules.custom_threshold/observability/rule/unsnooze", - "alerting:observability.rules.custom_threshold/observability/rule/runSoon", - "alerting:observability.rules.custom_threshold/observability/rule/scheduleBackfill", - "alerting:observability.rules.custom_threshold/observability/rule/deleteBackfill", - "alerting:.es-query/observability/rule/get", - "alerting:.es-query/observability/rule/getRuleState", - "alerting:.es-query/observability/rule/getAlertSummary", - "alerting:.es-query/observability/rule/getExecutionLog", - "alerting:.es-query/observability/rule/getActionErrorLog", - "alerting:.es-query/observability/rule/find", - "alerting:.es-query/observability/rule/getRuleExecutionKPI", - "alerting:.es-query/observability/rule/getBackfill", - "alerting:.es-query/observability/rule/findBackfill", - "alerting:.es-query/observability/rule/create", - "alerting:.es-query/observability/rule/delete", - "alerting:.es-query/observability/rule/update", - "alerting:.es-query/observability/rule/updateApiKey", - "alerting:.es-query/observability/rule/enable", - "alerting:.es-query/observability/rule/disable", - "alerting:.es-query/observability/rule/muteAll", - "alerting:.es-query/observability/rule/unmuteAll", - "alerting:.es-query/observability/rule/muteAlert", - "alerting:.es-query/observability/rule/unmuteAlert", - "alerting:.es-query/observability/rule/snooze", - "alerting:.es-query/observability/rule/bulkEdit", - "alerting:.es-query/observability/rule/bulkDelete", - "alerting:.es-query/observability/rule/bulkEnable", - "alerting:.es-query/observability/rule/bulkDisable", - "alerting:.es-query/observability/rule/unsnooze", - "alerting:.es-query/observability/rule/runSoon", - "alerting:.es-query/observability/rule/scheduleBackfill", - "alerting:.es-query/observability/rule/deleteBackfill", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/get", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleState", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getAlertSummary", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getExecutionLog", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getActionErrorLog", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/find", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleExecutionKPI", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getBackfill", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/findBackfill", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/create", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/delete", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/update", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/updateApiKey", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/enable", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/disable", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/muteAll", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unmuteAll", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/muteAlert", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unmuteAlert", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/snooze", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkEdit", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkDelete", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkEnable", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkDisable", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unsnooze", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/runSoon", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/scheduleBackfill", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/deleteBackfill", - "alerting:metrics.alert.inventory.threshold/observability/rule/get", - "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleState", - "alerting:metrics.alert.inventory.threshold/observability/rule/getAlertSummary", - "alerting:metrics.alert.inventory.threshold/observability/rule/getExecutionLog", - "alerting:metrics.alert.inventory.threshold/observability/rule/getActionErrorLog", - "alerting:metrics.alert.inventory.threshold/observability/rule/find", - "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleExecutionKPI", - "alerting:metrics.alert.inventory.threshold/observability/rule/getBackfill", - "alerting:metrics.alert.inventory.threshold/observability/rule/findBackfill", - "alerting:metrics.alert.inventory.threshold/observability/rule/create", - "alerting:metrics.alert.inventory.threshold/observability/rule/delete", - "alerting:metrics.alert.inventory.threshold/observability/rule/update", - "alerting:metrics.alert.inventory.threshold/observability/rule/updateApiKey", - "alerting:metrics.alert.inventory.threshold/observability/rule/enable", - "alerting:metrics.alert.inventory.threshold/observability/rule/disable", - "alerting:metrics.alert.inventory.threshold/observability/rule/muteAll", - "alerting:metrics.alert.inventory.threshold/observability/rule/unmuteAll", - "alerting:metrics.alert.inventory.threshold/observability/rule/muteAlert", - "alerting:metrics.alert.inventory.threshold/observability/rule/unmuteAlert", - "alerting:metrics.alert.inventory.threshold/observability/rule/snooze", - "alerting:metrics.alert.inventory.threshold/observability/rule/bulkEdit", - "alerting:metrics.alert.inventory.threshold/observability/rule/bulkDelete", - "alerting:metrics.alert.inventory.threshold/observability/rule/bulkEnable", - "alerting:metrics.alert.inventory.threshold/observability/rule/bulkDisable", - "alerting:metrics.alert.inventory.threshold/observability/rule/unsnooze", - "alerting:metrics.alert.inventory.threshold/observability/rule/runSoon", - "alerting:metrics.alert.inventory.threshold/observability/rule/scheduleBackfill", - "alerting:metrics.alert.inventory.threshold/observability/rule/deleteBackfill", "alerting:apm.error_rate/observability/rule/get", "alerting:apm.error_rate/observability/rule/getRuleState", "alerting:apm.error_rate/observability/rule/getAlertSummary", @@ -7613,6 +14223,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.error_rate/observability/rule/runSoon", "alerting:apm.error_rate/observability/rule/scheduleBackfill", "alerting:apm.error_rate/observability/rule/deleteBackfill", + "alerting:apm.error_rate/alerts/rule/get", + "alerting:apm.error_rate/alerts/rule/getRuleState", + "alerting:apm.error_rate/alerts/rule/getAlertSummary", + "alerting:apm.error_rate/alerts/rule/getExecutionLog", + "alerting:apm.error_rate/alerts/rule/getActionErrorLog", + "alerting:apm.error_rate/alerts/rule/find", + "alerting:apm.error_rate/alerts/rule/getRuleExecutionKPI", + "alerting:apm.error_rate/alerts/rule/getBackfill", + "alerting:apm.error_rate/alerts/rule/findBackfill", + "alerting:apm.error_rate/alerts/rule/create", + "alerting:apm.error_rate/alerts/rule/delete", + "alerting:apm.error_rate/alerts/rule/update", + "alerting:apm.error_rate/alerts/rule/updateApiKey", + "alerting:apm.error_rate/alerts/rule/enable", + "alerting:apm.error_rate/alerts/rule/disable", + "alerting:apm.error_rate/alerts/rule/muteAll", + "alerting:apm.error_rate/alerts/rule/unmuteAll", + "alerting:apm.error_rate/alerts/rule/muteAlert", + "alerting:apm.error_rate/alerts/rule/unmuteAlert", + "alerting:apm.error_rate/alerts/rule/snooze", + "alerting:apm.error_rate/alerts/rule/bulkEdit", + "alerting:apm.error_rate/alerts/rule/bulkDelete", + "alerting:apm.error_rate/alerts/rule/bulkEnable", + "alerting:apm.error_rate/alerts/rule/bulkDisable", + "alerting:apm.error_rate/alerts/rule/unsnooze", + "alerting:apm.error_rate/alerts/rule/runSoon", + "alerting:apm.error_rate/alerts/rule/scheduleBackfill", + "alerting:apm.error_rate/alerts/rule/deleteBackfill", "alerting:apm.transaction_error_rate/observability/rule/get", "alerting:apm.transaction_error_rate/observability/rule/getRuleState", "alerting:apm.transaction_error_rate/observability/rule/getAlertSummary", @@ -7641,6 +14279,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.transaction_error_rate/observability/rule/runSoon", "alerting:apm.transaction_error_rate/observability/rule/scheduleBackfill", "alerting:apm.transaction_error_rate/observability/rule/deleteBackfill", + "alerting:apm.transaction_error_rate/alerts/rule/get", + "alerting:apm.transaction_error_rate/alerts/rule/getRuleState", + "alerting:apm.transaction_error_rate/alerts/rule/getAlertSummary", + "alerting:apm.transaction_error_rate/alerts/rule/getExecutionLog", + "alerting:apm.transaction_error_rate/alerts/rule/getActionErrorLog", + "alerting:apm.transaction_error_rate/alerts/rule/find", + "alerting:apm.transaction_error_rate/alerts/rule/getRuleExecutionKPI", + "alerting:apm.transaction_error_rate/alerts/rule/getBackfill", + "alerting:apm.transaction_error_rate/alerts/rule/findBackfill", + "alerting:apm.transaction_error_rate/alerts/rule/create", + "alerting:apm.transaction_error_rate/alerts/rule/delete", + "alerting:apm.transaction_error_rate/alerts/rule/update", + "alerting:apm.transaction_error_rate/alerts/rule/updateApiKey", + "alerting:apm.transaction_error_rate/alerts/rule/enable", + "alerting:apm.transaction_error_rate/alerts/rule/disable", + "alerting:apm.transaction_error_rate/alerts/rule/muteAll", + "alerting:apm.transaction_error_rate/alerts/rule/unmuteAll", + "alerting:apm.transaction_error_rate/alerts/rule/muteAlert", + "alerting:apm.transaction_error_rate/alerts/rule/unmuteAlert", + "alerting:apm.transaction_error_rate/alerts/rule/snooze", + "alerting:apm.transaction_error_rate/alerts/rule/bulkEdit", + "alerting:apm.transaction_error_rate/alerts/rule/bulkDelete", + "alerting:apm.transaction_error_rate/alerts/rule/bulkEnable", + "alerting:apm.transaction_error_rate/alerts/rule/bulkDisable", + "alerting:apm.transaction_error_rate/alerts/rule/unsnooze", + "alerting:apm.transaction_error_rate/alerts/rule/runSoon", + "alerting:apm.transaction_error_rate/alerts/rule/scheduleBackfill", + "alerting:apm.transaction_error_rate/alerts/rule/deleteBackfill", "alerting:apm.transaction_duration/observability/rule/get", "alerting:apm.transaction_duration/observability/rule/getRuleState", "alerting:apm.transaction_duration/observability/rule/getAlertSummary", @@ -7669,6 +14335,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.transaction_duration/observability/rule/runSoon", "alerting:apm.transaction_duration/observability/rule/scheduleBackfill", "alerting:apm.transaction_duration/observability/rule/deleteBackfill", + "alerting:apm.transaction_duration/alerts/rule/get", + "alerting:apm.transaction_duration/alerts/rule/getRuleState", + "alerting:apm.transaction_duration/alerts/rule/getAlertSummary", + "alerting:apm.transaction_duration/alerts/rule/getExecutionLog", + "alerting:apm.transaction_duration/alerts/rule/getActionErrorLog", + "alerting:apm.transaction_duration/alerts/rule/find", + "alerting:apm.transaction_duration/alerts/rule/getRuleExecutionKPI", + "alerting:apm.transaction_duration/alerts/rule/getBackfill", + "alerting:apm.transaction_duration/alerts/rule/findBackfill", + "alerting:apm.transaction_duration/alerts/rule/create", + "alerting:apm.transaction_duration/alerts/rule/delete", + "alerting:apm.transaction_duration/alerts/rule/update", + "alerting:apm.transaction_duration/alerts/rule/updateApiKey", + "alerting:apm.transaction_duration/alerts/rule/enable", + "alerting:apm.transaction_duration/alerts/rule/disable", + "alerting:apm.transaction_duration/alerts/rule/muteAll", + "alerting:apm.transaction_duration/alerts/rule/unmuteAll", + "alerting:apm.transaction_duration/alerts/rule/muteAlert", + "alerting:apm.transaction_duration/alerts/rule/unmuteAlert", + "alerting:apm.transaction_duration/alerts/rule/snooze", + "alerting:apm.transaction_duration/alerts/rule/bulkEdit", + "alerting:apm.transaction_duration/alerts/rule/bulkDelete", + "alerting:apm.transaction_duration/alerts/rule/bulkEnable", + "alerting:apm.transaction_duration/alerts/rule/bulkDisable", + "alerting:apm.transaction_duration/alerts/rule/unsnooze", + "alerting:apm.transaction_duration/alerts/rule/runSoon", + "alerting:apm.transaction_duration/alerts/rule/scheduleBackfill", + "alerting:apm.transaction_duration/alerts/rule/deleteBackfill", "alerting:apm.anomaly/observability/rule/get", "alerting:apm.anomaly/observability/rule/getRuleState", "alerting:apm.anomaly/observability/rule/getAlertSummary", @@ -7697,6 +14391,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.anomaly/observability/rule/runSoon", "alerting:apm.anomaly/observability/rule/scheduleBackfill", "alerting:apm.anomaly/observability/rule/deleteBackfill", + "alerting:apm.anomaly/alerts/rule/get", + "alerting:apm.anomaly/alerts/rule/getRuleState", + "alerting:apm.anomaly/alerts/rule/getAlertSummary", + "alerting:apm.anomaly/alerts/rule/getExecutionLog", + "alerting:apm.anomaly/alerts/rule/getActionErrorLog", + "alerting:apm.anomaly/alerts/rule/find", + "alerting:apm.anomaly/alerts/rule/getRuleExecutionKPI", + "alerting:apm.anomaly/alerts/rule/getBackfill", + "alerting:apm.anomaly/alerts/rule/findBackfill", + "alerting:apm.anomaly/alerts/rule/create", + "alerting:apm.anomaly/alerts/rule/delete", + "alerting:apm.anomaly/alerts/rule/update", + "alerting:apm.anomaly/alerts/rule/updateApiKey", + "alerting:apm.anomaly/alerts/rule/enable", + "alerting:apm.anomaly/alerts/rule/disable", + "alerting:apm.anomaly/alerts/rule/muteAll", + "alerting:apm.anomaly/alerts/rule/unmuteAll", + "alerting:apm.anomaly/alerts/rule/muteAlert", + "alerting:apm.anomaly/alerts/rule/unmuteAlert", + "alerting:apm.anomaly/alerts/rule/snooze", + "alerting:apm.anomaly/alerts/rule/bulkEdit", + "alerting:apm.anomaly/alerts/rule/bulkDelete", + "alerting:apm.anomaly/alerts/rule/bulkEnable", + "alerting:apm.anomaly/alerts/rule/bulkDisable", + "alerting:apm.anomaly/alerts/rule/unsnooze", + "alerting:apm.anomaly/alerts/rule/runSoon", + "alerting:apm.anomaly/alerts/rule/scheduleBackfill", + "alerting:apm.anomaly/alerts/rule/deleteBackfill", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/get", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/getRuleState", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/getAlertSummary", @@ -7725,6 +14447,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/runSoon", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/scheduleBackfill", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/deleteBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/get", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getRuleState", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getAlertSummary", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getExecutionLog", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getActionErrorLog", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/find", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/findBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/create", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/delete", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/update", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/updateApiKey", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/enable", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/disable", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/muteAll", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/unmuteAll", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/muteAlert", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/unmuteAlert", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/snooze", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/bulkEdit", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/bulkDelete", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/bulkEnable", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/bulkDisable", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/unsnooze", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/runSoon", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/scheduleBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/deleteBackfill", "alerting:xpack.synthetics.alerts.tls/observability/rule/get", "alerting:xpack.synthetics.alerts.tls/observability/rule/getRuleState", "alerting:xpack.synthetics.alerts.tls/observability/rule/getAlertSummary", @@ -7753,61 +14503,787 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.synthetics.alerts.tls/observability/rule/runSoon", "alerting:xpack.synthetics.alerts.tls/observability/rule/scheduleBackfill", "alerting:xpack.synthetics.alerts.tls/observability/rule/deleteBackfill", - "alerting:slo.rules.burnRate/observability/alert/get", - "alerting:slo.rules.burnRate/observability/alert/find", - "alerting:slo.rules.burnRate/observability/alert/getAuthorizedAlertsIndices", - "alerting:slo.rules.burnRate/observability/alert/getAlertSummary", - "alerting:slo.rules.burnRate/observability/alert/update", - "alerting:observability.rules.custom_threshold/observability/alert/get", - "alerting:observability.rules.custom_threshold/observability/alert/find", - "alerting:observability.rules.custom_threshold/observability/alert/getAuthorizedAlertsIndices", - "alerting:observability.rules.custom_threshold/observability/alert/getAlertSummary", - "alerting:observability.rules.custom_threshold/observability/alert/update", - "alerting:.es-query/observability/alert/get", - "alerting:.es-query/observability/alert/find", - "alerting:.es-query/observability/alert/getAuthorizedAlertsIndices", - "alerting:.es-query/observability/alert/getAlertSummary", - "alerting:.es-query/observability/alert/update", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/get", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/find", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAuthorizedAlertsIndices", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAlertSummary", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/update", - "alerting:metrics.alert.inventory.threshold/observability/alert/get", - "alerting:metrics.alert.inventory.threshold/observability/alert/find", - "alerting:metrics.alert.inventory.threshold/observability/alert/getAuthorizedAlertsIndices", - "alerting:metrics.alert.inventory.threshold/observability/alert/getAlertSummary", - "alerting:metrics.alert.inventory.threshold/observability/alert/update", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/get", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getRuleState", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getAlertSummary", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getExecutionLog", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getActionErrorLog", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/find", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getBackfill", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/findBackfill", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/create", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/delete", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/update", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/updateApiKey", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/enable", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/disable", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/muteAll", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/unmuteAll", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/muteAlert", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/unmuteAlert", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/snooze", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/bulkEdit", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/bulkDelete", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/bulkEnable", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/bulkDisable", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/unsnooze", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/runSoon", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/scheduleBackfill", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/deleteBackfill", + "alerting:metrics.alert.threshold/observability/rule/get", + "alerting:metrics.alert.threshold/observability/rule/getRuleState", + "alerting:metrics.alert.threshold/observability/rule/getAlertSummary", + "alerting:metrics.alert.threshold/observability/rule/getExecutionLog", + "alerting:metrics.alert.threshold/observability/rule/getActionErrorLog", + "alerting:metrics.alert.threshold/observability/rule/find", + "alerting:metrics.alert.threshold/observability/rule/getRuleExecutionKPI", + "alerting:metrics.alert.threshold/observability/rule/getBackfill", + "alerting:metrics.alert.threshold/observability/rule/findBackfill", + "alerting:metrics.alert.threshold/observability/rule/create", + "alerting:metrics.alert.threshold/observability/rule/delete", + "alerting:metrics.alert.threshold/observability/rule/update", + "alerting:metrics.alert.threshold/observability/rule/updateApiKey", + "alerting:metrics.alert.threshold/observability/rule/enable", + "alerting:metrics.alert.threshold/observability/rule/disable", + "alerting:metrics.alert.threshold/observability/rule/muteAll", + "alerting:metrics.alert.threshold/observability/rule/unmuteAll", + "alerting:metrics.alert.threshold/observability/rule/muteAlert", + "alerting:metrics.alert.threshold/observability/rule/unmuteAlert", + "alerting:metrics.alert.threshold/observability/rule/snooze", + "alerting:metrics.alert.threshold/observability/rule/bulkEdit", + "alerting:metrics.alert.threshold/observability/rule/bulkDelete", + "alerting:metrics.alert.threshold/observability/rule/bulkEnable", + "alerting:metrics.alert.threshold/observability/rule/bulkDisable", + "alerting:metrics.alert.threshold/observability/rule/unsnooze", + "alerting:metrics.alert.threshold/observability/rule/runSoon", + "alerting:metrics.alert.threshold/observability/rule/scheduleBackfill", + "alerting:metrics.alert.threshold/observability/rule/deleteBackfill", + "alerting:metrics.alert.threshold/alerts/rule/get", + "alerting:metrics.alert.threshold/alerts/rule/getRuleState", + "alerting:metrics.alert.threshold/alerts/rule/getAlertSummary", + "alerting:metrics.alert.threshold/alerts/rule/getExecutionLog", + "alerting:metrics.alert.threshold/alerts/rule/getActionErrorLog", + "alerting:metrics.alert.threshold/alerts/rule/find", + "alerting:metrics.alert.threshold/alerts/rule/getRuleExecutionKPI", + "alerting:metrics.alert.threshold/alerts/rule/getBackfill", + "alerting:metrics.alert.threshold/alerts/rule/findBackfill", + "alerting:metrics.alert.threshold/alerts/rule/create", + "alerting:metrics.alert.threshold/alerts/rule/delete", + "alerting:metrics.alert.threshold/alerts/rule/update", + "alerting:metrics.alert.threshold/alerts/rule/updateApiKey", + "alerting:metrics.alert.threshold/alerts/rule/enable", + "alerting:metrics.alert.threshold/alerts/rule/disable", + "alerting:metrics.alert.threshold/alerts/rule/muteAll", + "alerting:metrics.alert.threshold/alerts/rule/unmuteAll", + "alerting:metrics.alert.threshold/alerts/rule/muteAlert", + "alerting:metrics.alert.threshold/alerts/rule/unmuteAlert", + "alerting:metrics.alert.threshold/alerts/rule/snooze", + "alerting:metrics.alert.threshold/alerts/rule/bulkEdit", + "alerting:metrics.alert.threshold/alerts/rule/bulkDelete", + "alerting:metrics.alert.threshold/alerts/rule/bulkEnable", + "alerting:metrics.alert.threshold/alerts/rule/bulkDisable", + "alerting:metrics.alert.threshold/alerts/rule/unsnooze", + "alerting:metrics.alert.threshold/alerts/rule/runSoon", + "alerting:metrics.alert.threshold/alerts/rule/scheduleBackfill", + "alerting:metrics.alert.threshold/alerts/rule/deleteBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/get", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleState", + "alerting:metrics.alert.inventory.threshold/observability/rule/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/rule/getExecutionLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/getActionErrorLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/find", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleExecutionKPI", + "alerting:metrics.alert.inventory.threshold/observability/rule/getBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/findBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/create", + "alerting:metrics.alert.inventory.threshold/observability/rule/delete", + "alerting:metrics.alert.inventory.threshold/observability/rule/update", + "alerting:metrics.alert.inventory.threshold/observability/rule/updateApiKey", + "alerting:metrics.alert.inventory.threshold/observability/rule/enable", + "alerting:metrics.alert.inventory.threshold/observability/rule/disable", + "alerting:metrics.alert.inventory.threshold/observability/rule/muteAll", + "alerting:metrics.alert.inventory.threshold/observability/rule/unmuteAll", + "alerting:metrics.alert.inventory.threshold/observability/rule/muteAlert", + "alerting:metrics.alert.inventory.threshold/observability/rule/unmuteAlert", + "alerting:metrics.alert.inventory.threshold/observability/rule/snooze", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkEdit", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkDelete", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkEnable", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkDisable", + "alerting:metrics.alert.inventory.threshold/observability/rule/unsnooze", + "alerting:metrics.alert.inventory.threshold/observability/rule/runSoon", + "alerting:metrics.alert.inventory.threshold/observability/rule/scheduleBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/deleteBackfill", + "alerting:metrics.alert.inventory.threshold/alerts/rule/get", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getRuleState", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getExecutionLog", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getActionErrorLog", + "alerting:metrics.alert.inventory.threshold/alerts/rule/find", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getRuleExecutionKPI", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getBackfill", + "alerting:metrics.alert.inventory.threshold/alerts/rule/findBackfill", + "alerting:metrics.alert.inventory.threshold/alerts/rule/create", + "alerting:metrics.alert.inventory.threshold/alerts/rule/delete", + "alerting:metrics.alert.inventory.threshold/alerts/rule/update", + "alerting:metrics.alert.inventory.threshold/alerts/rule/updateApiKey", + "alerting:metrics.alert.inventory.threshold/alerts/rule/enable", + "alerting:metrics.alert.inventory.threshold/alerts/rule/disable", + "alerting:metrics.alert.inventory.threshold/alerts/rule/muteAll", + "alerting:metrics.alert.inventory.threshold/alerts/rule/unmuteAll", + "alerting:metrics.alert.inventory.threshold/alerts/rule/muteAlert", + "alerting:metrics.alert.inventory.threshold/alerts/rule/unmuteAlert", + "alerting:metrics.alert.inventory.threshold/alerts/rule/snooze", + "alerting:metrics.alert.inventory.threshold/alerts/rule/bulkEdit", + "alerting:metrics.alert.inventory.threshold/alerts/rule/bulkDelete", + "alerting:metrics.alert.inventory.threshold/alerts/rule/bulkEnable", + "alerting:metrics.alert.inventory.threshold/alerts/rule/bulkDisable", + "alerting:metrics.alert.inventory.threshold/alerts/rule/unsnooze", + "alerting:metrics.alert.inventory.threshold/alerts/rule/runSoon", + "alerting:metrics.alert.inventory.threshold/alerts/rule/scheduleBackfill", + "alerting:metrics.alert.inventory.threshold/alerts/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.tls/observability/rule/get", + "alerting:xpack.uptime.alerts.tls/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.tls/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tls/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tls/observability/rule/find", + "alerting:xpack.uptime.alerts.tls/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tls/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.tls/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.tls/observability/rule/create", + "alerting:xpack.uptime.alerts.tls/observability/rule/delete", + "alerting:xpack.uptime.alerts.tls/observability/rule/update", + "alerting:xpack.uptime.alerts.tls/observability/rule/updateApiKey", + "alerting:xpack.uptime.alerts.tls/observability/rule/enable", + "alerting:xpack.uptime.alerts.tls/observability/rule/disable", + "alerting:xpack.uptime.alerts.tls/observability/rule/muteAll", + "alerting:xpack.uptime.alerts.tls/observability/rule/unmuteAll", + "alerting:xpack.uptime.alerts.tls/observability/rule/muteAlert", + "alerting:xpack.uptime.alerts.tls/observability/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.tls/observability/rule/snooze", + "alerting:xpack.uptime.alerts.tls/observability/rule/bulkEdit", + "alerting:xpack.uptime.alerts.tls/observability/rule/bulkDelete", + "alerting:xpack.uptime.alerts.tls/observability/rule/bulkEnable", + "alerting:xpack.uptime.alerts.tls/observability/rule/bulkDisable", + "alerting:xpack.uptime.alerts.tls/observability/rule/unsnooze", + "alerting:xpack.uptime.alerts.tls/observability/rule/runSoon", + "alerting:xpack.uptime.alerts.tls/observability/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.tls/observability/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.tls/alerts/rule/get", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tls/alerts/rule/find", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.tls/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.tls/alerts/rule/create", + "alerting:xpack.uptime.alerts.tls/alerts/rule/delete", + "alerting:xpack.uptime.alerts.tls/alerts/rule/update", + "alerting:xpack.uptime.alerts.tls/alerts/rule/updateApiKey", + "alerting:xpack.uptime.alerts.tls/alerts/rule/enable", + "alerting:xpack.uptime.alerts.tls/alerts/rule/disable", + "alerting:xpack.uptime.alerts.tls/alerts/rule/muteAll", + "alerting:xpack.uptime.alerts.tls/alerts/rule/unmuteAll", + "alerting:xpack.uptime.alerts.tls/alerts/rule/muteAlert", + "alerting:xpack.uptime.alerts.tls/alerts/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.tls/alerts/rule/snooze", + "alerting:xpack.uptime.alerts.tls/alerts/rule/bulkEdit", + "alerting:xpack.uptime.alerts.tls/alerts/rule/bulkDelete", + "alerting:xpack.uptime.alerts.tls/alerts/rule/bulkEnable", + "alerting:xpack.uptime.alerts.tls/alerts/rule/bulkDisable", + "alerting:xpack.uptime.alerts.tls/alerts/rule/unsnooze", + "alerting:xpack.uptime.alerts.tls/alerts/rule/runSoon", + "alerting:xpack.uptime.alerts.tls/alerts/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.tls/alerts/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/get", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/find", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/create", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/delete", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/update", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/updateApiKey", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/enable", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/disable", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/muteAll", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/unmuteAll", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/muteAlert", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/snooze", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/bulkEdit", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/bulkDelete", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/bulkEnable", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/bulkDisable", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/unsnooze", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/runSoon", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/get", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/find", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/create", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/delete", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/update", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/updateApiKey", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/enable", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/disable", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/muteAll", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/unmuteAll", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/muteAlert", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/snooze", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/bulkEdit", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/bulkDelete", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/bulkEnable", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/bulkDisable", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/unsnooze", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/runSoon", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/get", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/find", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/create", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/delete", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/update", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/updateApiKey", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/enable", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/disable", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/muteAll", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/unmuteAll", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/muteAlert", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/snooze", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/bulkEdit", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/bulkDelete", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/bulkEnable", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/bulkDisable", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/unsnooze", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/runSoon", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/get", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/find", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/create", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/delete", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/update", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/updateApiKey", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/enable", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/disable", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/muteAll", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/unmuteAll", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/muteAlert", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/snooze", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/bulkEdit", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/bulkDelete", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/bulkEnable", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/bulkDisable", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/unsnooze", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/runSoon", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/get", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/find", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/create", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/delete", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/update", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/updateApiKey", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/enable", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/disable", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/muteAll", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/unmuteAll", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/muteAlert", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/snooze", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/bulkEdit", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/bulkDelete", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/bulkEnable", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/bulkDisable", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/unsnooze", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/runSoon", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/get", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/find", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/create", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/delete", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/update", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/updateApiKey", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/enable", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/disable", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/muteAll", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/unmuteAll", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/muteAlert", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/snooze", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/bulkEdit", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/bulkDelete", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/bulkEnable", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/bulkDisable", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/unsnooze", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/runSoon", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/deleteBackfill", + "alerting:logs.alert.document.count/observability/rule/get", + "alerting:logs.alert.document.count/observability/rule/getRuleState", + "alerting:logs.alert.document.count/observability/rule/getAlertSummary", + "alerting:logs.alert.document.count/observability/rule/getExecutionLog", + "alerting:logs.alert.document.count/observability/rule/getActionErrorLog", + "alerting:logs.alert.document.count/observability/rule/find", + "alerting:logs.alert.document.count/observability/rule/getRuleExecutionKPI", + "alerting:logs.alert.document.count/observability/rule/getBackfill", + "alerting:logs.alert.document.count/observability/rule/findBackfill", + "alerting:logs.alert.document.count/observability/rule/create", + "alerting:logs.alert.document.count/observability/rule/delete", + "alerting:logs.alert.document.count/observability/rule/update", + "alerting:logs.alert.document.count/observability/rule/updateApiKey", + "alerting:logs.alert.document.count/observability/rule/enable", + "alerting:logs.alert.document.count/observability/rule/disable", + "alerting:logs.alert.document.count/observability/rule/muteAll", + "alerting:logs.alert.document.count/observability/rule/unmuteAll", + "alerting:logs.alert.document.count/observability/rule/muteAlert", + "alerting:logs.alert.document.count/observability/rule/unmuteAlert", + "alerting:logs.alert.document.count/observability/rule/snooze", + "alerting:logs.alert.document.count/observability/rule/bulkEdit", + "alerting:logs.alert.document.count/observability/rule/bulkDelete", + "alerting:logs.alert.document.count/observability/rule/bulkEnable", + "alerting:logs.alert.document.count/observability/rule/bulkDisable", + "alerting:logs.alert.document.count/observability/rule/unsnooze", + "alerting:logs.alert.document.count/observability/rule/runSoon", + "alerting:logs.alert.document.count/observability/rule/scheduleBackfill", + "alerting:logs.alert.document.count/observability/rule/deleteBackfill", + "alerting:logs.alert.document.count/alerts/rule/get", + "alerting:logs.alert.document.count/alerts/rule/getRuleState", + "alerting:logs.alert.document.count/alerts/rule/getAlertSummary", + "alerting:logs.alert.document.count/alerts/rule/getExecutionLog", + "alerting:logs.alert.document.count/alerts/rule/getActionErrorLog", + "alerting:logs.alert.document.count/alerts/rule/find", + "alerting:logs.alert.document.count/alerts/rule/getRuleExecutionKPI", + "alerting:logs.alert.document.count/alerts/rule/getBackfill", + "alerting:logs.alert.document.count/alerts/rule/findBackfill", + "alerting:logs.alert.document.count/alerts/rule/create", + "alerting:logs.alert.document.count/alerts/rule/delete", + "alerting:logs.alert.document.count/alerts/rule/update", + "alerting:logs.alert.document.count/alerts/rule/updateApiKey", + "alerting:logs.alert.document.count/alerts/rule/enable", + "alerting:logs.alert.document.count/alerts/rule/disable", + "alerting:logs.alert.document.count/alerts/rule/muteAll", + "alerting:logs.alert.document.count/alerts/rule/unmuteAll", + "alerting:logs.alert.document.count/alerts/rule/muteAlert", + "alerting:logs.alert.document.count/alerts/rule/unmuteAlert", + "alerting:logs.alert.document.count/alerts/rule/snooze", + "alerting:logs.alert.document.count/alerts/rule/bulkEdit", + "alerting:logs.alert.document.count/alerts/rule/bulkDelete", + "alerting:logs.alert.document.count/alerts/rule/bulkEnable", + "alerting:logs.alert.document.count/alerts/rule/bulkDisable", + "alerting:logs.alert.document.count/alerts/rule/unsnooze", + "alerting:logs.alert.document.count/alerts/rule/runSoon", + "alerting:logs.alert.document.count/alerts/rule/scheduleBackfill", + "alerting:logs.alert.document.count/alerts/rule/deleteBackfill", + "alerting:slo.rules.burnRate/observability/rule/get", + "alerting:slo.rules.burnRate/observability/rule/getRuleState", + "alerting:slo.rules.burnRate/observability/rule/getAlertSummary", + "alerting:slo.rules.burnRate/observability/rule/getExecutionLog", + "alerting:slo.rules.burnRate/observability/rule/getActionErrorLog", + "alerting:slo.rules.burnRate/observability/rule/find", + "alerting:slo.rules.burnRate/observability/rule/getRuleExecutionKPI", + "alerting:slo.rules.burnRate/observability/rule/getBackfill", + "alerting:slo.rules.burnRate/observability/rule/findBackfill", + "alerting:slo.rules.burnRate/observability/rule/create", + "alerting:slo.rules.burnRate/observability/rule/delete", + "alerting:slo.rules.burnRate/observability/rule/update", + "alerting:slo.rules.burnRate/observability/rule/updateApiKey", + "alerting:slo.rules.burnRate/observability/rule/enable", + "alerting:slo.rules.burnRate/observability/rule/disable", + "alerting:slo.rules.burnRate/observability/rule/muteAll", + "alerting:slo.rules.burnRate/observability/rule/unmuteAll", + "alerting:slo.rules.burnRate/observability/rule/muteAlert", + "alerting:slo.rules.burnRate/observability/rule/unmuteAlert", + "alerting:slo.rules.burnRate/observability/rule/snooze", + "alerting:slo.rules.burnRate/observability/rule/bulkEdit", + "alerting:slo.rules.burnRate/observability/rule/bulkDelete", + "alerting:slo.rules.burnRate/observability/rule/bulkEnable", + "alerting:slo.rules.burnRate/observability/rule/bulkDisable", + "alerting:slo.rules.burnRate/observability/rule/unsnooze", + "alerting:slo.rules.burnRate/observability/rule/runSoon", + "alerting:slo.rules.burnRate/observability/rule/scheduleBackfill", + "alerting:slo.rules.burnRate/observability/rule/deleteBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/get", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleState", + "alerting:observability.rules.custom_threshold/observability/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/observability/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/observability/rule/find", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/observability/rule/getBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/findBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/create", + "alerting:observability.rules.custom_threshold/observability/rule/delete", + "alerting:observability.rules.custom_threshold/observability/rule/update", + "alerting:observability.rules.custom_threshold/observability/rule/updateApiKey", + "alerting:observability.rules.custom_threshold/observability/rule/enable", + "alerting:observability.rules.custom_threshold/observability/rule/disable", + "alerting:observability.rules.custom_threshold/observability/rule/muteAll", + "alerting:observability.rules.custom_threshold/observability/rule/unmuteAll", + "alerting:observability.rules.custom_threshold/observability/rule/muteAlert", + "alerting:observability.rules.custom_threshold/observability/rule/unmuteAlert", + "alerting:observability.rules.custom_threshold/observability/rule/snooze", + "alerting:observability.rules.custom_threshold/observability/rule/bulkEdit", + "alerting:observability.rules.custom_threshold/observability/rule/bulkDelete", + "alerting:observability.rules.custom_threshold/observability/rule/bulkEnable", + "alerting:observability.rules.custom_threshold/observability/rule/bulkDisable", + "alerting:observability.rules.custom_threshold/observability/rule/unsnooze", + "alerting:observability.rules.custom_threshold/observability/rule/runSoon", + "alerting:observability.rules.custom_threshold/observability/rule/scheduleBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/deleteBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/get", + "alerting:observability.rules.custom_threshold/alerts/rule/getRuleState", + "alerting:observability.rules.custom_threshold/alerts/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/alerts/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/alerts/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/alerts/rule/find", + "alerting:observability.rules.custom_threshold/alerts/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/alerts/rule/getBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/findBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/create", + "alerting:observability.rules.custom_threshold/alerts/rule/delete", + "alerting:observability.rules.custom_threshold/alerts/rule/update", + "alerting:observability.rules.custom_threshold/alerts/rule/updateApiKey", + "alerting:observability.rules.custom_threshold/alerts/rule/enable", + "alerting:observability.rules.custom_threshold/alerts/rule/disable", + "alerting:observability.rules.custom_threshold/alerts/rule/muteAll", + "alerting:observability.rules.custom_threshold/alerts/rule/unmuteAll", + "alerting:observability.rules.custom_threshold/alerts/rule/muteAlert", + "alerting:observability.rules.custom_threshold/alerts/rule/unmuteAlert", + "alerting:observability.rules.custom_threshold/alerts/rule/snooze", + "alerting:observability.rules.custom_threshold/alerts/rule/bulkEdit", + "alerting:observability.rules.custom_threshold/alerts/rule/bulkDelete", + "alerting:observability.rules.custom_threshold/alerts/rule/bulkEnable", + "alerting:observability.rules.custom_threshold/alerts/rule/bulkDisable", + "alerting:observability.rules.custom_threshold/alerts/rule/unsnooze", + "alerting:observability.rules.custom_threshold/alerts/rule/runSoon", + "alerting:observability.rules.custom_threshold/alerts/rule/scheduleBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/deleteBackfill", + "alerting:.es-query/observability/rule/get", + "alerting:.es-query/observability/rule/getRuleState", + "alerting:.es-query/observability/rule/getAlertSummary", + "alerting:.es-query/observability/rule/getExecutionLog", + "alerting:.es-query/observability/rule/getActionErrorLog", + "alerting:.es-query/observability/rule/find", + "alerting:.es-query/observability/rule/getRuleExecutionKPI", + "alerting:.es-query/observability/rule/getBackfill", + "alerting:.es-query/observability/rule/findBackfill", + "alerting:.es-query/observability/rule/create", + "alerting:.es-query/observability/rule/delete", + "alerting:.es-query/observability/rule/update", + "alerting:.es-query/observability/rule/updateApiKey", + "alerting:.es-query/observability/rule/enable", + "alerting:.es-query/observability/rule/disable", + "alerting:.es-query/observability/rule/muteAll", + "alerting:.es-query/observability/rule/unmuteAll", + "alerting:.es-query/observability/rule/muteAlert", + "alerting:.es-query/observability/rule/unmuteAlert", + "alerting:.es-query/observability/rule/snooze", + "alerting:.es-query/observability/rule/bulkEdit", + "alerting:.es-query/observability/rule/bulkDelete", + "alerting:.es-query/observability/rule/bulkEnable", + "alerting:.es-query/observability/rule/bulkDisable", + "alerting:.es-query/observability/rule/unsnooze", + "alerting:.es-query/observability/rule/runSoon", + "alerting:.es-query/observability/rule/scheduleBackfill", + "alerting:.es-query/observability/rule/deleteBackfill", + "alerting:.es-query/alerts/rule/get", + "alerting:.es-query/alerts/rule/getRuleState", + "alerting:.es-query/alerts/rule/getAlertSummary", + "alerting:.es-query/alerts/rule/getExecutionLog", + "alerting:.es-query/alerts/rule/getActionErrorLog", + "alerting:.es-query/alerts/rule/find", + "alerting:.es-query/alerts/rule/getRuleExecutionKPI", + "alerting:.es-query/alerts/rule/getBackfill", + "alerting:.es-query/alerts/rule/findBackfill", + "alerting:.es-query/alerts/rule/create", + "alerting:.es-query/alerts/rule/delete", + "alerting:.es-query/alerts/rule/update", + "alerting:.es-query/alerts/rule/updateApiKey", + "alerting:.es-query/alerts/rule/enable", + "alerting:.es-query/alerts/rule/disable", + "alerting:.es-query/alerts/rule/muteAll", + "alerting:.es-query/alerts/rule/unmuteAll", + "alerting:.es-query/alerts/rule/muteAlert", + "alerting:.es-query/alerts/rule/unmuteAlert", + "alerting:.es-query/alerts/rule/snooze", + "alerting:.es-query/alerts/rule/bulkEdit", + "alerting:.es-query/alerts/rule/bulkDelete", + "alerting:.es-query/alerts/rule/bulkEnable", + "alerting:.es-query/alerts/rule/bulkDisable", + "alerting:.es-query/alerts/rule/unsnooze", + "alerting:.es-query/alerts/rule/runSoon", + "alerting:.es-query/alerts/rule/scheduleBackfill", + "alerting:.es-query/alerts/rule/deleteBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/create", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/delete", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/update", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/updateApiKey", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/enable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/disable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/muteAll", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unmuteAll", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/muteAlert", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unmuteAlert", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/snooze", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkEdit", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkDelete", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkEnable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkDisable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unsnooze", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/runSoon", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/scheduleBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/deleteBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/create", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/delete", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/update", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/updateApiKey", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/enable", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/disable", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/muteAll", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/unmuteAll", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/muteAlert", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/unmuteAlert", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/snooze", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/bulkEdit", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/bulkDelete", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/bulkEnable", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/bulkDisable", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/unsnooze", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/runSoon", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/scheduleBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/deleteBackfill", "alerting:apm.error_rate/observability/alert/get", "alerting:apm.error_rate/observability/alert/find", "alerting:apm.error_rate/observability/alert/getAuthorizedAlertsIndices", "alerting:apm.error_rate/observability/alert/getAlertSummary", "alerting:apm.error_rate/observability/alert/update", + "alerting:apm.error_rate/alerts/alert/get", + "alerting:apm.error_rate/alerts/alert/find", + "alerting:apm.error_rate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.error_rate/alerts/alert/getAlertSummary", + "alerting:apm.error_rate/alerts/alert/update", "alerting:apm.transaction_error_rate/observability/alert/get", "alerting:apm.transaction_error_rate/observability/alert/find", "alerting:apm.transaction_error_rate/observability/alert/getAuthorizedAlertsIndices", "alerting:apm.transaction_error_rate/observability/alert/getAlertSummary", "alerting:apm.transaction_error_rate/observability/alert/update", + "alerting:apm.transaction_error_rate/alerts/alert/get", + "alerting:apm.transaction_error_rate/alerts/alert/find", + "alerting:apm.transaction_error_rate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_error_rate/alerts/alert/getAlertSummary", + "alerting:apm.transaction_error_rate/alerts/alert/update", "alerting:apm.transaction_duration/observability/alert/get", "alerting:apm.transaction_duration/observability/alert/find", "alerting:apm.transaction_duration/observability/alert/getAuthorizedAlertsIndices", "alerting:apm.transaction_duration/observability/alert/getAlertSummary", "alerting:apm.transaction_duration/observability/alert/update", + "alerting:apm.transaction_duration/alerts/alert/get", + "alerting:apm.transaction_duration/alerts/alert/find", + "alerting:apm.transaction_duration/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_duration/alerts/alert/getAlertSummary", + "alerting:apm.transaction_duration/alerts/alert/update", "alerting:apm.anomaly/observability/alert/get", "alerting:apm.anomaly/observability/alert/find", "alerting:apm.anomaly/observability/alert/getAuthorizedAlertsIndices", "alerting:apm.anomaly/observability/alert/getAlertSummary", "alerting:apm.anomaly/observability/alert/update", + "alerting:apm.anomaly/alerts/alert/get", + "alerting:apm.anomaly/alerts/alert/find", + "alerting:apm.anomaly/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.anomaly/alerts/alert/getAlertSummary", + "alerting:apm.anomaly/alerts/alert/update", "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/get", "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/find", "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/getAuthorizedAlertsIndices", "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/getAlertSummary", "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/update", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/get", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/find", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/getAlertSummary", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/update", "alerting:xpack.synthetics.alerts.tls/observability/alert/get", "alerting:xpack.synthetics.alerts.tls/observability/alert/find", "alerting:xpack.synthetics.alerts.tls/observability/alert/getAuthorizedAlertsIndices", "alerting:xpack.synthetics.alerts.tls/observability/alert/getAlertSummary", "alerting:xpack.synthetics.alerts.tls/observability/alert/update", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/get", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/find", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/getAlertSummary", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/update", + "alerting:metrics.alert.threshold/observability/alert/get", + "alerting:metrics.alert.threshold/observability/alert/find", + "alerting:metrics.alert.threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.threshold/observability/alert/getAlertSummary", + "alerting:metrics.alert.threshold/observability/alert/update", + "alerting:metrics.alert.threshold/alerts/alert/get", + "alerting:metrics.alert.threshold/alerts/alert/find", + "alerting:metrics.alert.threshold/alerts/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.threshold/alerts/alert/getAlertSummary", + "alerting:metrics.alert.threshold/alerts/alert/update", + "alerting:metrics.alert.inventory.threshold/observability/alert/get", + "alerting:metrics.alert.inventory.threshold/observability/alert/find", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/alert/update", + "alerting:metrics.alert.inventory.threshold/alerts/alert/get", + "alerting:metrics.alert.inventory.threshold/alerts/alert/find", + "alerting:metrics.alert.inventory.threshold/alerts/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.inventory.threshold/alerts/alert/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/alerts/alert/update", + "alerting:xpack.uptime.alerts.tls/observability/alert/get", + "alerting:xpack.uptime.alerts.tls/observability/alert/find", + "alerting:xpack.uptime.alerts.tls/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tls/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/observability/alert/update", + "alerting:xpack.uptime.alerts.tls/alerts/alert/get", + "alerting:xpack.uptime.alerts.tls/alerts/alert/find", + "alerting:xpack.uptime.alerts.tls/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tls/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/alerts/alert/update", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/get", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/find", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/update", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/get", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/find", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/update", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/get", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/find", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/update", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/get", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/find", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/update", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/get", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/find", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/update", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/get", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/find", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/update", + "alerting:logs.alert.document.count/observability/alert/get", + "alerting:logs.alert.document.count/observability/alert/find", + "alerting:logs.alert.document.count/observability/alert/getAuthorizedAlertsIndices", + "alerting:logs.alert.document.count/observability/alert/getAlertSummary", + "alerting:logs.alert.document.count/observability/alert/update", + "alerting:logs.alert.document.count/alerts/alert/get", + "alerting:logs.alert.document.count/alerts/alert/find", + "alerting:logs.alert.document.count/alerts/alert/getAuthorizedAlertsIndices", + "alerting:logs.alert.document.count/alerts/alert/getAlertSummary", + "alerting:logs.alert.document.count/alerts/alert/update", + "alerting:slo.rules.burnRate/observability/alert/get", + "alerting:slo.rules.burnRate/observability/alert/find", + "alerting:slo.rules.burnRate/observability/alert/getAuthorizedAlertsIndices", + "alerting:slo.rules.burnRate/observability/alert/getAlertSummary", + "alerting:slo.rules.burnRate/observability/alert/update", + "alerting:observability.rules.custom_threshold/observability/alert/get", + "alerting:observability.rules.custom_threshold/observability/alert/find", + "alerting:observability.rules.custom_threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/observability/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/alert/update", + "alerting:observability.rules.custom_threshold/alerts/alert/get", + "alerting:observability.rules.custom_threshold/alerts/alert/find", + "alerting:observability.rules.custom_threshold/alerts/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/alerts/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/alerts/alert/update", + "alerting:.es-query/observability/alert/get", + "alerting:.es-query/observability/alert/find", + "alerting:.es-query/observability/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/observability/alert/getAlertSummary", + "alerting:.es-query/observability/alert/update", + "alerting:.es-query/alerts/alert/get", + "alerting:.es-query/alerts/alert/find", + "alerting:.es-query/alerts/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/alerts/alert/getAlertSummary", + "alerting:.es-query/alerts/alert/update", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/update", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/update", ], "minimal_all": Array [ "login:", @@ -7901,155 +15377,48 @@ export default function ({ getService }: FtrProviderContext) { "alerting:slo.rules.burnRate/slo/rule/runSoon", "alerting:slo.rules.burnRate/slo/rule/scheduleBackfill", "alerting:slo.rules.burnRate/slo/rule/deleteBackfill", + "alerting:slo.rules.burnRate/alerts/rule/get", + "alerting:slo.rules.burnRate/alerts/rule/getRuleState", + "alerting:slo.rules.burnRate/alerts/rule/getAlertSummary", + "alerting:slo.rules.burnRate/alerts/rule/getExecutionLog", + "alerting:slo.rules.burnRate/alerts/rule/getActionErrorLog", + "alerting:slo.rules.burnRate/alerts/rule/find", + "alerting:slo.rules.burnRate/alerts/rule/getRuleExecutionKPI", + "alerting:slo.rules.burnRate/alerts/rule/getBackfill", + "alerting:slo.rules.burnRate/alerts/rule/findBackfill", + "alerting:slo.rules.burnRate/alerts/rule/create", + "alerting:slo.rules.burnRate/alerts/rule/delete", + "alerting:slo.rules.burnRate/alerts/rule/update", + "alerting:slo.rules.burnRate/alerts/rule/updateApiKey", + "alerting:slo.rules.burnRate/alerts/rule/enable", + "alerting:slo.rules.burnRate/alerts/rule/disable", + "alerting:slo.rules.burnRate/alerts/rule/muteAll", + "alerting:slo.rules.burnRate/alerts/rule/unmuteAll", + "alerting:slo.rules.burnRate/alerts/rule/muteAlert", + "alerting:slo.rules.burnRate/alerts/rule/unmuteAlert", + "alerting:slo.rules.burnRate/alerts/rule/snooze", + "alerting:slo.rules.burnRate/alerts/rule/bulkEdit", + "alerting:slo.rules.burnRate/alerts/rule/bulkDelete", + "alerting:slo.rules.burnRate/alerts/rule/bulkEnable", + "alerting:slo.rules.burnRate/alerts/rule/bulkDisable", + "alerting:slo.rules.burnRate/alerts/rule/unsnooze", + "alerting:slo.rules.burnRate/alerts/rule/runSoon", + "alerting:slo.rules.burnRate/alerts/rule/scheduleBackfill", + "alerting:slo.rules.burnRate/alerts/rule/deleteBackfill", "alerting:slo.rules.burnRate/slo/alert/get", "alerting:slo.rules.burnRate/slo/alert/find", "alerting:slo.rules.burnRate/slo/alert/getAuthorizedAlertsIndices", "alerting:slo.rules.burnRate/slo/alert/getAlertSummary", "alerting:slo.rules.burnRate/slo/alert/update", - "app:observability", - "ui:navLinks/observability", - "ui:observability/read", - "ui:observability/write", - "alerting:slo.rules.burnRate/observability/rule/get", - "alerting:slo.rules.burnRate/observability/rule/getRuleState", - "alerting:slo.rules.burnRate/observability/rule/getAlertSummary", - "alerting:slo.rules.burnRate/observability/rule/getExecutionLog", - "alerting:slo.rules.burnRate/observability/rule/getActionErrorLog", - "alerting:slo.rules.burnRate/observability/rule/find", - "alerting:slo.rules.burnRate/observability/rule/getRuleExecutionKPI", - "alerting:slo.rules.burnRate/observability/rule/getBackfill", - "alerting:slo.rules.burnRate/observability/rule/findBackfill", - "alerting:slo.rules.burnRate/observability/rule/create", - "alerting:slo.rules.burnRate/observability/rule/delete", - "alerting:slo.rules.burnRate/observability/rule/update", - "alerting:slo.rules.burnRate/observability/rule/updateApiKey", - "alerting:slo.rules.burnRate/observability/rule/enable", - "alerting:slo.rules.burnRate/observability/rule/disable", - "alerting:slo.rules.burnRate/observability/rule/muteAll", - "alerting:slo.rules.burnRate/observability/rule/unmuteAll", - "alerting:slo.rules.burnRate/observability/rule/muteAlert", - "alerting:slo.rules.burnRate/observability/rule/unmuteAlert", - "alerting:slo.rules.burnRate/observability/rule/snooze", - "alerting:slo.rules.burnRate/observability/rule/bulkEdit", - "alerting:slo.rules.burnRate/observability/rule/bulkDelete", - "alerting:slo.rules.burnRate/observability/rule/bulkEnable", - "alerting:slo.rules.burnRate/observability/rule/bulkDisable", - "alerting:slo.rules.burnRate/observability/rule/unsnooze", - "alerting:slo.rules.burnRate/observability/rule/runSoon", - "alerting:slo.rules.burnRate/observability/rule/scheduleBackfill", - "alerting:slo.rules.burnRate/observability/rule/deleteBackfill", - "alerting:observability.rules.custom_threshold/observability/rule/get", - "alerting:observability.rules.custom_threshold/observability/rule/getRuleState", - "alerting:observability.rules.custom_threshold/observability/rule/getAlertSummary", - "alerting:observability.rules.custom_threshold/observability/rule/getExecutionLog", - "alerting:observability.rules.custom_threshold/observability/rule/getActionErrorLog", - "alerting:observability.rules.custom_threshold/observability/rule/find", - "alerting:observability.rules.custom_threshold/observability/rule/getRuleExecutionKPI", - "alerting:observability.rules.custom_threshold/observability/rule/getBackfill", - "alerting:observability.rules.custom_threshold/observability/rule/findBackfill", - "alerting:observability.rules.custom_threshold/observability/rule/create", - "alerting:observability.rules.custom_threshold/observability/rule/delete", - "alerting:observability.rules.custom_threshold/observability/rule/update", - "alerting:observability.rules.custom_threshold/observability/rule/updateApiKey", - "alerting:observability.rules.custom_threshold/observability/rule/enable", - "alerting:observability.rules.custom_threshold/observability/rule/disable", - "alerting:observability.rules.custom_threshold/observability/rule/muteAll", - "alerting:observability.rules.custom_threshold/observability/rule/unmuteAll", - "alerting:observability.rules.custom_threshold/observability/rule/muteAlert", - "alerting:observability.rules.custom_threshold/observability/rule/unmuteAlert", - "alerting:observability.rules.custom_threshold/observability/rule/snooze", - "alerting:observability.rules.custom_threshold/observability/rule/bulkEdit", - "alerting:observability.rules.custom_threshold/observability/rule/bulkDelete", - "alerting:observability.rules.custom_threshold/observability/rule/bulkEnable", - "alerting:observability.rules.custom_threshold/observability/rule/bulkDisable", - "alerting:observability.rules.custom_threshold/observability/rule/unsnooze", - "alerting:observability.rules.custom_threshold/observability/rule/runSoon", - "alerting:observability.rules.custom_threshold/observability/rule/scheduleBackfill", - "alerting:observability.rules.custom_threshold/observability/rule/deleteBackfill", - "alerting:.es-query/observability/rule/get", - "alerting:.es-query/observability/rule/getRuleState", - "alerting:.es-query/observability/rule/getAlertSummary", - "alerting:.es-query/observability/rule/getExecutionLog", - "alerting:.es-query/observability/rule/getActionErrorLog", - "alerting:.es-query/observability/rule/find", - "alerting:.es-query/observability/rule/getRuleExecutionKPI", - "alerting:.es-query/observability/rule/getBackfill", - "alerting:.es-query/observability/rule/findBackfill", - "alerting:.es-query/observability/rule/create", - "alerting:.es-query/observability/rule/delete", - "alerting:.es-query/observability/rule/update", - "alerting:.es-query/observability/rule/updateApiKey", - "alerting:.es-query/observability/rule/enable", - "alerting:.es-query/observability/rule/disable", - "alerting:.es-query/observability/rule/muteAll", - "alerting:.es-query/observability/rule/unmuteAll", - "alerting:.es-query/observability/rule/muteAlert", - "alerting:.es-query/observability/rule/unmuteAlert", - "alerting:.es-query/observability/rule/snooze", - "alerting:.es-query/observability/rule/bulkEdit", - "alerting:.es-query/observability/rule/bulkDelete", - "alerting:.es-query/observability/rule/bulkEnable", - "alerting:.es-query/observability/rule/bulkDisable", - "alerting:.es-query/observability/rule/unsnooze", - "alerting:.es-query/observability/rule/runSoon", - "alerting:.es-query/observability/rule/scheduleBackfill", - "alerting:.es-query/observability/rule/deleteBackfill", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/get", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleState", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getAlertSummary", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getExecutionLog", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getActionErrorLog", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/find", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleExecutionKPI", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getBackfill", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/findBackfill", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/create", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/delete", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/update", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/updateApiKey", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/enable", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/disable", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/muteAll", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unmuteAll", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/muteAlert", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unmuteAlert", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/snooze", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkEdit", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkDelete", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkEnable", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkDisable", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unsnooze", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/runSoon", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/scheduleBackfill", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/deleteBackfill", - "alerting:metrics.alert.inventory.threshold/observability/rule/get", - "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleState", - "alerting:metrics.alert.inventory.threshold/observability/rule/getAlertSummary", - "alerting:metrics.alert.inventory.threshold/observability/rule/getExecutionLog", - "alerting:metrics.alert.inventory.threshold/observability/rule/getActionErrorLog", - "alerting:metrics.alert.inventory.threshold/observability/rule/find", - "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleExecutionKPI", - "alerting:metrics.alert.inventory.threshold/observability/rule/getBackfill", - "alerting:metrics.alert.inventory.threshold/observability/rule/findBackfill", - "alerting:metrics.alert.inventory.threshold/observability/rule/create", - "alerting:metrics.alert.inventory.threshold/observability/rule/delete", - "alerting:metrics.alert.inventory.threshold/observability/rule/update", - "alerting:metrics.alert.inventory.threshold/observability/rule/updateApiKey", - "alerting:metrics.alert.inventory.threshold/observability/rule/enable", - "alerting:metrics.alert.inventory.threshold/observability/rule/disable", - "alerting:metrics.alert.inventory.threshold/observability/rule/muteAll", - "alerting:metrics.alert.inventory.threshold/observability/rule/unmuteAll", - "alerting:metrics.alert.inventory.threshold/observability/rule/muteAlert", - "alerting:metrics.alert.inventory.threshold/observability/rule/unmuteAlert", - "alerting:metrics.alert.inventory.threshold/observability/rule/snooze", - "alerting:metrics.alert.inventory.threshold/observability/rule/bulkEdit", - "alerting:metrics.alert.inventory.threshold/observability/rule/bulkDelete", - "alerting:metrics.alert.inventory.threshold/observability/rule/bulkEnable", - "alerting:metrics.alert.inventory.threshold/observability/rule/bulkDisable", - "alerting:metrics.alert.inventory.threshold/observability/rule/unsnooze", - "alerting:metrics.alert.inventory.threshold/observability/rule/runSoon", - "alerting:metrics.alert.inventory.threshold/observability/rule/scheduleBackfill", - "alerting:metrics.alert.inventory.threshold/observability/rule/deleteBackfill", + "alerting:slo.rules.burnRate/alerts/alert/get", + "alerting:slo.rules.burnRate/alerts/alert/find", + "alerting:slo.rules.burnRate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:slo.rules.burnRate/alerts/alert/getAlertSummary", + "alerting:slo.rules.burnRate/alerts/alert/update", + "app:observability", + "ui:navLinks/observability", + "ui:observability/read", + "ui:observability/write", "alerting:apm.error_rate/observability/rule/get", "alerting:apm.error_rate/observability/rule/getRuleState", "alerting:apm.error_rate/observability/rule/getAlertSummary", @@ -8078,6 +15447,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.error_rate/observability/rule/runSoon", "alerting:apm.error_rate/observability/rule/scheduleBackfill", "alerting:apm.error_rate/observability/rule/deleteBackfill", + "alerting:apm.error_rate/alerts/rule/get", + "alerting:apm.error_rate/alerts/rule/getRuleState", + "alerting:apm.error_rate/alerts/rule/getAlertSummary", + "alerting:apm.error_rate/alerts/rule/getExecutionLog", + "alerting:apm.error_rate/alerts/rule/getActionErrorLog", + "alerting:apm.error_rate/alerts/rule/find", + "alerting:apm.error_rate/alerts/rule/getRuleExecutionKPI", + "alerting:apm.error_rate/alerts/rule/getBackfill", + "alerting:apm.error_rate/alerts/rule/findBackfill", + "alerting:apm.error_rate/alerts/rule/create", + "alerting:apm.error_rate/alerts/rule/delete", + "alerting:apm.error_rate/alerts/rule/update", + "alerting:apm.error_rate/alerts/rule/updateApiKey", + "alerting:apm.error_rate/alerts/rule/enable", + "alerting:apm.error_rate/alerts/rule/disable", + "alerting:apm.error_rate/alerts/rule/muteAll", + "alerting:apm.error_rate/alerts/rule/unmuteAll", + "alerting:apm.error_rate/alerts/rule/muteAlert", + "alerting:apm.error_rate/alerts/rule/unmuteAlert", + "alerting:apm.error_rate/alerts/rule/snooze", + "alerting:apm.error_rate/alerts/rule/bulkEdit", + "alerting:apm.error_rate/alerts/rule/bulkDelete", + "alerting:apm.error_rate/alerts/rule/bulkEnable", + "alerting:apm.error_rate/alerts/rule/bulkDisable", + "alerting:apm.error_rate/alerts/rule/unsnooze", + "alerting:apm.error_rate/alerts/rule/runSoon", + "alerting:apm.error_rate/alerts/rule/scheduleBackfill", + "alerting:apm.error_rate/alerts/rule/deleteBackfill", "alerting:apm.transaction_error_rate/observability/rule/get", "alerting:apm.transaction_error_rate/observability/rule/getRuleState", "alerting:apm.transaction_error_rate/observability/rule/getAlertSummary", @@ -8106,6 +15503,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.transaction_error_rate/observability/rule/runSoon", "alerting:apm.transaction_error_rate/observability/rule/scheduleBackfill", "alerting:apm.transaction_error_rate/observability/rule/deleteBackfill", + "alerting:apm.transaction_error_rate/alerts/rule/get", + "alerting:apm.transaction_error_rate/alerts/rule/getRuleState", + "alerting:apm.transaction_error_rate/alerts/rule/getAlertSummary", + "alerting:apm.transaction_error_rate/alerts/rule/getExecutionLog", + "alerting:apm.transaction_error_rate/alerts/rule/getActionErrorLog", + "alerting:apm.transaction_error_rate/alerts/rule/find", + "alerting:apm.transaction_error_rate/alerts/rule/getRuleExecutionKPI", + "alerting:apm.transaction_error_rate/alerts/rule/getBackfill", + "alerting:apm.transaction_error_rate/alerts/rule/findBackfill", + "alerting:apm.transaction_error_rate/alerts/rule/create", + "alerting:apm.transaction_error_rate/alerts/rule/delete", + "alerting:apm.transaction_error_rate/alerts/rule/update", + "alerting:apm.transaction_error_rate/alerts/rule/updateApiKey", + "alerting:apm.transaction_error_rate/alerts/rule/enable", + "alerting:apm.transaction_error_rate/alerts/rule/disable", + "alerting:apm.transaction_error_rate/alerts/rule/muteAll", + "alerting:apm.transaction_error_rate/alerts/rule/unmuteAll", + "alerting:apm.transaction_error_rate/alerts/rule/muteAlert", + "alerting:apm.transaction_error_rate/alerts/rule/unmuteAlert", + "alerting:apm.transaction_error_rate/alerts/rule/snooze", + "alerting:apm.transaction_error_rate/alerts/rule/bulkEdit", + "alerting:apm.transaction_error_rate/alerts/rule/bulkDelete", + "alerting:apm.transaction_error_rate/alerts/rule/bulkEnable", + "alerting:apm.transaction_error_rate/alerts/rule/bulkDisable", + "alerting:apm.transaction_error_rate/alerts/rule/unsnooze", + "alerting:apm.transaction_error_rate/alerts/rule/runSoon", + "alerting:apm.transaction_error_rate/alerts/rule/scheduleBackfill", + "alerting:apm.transaction_error_rate/alerts/rule/deleteBackfill", "alerting:apm.transaction_duration/observability/rule/get", "alerting:apm.transaction_duration/observability/rule/getRuleState", "alerting:apm.transaction_duration/observability/rule/getAlertSummary", @@ -8134,6 +15559,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.transaction_duration/observability/rule/runSoon", "alerting:apm.transaction_duration/observability/rule/scheduleBackfill", "alerting:apm.transaction_duration/observability/rule/deleteBackfill", + "alerting:apm.transaction_duration/alerts/rule/get", + "alerting:apm.transaction_duration/alerts/rule/getRuleState", + "alerting:apm.transaction_duration/alerts/rule/getAlertSummary", + "alerting:apm.transaction_duration/alerts/rule/getExecutionLog", + "alerting:apm.transaction_duration/alerts/rule/getActionErrorLog", + "alerting:apm.transaction_duration/alerts/rule/find", + "alerting:apm.transaction_duration/alerts/rule/getRuleExecutionKPI", + "alerting:apm.transaction_duration/alerts/rule/getBackfill", + "alerting:apm.transaction_duration/alerts/rule/findBackfill", + "alerting:apm.transaction_duration/alerts/rule/create", + "alerting:apm.transaction_duration/alerts/rule/delete", + "alerting:apm.transaction_duration/alerts/rule/update", + "alerting:apm.transaction_duration/alerts/rule/updateApiKey", + "alerting:apm.transaction_duration/alerts/rule/enable", + "alerting:apm.transaction_duration/alerts/rule/disable", + "alerting:apm.transaction_duration/alerts/rule/muteAll", + "alerting:apm.transaction_duration/alerts/rule/unmuteAll", + "alerting:apm.transaction_duration/alerts/rule/muteAlert", + "alerting:apm.transaction_duration/alerts/rule/unmuteAlert", + "alerting:apm.transaction_duration/alerts/rule/snooze", + "alerting:apm.transaction_duration/alerts/rule/bulkEdit", + "alerting:apm.transaction_duration/alerts/rule/bulkDelete", + "alerting:apm.transaction_duration/alerts/rule/bulkEnable", + "alerting:apm.transaction_duration/alerts/rule/bulkDisable", + "alerting:apm.transaction_duration/alerts/rule/unsnooze", + "alerting:apm.transaction_duration/alerts/rule/runSoon", + "alerting:apm.transaction_duration/alerts/rule/scheduleBackfill", + "alerting:apm.transaction_duration/alerts/rule/deleteBackfill", "alerting:apm.anomaly/observability/rule/get", "alerting:apm.anomaly/observability/rule/getRuleState", "alerting:apm.anomaly/observability/rule/getAlertSummary", @@ -8162,6 +15615,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.anomaly/observability/rule/runSoon", "alerting:apm.anomaly/observability/rule/scheduleBackfill", "alerting:apm.anomaly/observability/rule/deleteBackfill", + "alerting:apm.anomaly/alerts/rule/get", + "alerting:apm.anomaly/alerts/rule/getRuleState", + "alerting:apm.anomaly/alerts/rule/getAlertSummary", + "alerting:apm.anomaly/alerts/rule/getExecutionLog", + "alerting:apm.anomaly/alerts/rule/getActionErrorLog", + "alerting:apm.anomaly/alerts/rule/find", + "alerting:apm.anomaly/alerts/rule/getRuleExecutionKPI", + "alerting:apm.anomaly/alerts/rule/getBackfill", + "alerting:apm.anomaly/alerts/rule/findBackfill", + "alerting:apm.anomaly/alerts/rule/create", + "alerting:apm.anomaly/alerts/rule/delete", + "alerting:apm.anomaly/alerts/rule/update", + "alerting:apm.anomaly/alerts/rule/updateApiKey", + "alerting:apm.anomaly/alerts/rule/enable", + "alerting:apm.anomaly/alerts/rule/disable", + "alerting:apm.anomaly/alerts/rule/muteAll", + "alerting:apm.anomaly/alerts/rule/unmuteAll", + "alerting:apm.anomaly/alerts/rule/muteAlert", + "alerting:apm.anomaly/alerts/rule/unmuteAlert", + "alerting:apm.anomaly/alerts/rule/snooze", + "alerting:apm.anomaly/alerts/rule/bulkEdit", + "alerting:apm.anomaly/alerts/rule/bulkDelete", + "alerting:apm.anomaly/alerts/rule/bulkEnable", + "alerting:apm.anomaly/alerts/rule/bulkDisable", + "alerting:apm.anomaly/alerts/rule/unsnooze", + "alerting:apm.anomaly/alerts/rule/runSoon", + "alerting:apm.anomaly/alerts/rule/scheduleBackfill", + "alerting:apm.anomaly/alerts/rule/deleteBackfill", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/get", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/getRuleState", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/getAlertSummary", @@ -8190,6 +15671,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/runSoon", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/scheduleBackfill", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/deleteBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/get", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getRuleState", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getAlertSummary", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getExecutionLog", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getActionErrorLog", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/find", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/findBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/create", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/delete", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/update", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/updateApiKey", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/enable", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/disable", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/muteAll", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/unmuteAll", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/muteAlert", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/unmuteAlert", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/snooze", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/bulkEdit", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/bulkDelete", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/bulkEnable", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/bulkDisable", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/unsnooze", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/runSoon", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/scheduleBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/deleteBackfill", "alerting:xpack.synthetics.alerts.tls/observability/rule/get", "alerting:xpack.synthetics.alerts.tls/observability/rule/getRuleState", "alerting:xpack.synthetics.alerts.tls/observability/rule/getAlertSummary", @@ -8218,61 +15727,787 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.synthetics.alerts.tls/observability/rule/runSoon", "alerting:xpack.synthetics.alerts.tls/observability/rule/scheduleBackfill", "alerting:xpack.synthetics.alerts.tls/observability/rule/deleteBackfill", - "alerting:slo.rules.burnRate/observability/alert/get", - "alerting:slo.rules.burnRate/observability/alert/find", - "alerting:slo.rules.burnRate/observability/alert/getAuthorizedAlertsIndices", - "alerting:slo.rules.burnRate/observability/alert/getAlertSummary", - "alerting:slo.rules.burnRate/observability/alert/update", - "alerting:observability.rules.custom_threshold/observability/alert/get", - "alerting:observability.rules.custom_threshold/observability/alert/find", - "alerting:observability.rules.custom_threshold/observability/alert/getAuthorizedAlertsIndices", - "alerting:observability.rules.custom_threshold/observability/alert/getAlertSummary", - "alerting:observability.rules.custom_threshold/observability/alert/update", - "alerting:.es-query/observability/alert/get", - "alerting:.es-query/observability/alert/find", - "alerting:.es-query/observability/alert/getAuthorizedAlertsIndices", - "alerting:.es-query/observability/alert/getAlertSummary", - "alerting:.es-query/observability/alert/update", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/get", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/find", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAuthorizedAlertsIndices", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAlertSummary", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/update", - "alerting:metrics.alert.inventory.threshold/observability/alert/get", - "alerting:metrics.alert.inventory.threshold/observability/alert/find", - "alerting:metrics.alert.inventory.threshold/observability/alert/getAuthorizedAlertsIndices", - "alerting:metrics.alert.inventory.threshold/observability/alert/getAlertSummary", - "alerting:metrics.alert.inventory.threshold/observability/alert/update", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/get", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getRuleState", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getAlertSummary", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getExecutionLog", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getActionErrorLog", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/find", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getBackfill", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/findBackfill", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/create", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/delete", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/update", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/updateApiKey", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/enable", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/disable", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/muteAll", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/unmuteAll", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/muteAlert", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/unmuteAlert", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/snooze", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/bulkEdit", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/bulkDelete", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/bulkEnable", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/bulkDisable", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/unsnooze", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/runSoon", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/scheduleBackfill", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/deleteBackfill", + "alerting:metrics.alert.threshold/observability/rule/get", + "alerting:metrics.alert.threshold/observability/rule/getRuleState", + "alerting:metrics.alert.threshold/observability/rule/getAlertSummary", + "alerting:metrics.alert.threshold/observability/rule/getExecutionLog", + "alerting:metrics.alert.threshold/observability/rule/getActionErrorLog", + "alerting:metrics.alert.threshold/observability/rule/find", + "alerting:metrics.alert.threshold/observability/rule/getRuleExecutionKPI", + "alerting:metrics.alert.threshold/observability/rule/getBackfill", + "alerting:metrics.alert.threshold/observability/rule/findBackfill", + "alerting:metrics.alert.threshold/observability/rule/create", + "alerting:metrics.alert.threshold/observability/rule/delete", + "alerting:metrics.alert.threshold/observability/rule/update", + "alerting:metrics.alert.threshold/observability/rule/updateApiKey", + "alerting:metrics.alert.threshold/observability/rule/enable", + "alerting:metrics.alert.threshold/observability/rule/disable", + "alerting:metrics.alert.threshold/observability/rule/muteAll", + "alerting:metrics.alert.threshold/observability/rule/unmuteAll", + "alerting:metrics.alert.threshold/observability/rule/muteAlert", + "alerting:metrics.alert.threshold/observability/rule/unmuteAlert", + "alerting:metrics.alert.threshold/observability/rule/snooze", + "alerting:metrics.alert.threshold/observability/rule/bulkEdit", + "alerting:metrics.alert.threshold/observability/rule/bulkDelete", + "alerting:metrics.alert.threshold/observability/rule/bulkEnable", + "alerting:metrics.alert.threshold/observability/rule/bulkDisable", + "alerting:metrics.alert.threshold/observability/rule/unsnooze", + "alerting:metrics.alert.threshold/observability/rule/runSoon", + "alerting:metrics.alert.threshold/observability/rule/scheduleBackfill", + "alerting:metrics.alert.threshold/observability/rule/deleteBackfill", + "alerting:metrics.alert.threshold/alerts/rule/get", + "alerting:metrics.alert.threshold/alerts/rule/getRuleState", + "alerting:metrics.alert.threshold/alerts/rule/getAlertSummary", + "alerting:metrics.alert.threshold/alerts/rule/getExecutionLog", + "alerting:metrics.alert.threshold/alerts/rule/getActionErrorLog", + "alerting:metrics.alert.threshold/alerts/rule/find", + "alerting:metrics.alert.threshold/alerts/rule/getRuleExecutionKPI", + "alerting:metrics.alert.threshold/alerts/rule/getBackfill", + "alerting:metrics.alert.threshold/alerts/rule/findBackfill", + "alerting:metrics.alert.threshold/alerts/rule/create", + "alerting:metrics.alert.threshold/alerts/rule/delete", + "alerting:metrics.alert.threshold/alerts/rule/update", + "alerting:metrics.alert.threshold/alerts/rule/updateApiKey", + "alerting:metrics.alert.threshold/alerts/rule/enable", + "alerting:metrics.alert.threshold/alerts/rule/disable", + "alerting:metrics.alert.threshold/alerts/rule/muteAll", + "alerting:metrics.alert.threshold/alerts/rule/unmuteAll", + "alerting:metrics.alert.threshold/alerts/rule/muteAlert", + "alerting:metrics.alert.threshold/alerts/rule/unmuteAlert", + "alerting:metrics.alert.threshold/alerts/rule/snooze", + "alerting:metrics.alert.threshold/alerts/rule/bulkEdit", + "alerting:metrics.alert.threshold/alerts/rule/bulkDelete", + "alerting:metrics.alert.threshold/alerts/rule/bulkEnable", + "alerting:metrics.alert.threshold/alerts/rule/bulkDisable", + "alerting:metrics.alert.threshold/alerts/rule/unsnooze", + "alerting:metrics.alert.threshold/alerts/rule/runSoon", + "alerting:metrics.alert.threshold/alerts/rule/scheduleBackfill", + "alerting:metrics.alert.threshold/alerts/rule/deleteBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/get", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleState", + "alerting:metrics.alert.inventory.threshold/observability/rule/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/rule/getExecutionLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/getActionErrorLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/find", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleExecutionKPI", + "alerting:metrics.alert.inventory.threshold/observability/rule/getBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/findBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/create", + "alerting:metrics.alert.inventory.threshold/observability/rule/delete", + "alerting:metrics.alert.inventory.threshold/observability/rule/update", + "alerting:metrics.alert.inventory.threshold/observability/rule/updateApiKey", + "alerting:metrics.alert.inventory.threshold/observability/rule/enable", + "alerting:metrics.alert.inventory.threshold/observability/rule/disable", + "alerting:metrics.alert.inventory.threshold/observability/rule/muteAll", + "alerting:metrics.alert.inventory.threshold/observability/rule/unmuteAll", + "alerting:metrics.alert.inventory.threshold/observability/rule/muteAlert", + "alerting:metrics.alert.inventory.threshold/observability/rule/unmuteAlert", + "alerting:metrics.alert.inventory.threshold/observability/rule/snooze", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkEdit", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkDelete", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkEnable", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkDisable", + "alerting:metrics.alert.inventory.threshold/observability/rule/unsnooze", + "alerting:metrics.alert.inventory.threshold/observability/rule/runSoon", + "alerting:metrics.alert.inventory.threshold/observability/rule/scheduleBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/deleteBackfill", + "alerting:metrics.alert.inventory.threshold/alerts/rule/get", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getRuleState", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getExecutionLog", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getActionErrorLog", + "alerting:metrics.alert.inventory.threshold/alerts/rule/find", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getRuleExecutionKPI", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getBackfill", + "alerting:metrics.alert.inventory.threshold/alerts/rule/findBackfill", + "alerting:metrics.alert.inventory.threshold/alerts/rule/create", + "alerting:metrics.alert.inventory.threshold/alerts/rule/delete", + "alerting:metrics.alert.inventory.threshold/alerts/rule/update", + "alerting:metrics.alert.inventory.threshold/alerts/rule/updateApiKey", + "alerting:metrics.alert.inventory.threshold/alerts/rule/enable", + "alerting:metrics.alert.inventory.threshold/alerts/rule/disable", + "alerting:metrics.alert.inventory.threshold/alerts/rule/muteAll", + "alerting:metrics.alert.inventory.threshold/alerts/rule/unmuteAll", + "alerting:metrics.alert.inventory.threshold/alerts/rule/muteAlert", + "alerting:metrics.alert.inventory.threshold/alerts/rule/unmuteAlert", + "alerting:metrics.alert.inventory.threshold/alerts/rule/snooze", + "alerting:metrics.alert.inventory.threshold/alerts/rule/bulkEdit", + "alerting:metrics.alert.inventory.threshold/alerts/rule/bulkDelete", + "alerting:metrics.alert.inventory.threshold/alerts/rule/bulkEnable", + "alerting:metrics.alert.inventory.threshold/alerts/rule/bulkDisable", + "alerting:metrics.alert.inventory.threshold/alerts/rule/unsnooze", + "alerting:metrics.alert.inventory.threshold/alerts/rule/runSoon", + "alerting:metrics.alert.inventory.threshold/alerts/rule/scheduleBackfill", + "alerting:metrics.alert.inventory.threshold/alerts/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.tls/observability/rule/get", + "alerting:xpack.uptime.alerts.tls/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.tls/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tls/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tls/observability/rule/find", + "alerting:xpack.uptime.alerts.tls/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tls/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.tls/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.tls/observability/rule/create", + "alerting:xpack.uptime.alerts.tls/observability/rule/delete", + "alerting:xpack.uptime.alerts.tls/observability/rule/update", + "alerting:xpack.uptime.alerts.tls/observability/rule/updateApiKey", + "alerting:xpack.uptime.alerts.tls/observability/rule/enable", + "alerting:xpack.uptime.alerts.tls/observability/rule/disable", + "alerting:xpack.uptime.alerts.tls/observability/rule/muteAll", + "alerting:xpack.uptime.alerts.tls/observability/rule/unmuteAll", + "alerting:xpack.uptime.alerts.tls/observability/rule/muteAlert", + "alerting:xpack.uptime.alerts.tls/observability/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.tls/observability/rule/snooze", + "alerting:xpack.uptime.alerts.tls/observability/rule/bulkEdit", + "alerting:xpack.uptime.alerts.tls/observability/rule/bulkDelete", + "alerting:xpack.uptime.alerts.tls/observability/rule/bulkEnable", + "alerting:xpack.uptime.alerts.tls/observability/rule/bulkDisable", + "alerting:xpack.uptime.alerts.tls/observability/rule/unsnooze", + "alerting:xpack.uptime.alerts.tls/observability/rule/runSoon", + "alerting:xpack.uptime.alerts.tls/observability/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.tls/observability/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.tls/alerts/rule/get", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tls/alerts/rule/find", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.tls/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.tls/alerts/rule/create", + "alerting:xpack.uptime.alerts.tls/alerts/rule/delete", + "alerting:xpack.uptime.alerts.tls/alerts/rule/update", + "alerting:xpack.uptime.alerts.tls/alerts/rule/updateApiKey", + "alerting:xpack.uptime.alerts.tls/alerts/rule/enable", + "alerting:xpack.uptime.alerts.tls/alerts/rule/disable", + "alerting:xpack.uptime.alerts.tls/alerts/rule/muteAll", + "alerting:xpack.uptime.alerts.tls/alerts/rule/unmuteAll", + "alerting:xpack.uptime.alerts.tls/alerts/rule/muteAlert", + "alerting:xpack.uptime.alerts.tls/alerts/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.tls/alerts/rule/snooze", + "alerting:xpack.uptime.alerts.tls/alerts/rule/bulkEdit", + "alerting:xpack.uptime.alerts.tls/alerts/rule/bulkDelete", + "alerting:xpack.uptime.alerts.tls/alerts/rule/bulkEnable", + "alerting:xpack.uptime.alerts.tls/alerts/rule/bulkDisable", + "alerting:xpack.uptime.alerts.tls/alerts/rule/unsnooze", + "alerting:xpack.uptime.alerts.tls/alerts/rule/runSoon", + "alerting:xpack.uptime.alerts.tls/alerts/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.tls/alerts/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/get", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/find", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/create", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/delete", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/update", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/updateApiKey", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/enable", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/disable", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/muteAll", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/unmuteAll", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/muteAlert", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/snooze", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/bulkEdit", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/bulkDelete", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/bulkEnable", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/bulkDisable", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/unsnooze", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/runSoon", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/get", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/find", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/create", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/delete", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/update", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/updateApiKey", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/enable", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/disable", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/muteAll", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/unmuteAll", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/muteAlert", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/snooze", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/bulkEdit", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/bulkDelete", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/bulkEnable", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/bulkDisable", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/unsnooze", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/runSoon", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/get", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/find", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/create", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/delete", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/update", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/updateApiKey", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/enable", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/disable", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/muteAll", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/unmuteAll", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/muteAlert", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/snooze", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/bulkEdit", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/bulkDelete", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/bulkEnable", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/bulkDisable", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/unsnooze", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/runSoon", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/get", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/find", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/create", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/delete", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/update", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/updateApiKey", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/enable", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/disable", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/muteAll", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/unmuteAll", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/muteAlert", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/snooze", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/bulkEdit", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/bulkDelete", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/bulkEnable", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/bulkDisable", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/unsnooze", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/runSoon", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/get", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/find", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/create", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/delete", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/update", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/updateApiKey", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/enable", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/disable", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/muteAll", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/unmuteAll", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/muteAlert", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/snooze", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/bulkEdit", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/bulkDelete", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/bulkEnable", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/bulkDisable", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/unsnooze", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/runSoon", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/get", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/find", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/create", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/delete", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/update", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/updateApiKey", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/enable", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/disable", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/muteAll", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/unmuteAll", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/muteAlert", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/snooze", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/bulkEdit", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/bulkDelete", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/bulkEnable", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/bulkDisable", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/unsnooze", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/runSoon", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/deleteBackfill", + "alerting:logs.alert.document.count/observability/rule/get", + "alerting:logs.alert.document.count/observability/rule/getRuleState", + "alerting:logs.alert.document.count/observability/rule/getAlertSummary", + "alerting:logs.alert.document.count/observability/rule/getExecutionLog", + "alerting:logs.alert.document.count/observability/rule/getActionErrorLog", + "alerting:logs.alert.document.count/observability/rule/find", + "alerting:logs.alert.document.count/observability/rule/getRuleExecutionKPI", + "alerting:logs.alert.document.count/observability/rule/getBackfill", + "alerting:logs.alert.document.count/observability/rule/findBackfill", + "alerting:logs.alert.document.count/observability/rule/create", + "alerting:logs.alert.document.count/observability/rule/delete", + "alerting:logs.alert.document.count/observability/rule/update", + "alerting:logs.alert.document.count/observability/rule/updateApiKey", + "alerting:logs.alert.document.count/observability/rule/enable", + "alerting:logs.alert.document.count/observability/rule/disable", + "alerting:logs.alert.document.count/observability/rule/muteAll", + "alerting:logs.alert.document.count/observability/rule/unmuteAll", + "alerting:logs.alert.document.count/observability/rule/muteAlert", + "alerting:logs.alert.document.count/observability/rule/unmuteAlert", + "alerting:logs.alert.document.count/observability/rule/snooze", + "alerting:logs.alert.document.count/observability/rule/bulkEdit", + "alerting:logs.alert.document.count/observability/rule/bulkDelete", + "alerting:logs.alert.document.count/observability/rule/bulkEnable", + "alerting:logs.alert.document.count/observability/rule/bulkDisable", + "alerting:logs.alert.document.count/observability/rule/unsnooze", + "alerting:logs.alert.document.count/observability/rule/runSoon", + "alerting:logs.alert.document.count/observability/rule/scheduleBackfill", + "alerting:logs.alert.document.count/observability/rule/deleteBackfill", + "alerting:logs.alert.document.count/alerts/rule/get", + "alerting:logs.alert.document.count/alerts/rule/getRuleState", + "alerting:logs.alert.document.count/alerts/rule/getAlertSummary", + "alerting:logs.alert.document.count/alerts/rule/getExecutionLog", + "alerting:logs.alert.document.count/alerts/rule/getActionErrorLog", + "alerting:logs.alert.document.count/alerts/rule/find", + "alerting:logs.alert.document.count/alerts/rule/getRuleExecutionKPI", + "alerting:logs.alert.document.count/alerts/rule/getBackfill", + "alerting:logs.alert.document.count/alerts/rule/findBackfill", + "alerting:logs.alert.document.count/alerts/rule/create", + "alerting:logs.alert.document.count/alerts/rule/delete", + "alerting:logs.alert.document.count/alerts/rule/update", + "alerting:logs.alert.document.count/alerts/rule/updateApiKey", + "alerting:logs.alert.document.count/alerts/rule/enable", + "alerting:logs.alert.document.count/alerts/rule/disable", + "alerting:logs.alert.document.count/alerts/rule/muteAll", + "alerting:logs.alert.document.count/alerts/rule/unmuteAll", + "alerting:logs.alert.document.count/alerts/rule/muteAlert", + "alerting:logs.alert.document.count/alerts/rule/unmuteAlert", + "alerting:logs.alert.document.count/alerts/rule/snooze", + "alerting:logs.alert.document.count/alerts/rule/bulkEdit", + "alerting:logs.alert.document.count/alerts/rule/bulkDelete", + "alerting:logs.alert.document.count/alerts/rule/bulkEnable", + "alerting:logs.alert.document.count/alerts/rule/bulkDisable", + "alerting:logs.alert.document.count/alerts/rule/unsnooze", + "alerting:logs.alert.document.count/alerts/rule/runSoon", + "alerting:logs.alert.document.count/alerts/rule/scheduleBackfill", + "alerting:logs.alert.document.count/alerts/rule/deleteBackfill", + "alerting:slo.rules.burnRate/observability/rule/get", + "alerting:slo.rules.burnRate/observability/rule/getRuleState", + "alerting:slo.rules.burnRate/observability/rule/getAlertSummary", + "alerting:slo.rules.burnRate/observability/rule/getExecutionLog", + "alerting:slo.rules.burnRate/observability/rule/getActionErrorLog", + "alerting:slo.rules.burnRate/observability/rule/find", + "alerting:slo.rules.burnRate/observability/rule/getRuleExecutionKPI", + "alerting:slo.rules.burnRate/observability/rule/getBackfill", + "alerting:slo.rules.burnRate/observability/rule/findBackfill", + "alerting:slo.rules.burnRate/observability/rule/create", + "alerting:slo.rules.burnRate/observability/rule/delete", + "alerting:slo.rules.burnRate/observability/rule/update", + "alerting:slo.rules.burnRate/observability/rule/updateApiKey", + "alerting:slo.rules.burnRate/observability/rule/enable", + "alerting:slo.rules.burnRate/observability/rule/disable", + "alerting:slo.rules.burnRate/observability/rule/muteAll", + "alerting:slo.rules.burnRate/observability/rule/unmuteAll", + "alerting:slo.rules.burnRate/observability/rule/muteAlert", + "alerting:slo.rules.burnRate/observability/rule/unmuteAlert", + "alerting:slo.rules.burnRate/observability/rule/snooze", + "alerting:slo.rules.burnRate/observability/rule/bulkEdit", + "alerting:slo.rules.burnRate/observability/rule/bulkDelete", + "alerting:slo.rules.burnRate/observability/rule/bulkEnable", + "alerting:slo.rules.burnRate/observability/rule/bulkDisable", + "alerting:slo.rules.burnRate/observability/rule/unsnooze", + "alerting:slo.rules.burnRate/observability/rule/runSoon", + "alerting:slo.rules.burnRate/observability/rule/scheduleBackfill", + "alerting:slo.rules.burnRate/observability/rule/deleteBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/get", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleState", + "alerting:observability.rules.custom_threshold/observability/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/observability/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/observability/rule/find", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/observability/rule/getBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/findBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/create", + "alerting:observability.rules.custom_threshold/observability/rule/delete", + "alerting:observability.rules.custom_threshold/observability/rule/update", + "alerting:observability.rules.custom_threshold/observability/rule/updateApiKey", + "alerting:observability.rules.custom_threshold/observability/rule/enable", + "alerting:observability.rules.custom_threshold/observability/rule/disable", + "alerting:observability.rules.custom_threshold/observability/rule/muteAll", + "alerting:observability.rules.custom_threshold/observability/rule/unmuteAll", + "alerting:observability.rules.custom_threshold/observability/rule/muteAlert", + "alerting:observability.rules.custom_threshold/observability/rule/unmuteAlert", + "alerting:observability.rules.custom_threshold/observability/rule/snooze", + "alerting:observability.rules.custom_threshold/observability/rule/bulkEdit", + "alerting:observability.rules.custom_threshold/observability/rule/bulkDelete", + "alerting:observability.rules.custom_threshold/observability/rule/bulkEnable", + "alerting:observability.rules.custom_threshold/observability/rule/bulkDisable", + "alerting:observability.rules.custom_threshold/observability/rule/unsnooze", + "alerting:observability.rules.custom_threshold/observability/rule/runSoon", + "alerting:observability.rules.custom_threshold/observability/rule/scheduleBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/deleteBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/get", + "alerting:observability.rules.custom_threshold/alerts/rule/getRuleState", + "alerting:observability.rules.custom_threshold/alerts/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/alerts/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/alerts/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/alerts/rule/find", + "alerting:observability.rules.custom_threshold/alerts/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/alerts/rule/getBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/findBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/create", + "alerting:observability.rules.custom_threshold/alerts/rule/delete", + "alerting:observability.rules.custom_threshold/alerts/rule/update", + "alerting:observability.rules.custom_threshold/alerts/rule/updateApiKey", + "alerting:observability.rules.custom_threshold/alerts/rule/enable", + "alerting:observability.rules.custom_threshold/alerts/rule/disable", + "alerting:observability.rules.custom_threshold/alerts/rule/muteAll", + "alerting:observability.rules.custom_threshold/alerts/rule/unmuteAll", + "alerting:observability.rules.custom_threshold/alerts/rule/muteAlert", + "alerting:observability.rules.custom_threshold/alerts/rule/unmuteAlert", + "alerting:observability.rules.custom_threshold/alerts/rule/snooze", + "alerting:observability.rules.custom_threshold/alerts/rule/bulkEdit", + "alerting:observability.rules.custom_threshold/alerts/rule/bulkDelete", + "alerting:observability.rules.custom_threshold/alerts/rule/bulkEnable", + "alerting:observability.rules.custom_threshold/alerts/rule/bulkDisable", + "alerting:observability.rules.custom_threshold/alerts/rule/unsnooze", + "alerting:observability.rules.custom_threshold/alerts/rule/runSoon", + "alerting:observability.rules.custom_threshold/alerts/rule/scheduleBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/deleteBackfill", + "alerting:.es-query/observability/rule/get", + "alerting:.es-query/observability/rule/getRuleState", + "alerting:.es-query/observability/rule/getAlertSummary", + "alerting:.es-query/observability/rule/getExecutionLog", + "alerting:.es-query/observability/rule/getActionErrorLog", + "alerting:.es-query/observability/rule/find", + "alerting:.es-query/observability/rule/getRuleExecutionKPI", + "alerting:.es-query/observability/rule/getBackfill", + "alerting:.es-query/observability/rule/findBackfill", + "alerting:.es-query/observability/rule/create", + "alerting:.es-query/observability/rule/delete", + "alerting:.es-query/observability/rule/update", + "alerting:.es-query/observability/rule/updateApiKey", + "alerting:.es-query/observability/rule/enable", + "alerting:.es-query/observability/rule/disable", + "alerting:.es-query/observability/rule/muteAll", + "alerting:.es-query/observability/rule/unmuteAll", + "alerting:.es-query/observability/rule/muteAlert", + "alerting:.es-query/observability/rule/unmuteAlert", + "alerting:.es-query/observability/rule/snooze", + "alerting:.es-query/observability/rule/bulkEdit", + "alerting:.es-query/observability/rule/bulkDelete", + "alerting:.es-query/observability/rule/bulkEnable", + "alerting:.es-query/observability/rule/bulkDisable", + "alerting:.es-query/observability/rule/unsnooze", + "alerting:.es-query/observability/rule/runSoon", + "alerting:.es-query/observability/rule/scheduleBackfill", + "alerting:.es-query/observability/rule/deleteBackfill", + "alerting:.es-query/alerts/rule/get", + "alerting:.es-query/alerts/rule/getRuleState", + "alerting:.es-query/alerts/rule/getAlertSummary", + "alerting:.es-query/alerts/rule/getExecutionLog", + "alerting:.es-query/alerts/rule/getActionErrorLog", + "alerting:.es-query/alerts/rule/find", + "alerting:.es-query/alerts/rule/getRuleExecutionKPI", + "alerting:.es-query/alerts/rule/getBackfill", + "alerting:.es-query/alerts/rule/findBackfill", + "alerting:.es-query/alerts/rule/create", + "alerting:.es-query/alerts/rule/delete", + "alerting:.es-query/alerts/rule/update", + "alerting:.es-query/alerts/rule/updateApiKey", + "alerting:.es-query/alerts/rule/enable", + "alerting:.es-query/alerts/rule/disable", + "alerting:.es-query/alerts/rule/muteAll", + "alerting:.es-query/alerts/rule/unmuteAll", + "alerting:.es-query/alerts/rule/muteAlert", + "alerting:.es-query/alerts/rule/unmuteAlert", + "alerting:.es-query/alerts/rule/snooze", + "alerting:.es-query/alerts/rule/bulkEdit", + "alerting:.es-query/alerts/rule/bulkDelete", + "alerting:.es-query/alerts/rule/bulkEnable", + "alerting:.es-query/alerts/rule/bulkDisable", + "alerting:.es-query/alerts/rule/unsnooze", + "alerting:.es-query/alerts/rule/runSoon", + "alerting:.es-query/alerts/rule/scheduleBackfill", + "alerting:.es-query/alerts/rule/deleteBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/create", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/delete", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/update", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/updateApiKey", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/enable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/disable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/muteAll", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unmuteAll", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/muteAlert", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unmuteAlert", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/snooze", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkEdit", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkDelete", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkEnable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkDisable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unsnooze", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/runSoon", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/scheduleBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/deleteBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/create", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/delete", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/update", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/updateApiKey", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/enable", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/disable", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/muteAll", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/unmuteAll", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/muteAlert", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/unmuteAlert", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/snooze", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/bulkEdit", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/bulkDelete", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/bulkEnable", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/bulkDisable", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/unsnooze", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/runSoon", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/scheduleBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/deleteBackfill", "alerting:apm.error_rate/observability/alert/get", "alerting:apm.error_rate/observability/alert/find", "alerting:apm.error_rate/observability/alert/getAuthorizedAlertsIndices", "alerting:apm.error_rate/observability/alert/getAlertSummary", "alerting:apm.error_rate/observability/alert/update", + "alerting:apm.error_rate/alerts/alert/get", + "alerting:apm.error_rate/alerts/alert/find", + "alerting:apm.error_rate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.error_rate/alerts/alert/getAlertSummary", + "alerting:apm.error_rate/alerts/alert/update", "alerting:apm.transaction_error_rate/observability/alert/get", "alerting:apm.transaction_error_rate/observability/alert/find", "alerting:apm.transaction_error_rate/observability/alert/getAuthorizedAlertsIndices", "alerting:apm.transaction_error_rate/observability/alert/getAlertSummary", "alerting:apm.transaction_error_rate/observability/alert/update", + "alerting:apm.transaction_error_rate/alerts/alert/get", + "alerting:apm.transaction_error_rate/alerts/alert/find", + "alerting:apm.transaction_error_rate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_error_rate/alerts/alert/getAlertSummary", + "alerting:apm.transaction_error_rate/alerts/alert/update", "alerting:apm.transaction_duration/observability/alert/get", "alerting:apm.transaction_duration/observability/alert/find", "alerting:apm.transaction_duration/observability/alert/getAuthorizedAlertsIndices", "alerting:apm.transaction_duration/observability/alert/getAlertSummary", "alerting:apm.transaction_duration/observability/alert/update", + "alerting:apm.transaction_duration/alerts/alert/get", + "alerting:apm.transaction_duration/alerts/alert/find", + "alerting:apm.transaction_duration/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_duration/alerts/alert/getAlertSummary", + "alerting:apm.transaction_duration/alerts/alert/update", "alerting:apm.anomaly/observability/alert/get", "alerting:apm.anomaly/observability/alert/find", "alerting:apm.anomaly/observability/alert/getAuthorizedAlertsIndices", "alerting:apm.anomaly/observability/alert/getAlertSummary", "alerting:apm.anomaly/observability/alert/update", + "alerting:apm.anomaly/alerts/alert/get", + "alerting:apm.anomaly/alerts/alert/find", + "alerting:apm.anomaly/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.anomaly/alerts/alert/getAlertSummary", + "alerting:apm.anomaly/alerts/alert/update", "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/get", "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/find", "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/getAuthorizedAlertsIndices", "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/getAlertSummary", "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/update", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/get", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/find", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/getAlertSummary", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/update", "alerting:xpack.synthetics.alerts.tls/observability/alert/get", "alerting:xpack.synthetics.alerts.tls/observability/alert/find", "alerting:xpack.synthetics.alerts.tls/observability/alert/getAuthorizedAlertsIndices", "alerting:xpack.synthetics.alerts.tls/observability/alert/getAlertSummary", "alerting:xpack.synthetics.alerts.tls/observability/alert/update", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/get", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/find", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/getAlertSummary", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/update", + "alerting:metrics.alert.threshold/observability/alert/get", + "alerting:metrics.alert.threshold/observability/alert/find", + "alerting:metrics.alert.threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.threshold/observability/alert/getAlertSummary", + "alerting:metrics.alert.threshold/observability/alert/update", + "alerting:metrics.alert.threshold/alerts/alert/get", + "alerting:metrics.alert.threshold/alerts/alert/find", + "alerting:metrics.alert.threshold/alerts/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.threshold/alerts/alert/getAlertSummary", + "alerting:metrics.alert.threshold/alerts/alert/update", + "alerting:metrics.alert.inventory.threshold/observability/alert/get", + "alerting:metrics.alert.inventory.threshold/observability/alert/find", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/alert/update", + "alerting:metrics.alert.inventory.threshold/alerts/alert/get", + "alerting:metrics.alert.inventory.threshold/alerts/alert/find", + "alerting:metrics.alert.inventory.threshold/alerts/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.inventory.threshold/alerts/alert/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/alerts/alert/update", + "alerting:xpack.uptime.alerts.tls/observability/alert/get", + "alerting:xpack.uptime.alerts.tls/observability/alert/find", + "alerting:xpack.uptime.alerts.tls/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tls/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/observability/alert/update", + "alerting:xpack.uptime.alerts.tls/alerts/alert/get", + "alerting:xpack.uptime.alerts.tls/alerts/alert/find", + "alerting:xpack.uptime.alerts.tls/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tls/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/alerts/alert/update", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/get", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/find", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/update", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/get", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/find", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/update", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/get", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/find", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/update", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/get", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/find", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/update", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/get", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/find", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/update", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/get", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/find", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/update", + "alerting:logs.alert.document.count/observability/alert/get", + "alerting:logs.alert.document.count/observability/alert/find", + "alerting:logs.alert.document.count/observability/alert/getAuthorizedAlertsIndices", + "alerting:logs.alert.document.count/observability/alert/getAlertSummary", + "alerting:logs.alert.document.count/observability/alert/update", + "alerting:logs.alert.document.count/alerts/alert/get", + "alerting:logs.alert.document.count/alerts/alert/find", + "alerting:logs.alert.document.count/alerts/alert/getAuthorizedAlertsIndices", + "alerting:logs.alert.document.count/alerts/alert/getAlertSummary", + "alerting:logs.alert.document.count/alerts/alert/update", + "alerting:slo.rules.burnRate/observability/alert/get", + "alerting:slo.rules.burnRate/observability/alert/find", + "alerting:slo.rules.burnRate/observability/alert/getAuthorizedAlertsIndices", + "alerting:slo.rules.burnRate/observability/alert/getAlertSummary", + "alerting:slo.rules.burnRate/observability/alert/update", + "alerting:observability.rules.custom_threshold/observability/alert/get", + "alerting:observability.rules.custom_threshold/observability/alert/find", + "alerting:observability.rules.custom_threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/observability/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/alert/update", + "alerting:observability.rules.custom_threshold/alerts/alert/get", + "alerting:observability.rules.custom_threshold/alerts/alert/find", + "alerting:observability.rules.custom_threshold/alerts/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/alerts/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/alerts/alert/update", + "alerting:.es-query/observability/alert/get", + "alerting:.es-query/observability/alert/find", + "alerting:.es-query/observability/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/observability/alert/getAlertSummary", + "alerting:.es-query/observability/alert/update", + "alerting:.es-query/alerts/alert/get", + "alerting:.es-query/alerts/alert/find", + "alerting:.es-query/alerts/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/alerts/alert/getAlertSummary", + "alerting:.es-query/alerts/alert/update", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/update", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/update", ], "minimal_read": Array [ "login:", @@ -8314,68 +16549,36 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:url/find", "saved_object:url/open_point_in_time", "saved_object:url/close_point_in_time", - "ui:slo/read", - "alerting:slo.rules.burnRate/slo/rule/get", - "alerting:slo.rules.burnRate/slo/rule/getRuleState", - "alerting:slo.rules.burnRate/slo/rule/getAlertSummary", - "alerting:slo.rules.burnRate/slo/rule/getExecutionLog", - "alerting:slo.rules.burnRate/slo/rule/getActionErrorLog", - "alerting:slo.rules.burnRate/slo/rule/find", - "alerting:slo.rules.burnRate/slo/rule/getRuleExecutionKPI", - "alerting:slo.rules.burnRate/slo/rule/getBackfill", - "alerting:slo.rules.burnRate/slo/rule/findBackfill", - "alerting:slo.rules.burnRate/slo/alert/get", - "alerting:slo.rules.burnRate/slo/alert/find", - "alerting:slo.rules.burnRate/slo/alert/getAuthorizedAlertsIndices", - "alerting:slo.rules.burnRate/slo/alert/getAlertSummary", - "app:observability", - "ui:navLinks/observability", - "ui:observability/read", - "alerting:slo.rules.burnRate/observability/rule/get", - "alerting:slo.rules.burnRate/observability/rule/getRuleState", - "alerting:slo.rules.burnRate/observability/rule/getAlertSummary", - "alerting:slo.rules.burnRate/observability/rule/getExecutionLog", - "alerting:slo.rules.burnRate/observability/rule/getActionErrorLog", - "alerting:slo.rules.burnRate/observability/rule/find", - "alerting:slo.rules.burnRate/observability/rule/getRuleExecutionKPI", - "alerting:slo.rules.burnRate/observability/rule/getBackfill", - "alerting:slo.rules.burnRate/observability/rule/findBackfill", - "alerting:observability.rules.custom_threshold/observability/rule/get", - "alerting:observability.rules.custom_threshold/observability/rule/getRuleState", - "alerting:observability.rules.custom_threshold/observability/rule/getAlertSummary", - "alerting:observability.rules.custom_threshold/observability/rule/getExecutionLog", - "alerting:observability.rules.custom_threshold/observability/rule/getActionErrorLog", - "alerting:observability.rules.custom_threshold/observability/rule/find", - "alerting:observability.rules.custom_threshold/observability/rule/getRuleExecutionKPI", - "alerting:observability.rules.custom_threshold/observability/rule/getBackfill", - "alerting:observability.rules.custom_threshold/observability/rule/findBackfill", - "alerting:.es-query/observability/rule/get", - "alerting:.es-query/observability/rule/getRuleState", - "alerting:.es-query/observability/rule/getAlertSummary", - "alerting:.es-query/observability/rule/getExecutionLog", - "alerting:.es-query/observability/rule/getActionErrorLog", - "alerting:.es-query/observability/rule/find", - "alerting:.es-query/observability/rule/getRuleExecutionKPI", - "alerting:.es-query/observability/rule/getBackfill", - "alerting:.es-query/observability/rule/findBackfill", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/get", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleState", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getAlertSummary", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getExecutionLog", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getActionErrorLog", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/find", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleExecutionKPI", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getBackfill", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/findBackfill", - "alerting:metrics.alert.inventory.threshold/observability/rule/get", - "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleState", - "alerting:metrics.alert.inventory.threshold/observability/rule/getAlertSummary", - "alerting:metrics.alert.inventory.threshold/observability/rule/getExecutionLog", - "alerting:metrics.alert.inventory.threshold/observability/rule/getActionErrorLog", - "alerting:metrics.alert.inventory.threshold/observability/rule/find", - "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleExecutionKPI", - "alerting:metrics.alert.inventory.threshold/observability/rule/getBackfill", - "alerting:metrics.alert.inventory.threshold/observability/rule/findBackfill", + "ui:slo/read", + "alerting:slo.rules.burnRate/slo/rule/get", + "alerting:slo.rules.burnRate/slo/rule/getRuleState", + "alerting:slo.rules.burnRate/slo/rule/getAlertSummary", + "alerting:slo.rules.burnRate/slo/rule/getExecutionLog", + "alerting:slo.rules.burnRate/slo/rule/getActionErrorLog", + "alerting:slo.rules.burnRate/slo/rule/find", + "alerting:slo.rules.burnRate/slo/rule/getRuleExecutionKPI", + "alerting:slo.rules.burnRate/slo/rule/getBackfill", + "alerting:slo.rules.burnRate/slo/rule/findBackfill", + "alerting:slo.rules.burnRate/alerts/rule/get", + "alerting:slo.rules.burnRate/alerts/rule/getRuleState", + "alerting:slo.rules.burnRate/alerts/rule/getAlertSummary", + "alerting:slo.rules.burnRate/alerts/rule/getExecutionLog", + "alerting:slo.rules.burnRate/alerts/rule/getActionErrorLog", + "alerting:slo.rules.burnRate/alerts/rule/find", + "alerting:slo.rules.burnRate/alerts/rule/getRuleExecutionKPI", + "alerting:slo.rules.burnRate/alerts/rule/getBackfill", + "alerting:slo.rules.burnRate/alerts/rule/findBackfill", + "alerting:slo.rules.burnRate/slo/alert/get", + "alerting:slo.rules.burnRate/slo/alert/find", + "alerting:slo.rules.burnRate/slo/alert/getAuthorizedAlertsIndices", + "alerting:slo.rules.burnRate/slo/alert/getAlertSummary", + "alerting:slo.rules.burnRate/alerts/alert/get", + "alerting:slo.rules.burnRate/alerts/alert/find", + "alerting:slo.rules.burnRate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:slo.rules.burnRate/alerts/alert/getAlertSummary", + "app:observability", + "ui:navLinks/observability", + "ui:observability/read", "alerting:apm.error_rate/observability/rule/get", "alerting:apm.error_rate/observability/rule/getRuleState", "alerting:apm.error_rate/observability/rule/getAlertSummary", @@ -8385,6 +16588,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.error_rate/observability/rule/getRuleExecutionKPI", "alerting:apm.error_rate/observability/rule/getBackfill", "alerting:apm.error_rate/observability/rule/findBackfill", + "alerting:apm.error_rate/alerts/rule/get", + "alerting:apm.error_rate/alerts/rule/getRuleState", + "alerting:apm.error_rate/alerts/rule/getAlertSummary", + "alerting:apm.error_rate/alerts/rule/getExecutionLog", + "alerting:apm.error_rate/alerts/rule/getActionErrorLog", + "alerting:apm.error_rate/alerts/rule/find", + "alerting:apm.error_rate/alerts/rule/getRuleExecutionKPI", + "alerting:apm.error_rate/alerts/rule/getBackfill", + "alerting:apm.error_rate/alerts/rule/findBackfill", "alerting:apm.transaction_error_rate/observability/rule/get", "alerting:apm.transaction_error_rate/observability/rule/getRuleState", "alerting:apm.transaction_error_rate/observability/rule/getAlertSummary", @@ -8394,6 +16606,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.transaction_error_rate/observability/rule/getRuleExecutionKPI", "alerting:apm.transaction_error_rate/observability/rule/getBackfill", "alerting:apm.transaction_error_rate/observability/rule/findBackfill", + "alerting:apm.transaction_error_rate/alerts/rule/get", + "alerting:apm.transaction_error_rate/alerts/rule/getRuleState", + "alerting:apm.transaction_error_rate/alerts/rule/getAlertSummary", + "alerting:apm.transaction_error_rate/alerts/rule/getExecutionLog", + "alerting:apm.transaction_error_rate/alerts/rule/getActionErrorLog", + "alerting:apm.transaction_error_rate/alerts/rule/find", + "alerting:apm.transaction_error_rate/alerts/rule/getRuleExecutionKPI", + "alerting:apm.transaction_error_rate/alerts/rule/getBackfill", + "alerting:apm.transaction_error_rate/alerts/rule/findBackfill", "alerting:apm.transaction_duration/observability/rule/get", "alerting:apm.transaction_duration/observability/rule/getRuleState", "alerting:apm.transaction_duration/observability/rule/getAlertSummary", @@ -8403,6 +16624,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.transaction_duration/observability/rule/getRuleExecutionKPI", "alerting:apm.transaction_duration/observability/rule/getBackfill", "alerting:apm.transaction_duration/observability/rule/findBackfill", + "alerting:apm.transaction_duration/alerts/rule/get", + "alerting:apm.transaction_duration/alerts/rule/getRuleState", + "alerting:apm.transaction_duration/alerts/rule/getAlertSummary", + "alerting:apm.transaction_duration/alerts/rule/getExecutionLog", + "alerting:apm.transaction_duration/alerts/rule/getActionErrorLog", + "alerting:apm.transaction_duration/alerts/rule/find", + "alerting:apm.transaction_duration/alerts/rule/getRuleExecutionKPI", + "alerting:apm.transaction_duration/alerts/rule/getBackfill", + "alerting:apm.transaction_duration/alerts/rule/findBackfill", "alerting:apm.anomaly/observability/rule/get", "alerting:apm.anomaly/observability/rule/getRuleState", "alerting:apm.anomaly/observability/rule/getAlertSummary", @@ -8412,6 +16642,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.anomaly/observability/rule/getRuleExecutionKPI", "alerting:apm.anomaly/observability/rule/getBackfill", "alerting:apm.anomaly/observability/rule/findBackfill", + "alerting:apm.anomaly/alerts/rule/get", + "alerting:apm.anomaly/alerts/rule/getRuleState", + "alerting:apm.anomaly/alerts/rule/getAlertSummary", + "alerting:apm.anomaly/alerts/rule/getExecutionLog", + "alerting:apm.anomaly/alerts/rule/getActionErrorLog", + "alerting:apm.anomaly/alerts/rule/find", + "alerting:apm.anomaly/alerts/rule/getRuleExecutionKPI", + "alerting:apm.anomaly/alerts/rule/getBackfill", + "alerting:apm.anomaly/alerts/rule/findBackfill", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/get", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/getRuleState", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/getAlertSummary", @@ -8421,6 +16660,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/getRuleExecutionKPI", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/getBackfill", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/findBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/get", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getRuleState", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getAlertSummary", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getExecutionLog", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getActionErrorLog", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/find", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/findBackfill", "alerting:xpack.synthetics.alerts.tls/observability/rule/get", "alerting:xpack.synthetics.alerts.tls/observability/rule/getRuleState", "alerting:xpack.synthetics.alerts.tls/observability/rule/getAlertSummary", @@ -8430,50 +16678,336 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.synthetics.alerts.tls/observability/rule/getRuleExecutionKPI", "alerting:xpack.synthetics.alerts.tls/observability/rule/getBackfill", "alerting:xpack.synthetics.alerts.tls/observability/rule/findBackfill", - "alerting:slo.rules.burnRate/observability/alert/get", - "alerting:slo.rules.burnRate/observability/alert/find", - "alerting:slo.rules.burnRate/observability/alert/getAuthorizedAlertsIndices", - "alerting:slo.rules.burnRate/observability/alert/getAlertSummary", - "alerting:observability.rules.custom_threshold/observability/alert/get", - "alerting:observability.rules.custom_threshold/observability/alert/find", - "alerting:observability.rules.custom_threshold/observability/alert/getAuthorizedAlertsIndices", - "alerting:observability.rules.custom_threshold/observability/alert/getAlertSummary", - "alerting:.es-query/observability/alert/get", - "alerting:.es-query/observability/alert/find", - "alerting:.es-query/observability/alert/getAuthorizedAlertsIndices", - "alerting:.es-query/observability/alert/getAlertSummary", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/get", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/find", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAuthorizedAlertsIndices", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAlertSummary", - "alerting:metrics.alert.inventory.threshold/observability/alert/get", - "alerting:metrics.alert.inventory.threshold/observability/alert/find", - "alerting:metrics.alert.inventory.threshold/observability/alert/getAuthorizedAlertsIndices", - "alerting:metrics.alert.inventory.threshold/observability/alert/getAlertSummary", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/get", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getRuleState", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getAlertSummary", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getExecutionLog", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getActionErrorLog", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/find", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getBackfill", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/findBackfill", + "alerting:metrics.alert.threshold/observability/rule/get", + "alerting:metrics.alert.threshold/observability/rule/getRuleState", + "alerting:metrics.alert.threshold/observability/rule/getAlertSummary", + "alerting:metrics.alert.threshold/observability/rule/getExecutionLog", + "alerting:metrics.alert.threshold/observability/rule/getActionErrorLog", + "alerting:metrics.alert.threshold/observability/rule/find", + "alerting:metrics.alert.threshold/observability/rule/getRuleExecutionKPI", + "alerting:metrics.alert.threshold/observability/rule/getBackfill", + "alerting:metrics.alert.threshold/observability/rule/findBackfill", + "alerting:metrics.alert.threshold/alerts/rule/get", + "alerting:metrics.alert.threshold/alerts/rule/getRuleState", + "alerting:metrics.alert.threshold/alerts/rule/getAlertSummary", + "alerting:metrics.alert.threshold/alerts/rule/getExecutionLog", + "alerting:metrics.alert.threshold/alerts/rule/getActionErrorLog", + "alerting:metrics.alert.threshold/alerts/rule/find", + "alerting:metrics.alert.threshold/alerts/rule/getRuleExecutionKPI", + "alerting:metrics.alert.threshold/alerts/rule/getBackfill", + "alerting:metrics.alert.threshold/alerts/rule/findBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/get", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleState", + "alerting:metrics.alert.inventory.threshold/observability/rule/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/rule/getExecutionLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/getActionErrorLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/find", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleExecutionKPI", + "alerting:metrics.alert.inventory.threshold/observability/rule/getBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/findBackfill", + "alerting:metrics.alert.inventory.threshold/alerts/rule/get", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getRuleState", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getExecutionLog", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getActionErrorLog", + "alerting:metrics.alert.inventory.threshold/alerts/rule/find", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getRuleExecutionKPI", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getBackfill", + "alerting:metrics.alert.inventory.threshold/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.tls/observability/rule/get", + "alerting:xpack.uptime.alerts.tls/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.tls/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tls/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tls/observability/rule/find", + "alerting:xpack.uptime.alerts.tls/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tls/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.tls/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.tls/alerts/rule/get", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tls/alerts/rule/find", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.tls/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/get", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/find", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/get", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/find", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/get", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/find", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/get", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/find", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/get", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/find", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/get", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/find", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/findBackfill", + "alerting:logs.alert.document.count/observability/rule/get", + "alerting:logs.alert.document.count/observability/rule/getRuleState", + "alerting:logs.alert.document.count/observability/rule/getAlertSummary", + "alerting:logs.alert.document.count/observability/rule/getExecutionLog", + "alerting:logs.alert.document.count/observability/rule/getActionErrorLog", + "alerting:logs.alert.document.count/observability/rule/find", + "alerting:logs.alert.document.count/observability/rule/getRuleExecutionKPI", + "alerting:logs.alert.document.count/observability/rule/getBackfill", + "alerting:logs.alert.document.count/observability/rule/findBackfill", + "alerting:logs.alert.document.count/alerts/rule/get", + "alerting:logs.alert.document.count/alerts/rule/getRuleState", + "alerting:logs.alert.document.count/alerts/rule/getAlertSummary", + "alerting:logs.alert.document.count/alerts/rule/getExecutionLog", + "alerting:logs.alert.document.count/alerts/rule/getActionErrorLog", + "alerting:logs.alert.document.count/alerts/rule/find", + "alerting:logs.alert.document.count/alerts/rule/getRuleExecutionKPI", + "alerting:logs.alert.document.count/alerts/rule/getBackfill", + "alerting:logs.alert.document.count/alerts/rule/findBackfill", + "alerting:slo.rules.burnRate/observability/rule/get", + "alerting:slo.rules.burnRate/observability/rule/getRuleState", + "alerting:slo.rules.burnRate/observability/rule/getAlertSummary", + "alerting:slo.rules.burnRate/observability/rule/getExecutionLog", + "alerting:slo.rules.burnRate/observability/rule/getActionErrorLog", + "alerting:slo.rules.burnRate/observability/rule/find", + "alerting:slo.rules.burnRate/observability/rule/getRuleExecutionKPI", + "alerting:slo.rules.burnRate/observability/rule/getBackfill", + "alerting:slo.rules.burnRate/observability/rule/findBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/get", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleState", + "alerting:observability.rules.custom_threshold/observability/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/observability/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/observability/rule/find", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/observability/rule/getBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/findBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/get", + "alerting:observability.rules.custom_threshold/alerts/rule/getRuleState", + "alerting:observability.rules.custom_threshold/alerts/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/alerts/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/alerts/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/alerts/rule/find", + "alerting:observability.rules.custom_threshold/alerts/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/alerts/rule/getBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/findBackfill", + "alerting:.es-query/observability/rule/get", + "alerting:.es-query/observability/rule/getRuleState", + "alerting:.es-query/observability/rule/getAlertSummary", + "alerting:.es-query/observability/rule/getExecutionLog", + "alerting:.es-query/observability/rule/getActionErrorLog", + "alerting:.es-query/observability/rule/find", + "alerting:.es-query/observability/rule/getRuleExecutionKPI", + "alerting:.es-query/observability/rule/getBackfill", + "alerting:.es-query/observability/rule/findBackfill", + "alerting:.es-query/alerts/rule/get", + "alerting:.es-query/alerts/rule/getRuleState", + "alerting:.es-query/alerts/rule/getAlertSummary", + "alerting:.es-query/alerts/rule/getExecutionLog", + "alerting:.es-query/alerts/rule/getActionErrorLog", + "alerting:.es-query/alerts/rule/find", + "alerting:.es-query/alerts/rule/getRuleExecutionKPI", + "alerting:.es-query/alerts/rule/getBackfill", + "alerting:.es-query/alerts/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/findBackfill", "alerting:apm.error_rate/observability/alert/get", "alerting:apm.error_rate/observability/alert/find", "alerting:apm.error_rate/observability/alert/getAuthorizedAlertsIndices", "alerting:apm.error_rate/observability/alert/getAlertSummary", + "alerting:apm.error_rate/alerts/alert/get", + "alerting:apm.error_rate/alerts/alert/find", + "alerting:apm.error_rate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.error_rate/alerts/alert/getAlertSummary", "alerting:apm.transaction_error_rate/observability/alert/get", "alerting:apm.transaction_error_rate/observability/alert/find", "alerting:apm.transaction_error_rate/observability/alert/getAuthorizedAlertsIndices", "alerting:apm.transaction_error_rate/observability/alert/getAlertSummary", + "alerting:apm.transaction_error_rate/alerts/alert/get", + "alerting:apm.transaction_error_rate/alerts/alert/find", + "alerting:apm.transaction_error_rate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_error_rate/alerts/alert/getAlertSummary", "alerting:apm.transaction_duration/observability/alert/get", "alerting:apm.transaction_duration/observability/alert/find", "alerting:apm.transaction_duration/observability/alert/getAuthorizedAlertsIndices", "alerting:apm.transaction_duration/observability/alert/getAlertSummary", + "alerting:apm.transaction_duration/alerts/alert/get", + "alerting:apm.transaction_duration/alerts/alert/find", + "alerting:apm.transaction_duration/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_duration/alerts/alert/getAlertSummary", "alerting:apm.anomaly/observability/alert/get", "alerting:apm.anomaly/observability/alert/find", "alerting:apm.anomaly/observability/alert/getAuthorizedAlertsIndices", "alerting:apm.anomaly/observability/alert/getAlertSummary", + "alerting:apm.anomaly/alerts/alert/get", + "alerting:apm.anomaly/alerts/alert/find", + "alerting:apm.anomaly/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.anomaly/alerts/alert/getAlertSummary", "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/get", "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/find", "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/getAuthorizedAlertsIndices", "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/getAlertSummary", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/get", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/find", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/getAlertSummary", "alerting:xpack.synthetics.alerts.tls/observability/alert/get", "alerting:xpack.synthetics.alerts.tls/observability/alert/find", "alerting:xpack.synthetics.alerts.tls/observability/alert/getAuthorizedAlertsIndices", "alerting:xpack.synthetics.alerts.tls/observability/alert/getAlertSummary", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/get", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/find", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/getAlertSummary", + "alerting:metrics.alert.threshold/observability/alert/get", + "alerting:metrics.alert.threshold/observability/alert/find", + "alerting:metrics.alert.threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.threshold/observability/alert/getAlertSummary", + "alerting:metrics.alert.threshold/alerts/alert/get", + "alerting:metrics.alert.threshold/alerts/alert/find", + "alerting:metrics.alert.threshold/alerts/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.threshold/alerts/alert/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/alert/get", + "alerting:metrics.alert.inventory.threshold/observability/alert/find", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/alerts/alert/get", + "alerting:metrics.alert.inventory.threshold/alerts/alert/find", + "alerting:metrics.alert.inventory.threshold/alerts/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.inventory.threshold/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/observability/alert/get", + "alerting:xpack.uptime.alerts.tls/observability/alert/find", + "alerting:xpack.uptime.alerts.tls/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tls/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/alerts/alert/get", + "alerting:xpack.uptime.alerts.tls/alerts/alert/find", + "alerting:xpack.uptime.alerts.tls/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tls/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/get", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/find", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/get", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/find", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/get", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/find", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/get", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/find", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/get", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/find", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/get", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/find", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/getAlertSummary", + "alerting:logs.alert.document.count/observability/alert/get", + "alerting:logs.alert.document.count/observability/alert/find", + "alerting:logs.alert.document.count/observability/alert/getAuthorizedAlertsIndices", + "alerting:logs.alert.document.count/observability/alert/getAlertSummary", + "alerting:logs.alert.document.count/alerts/alert/get", + "alerting:logs.alert.document.count/alerts/alert/find", + "alerting:logs.alert.document.count/alerts/alert/getAuthorizedAlertsIndices", + "alerting:logs.alert.document.count/alerts/alert/getAlertSummary", + "alerting:slo.rules.burnRate/observability/alert/get", + "alerting:slo.rules.burnRate/observability/alert/find", + "alerting:slo.rules.burnRate/observability/alert/getAuthorizedAlertsIndices", + "alerting:slo.rules.burnRate/observability/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/alert/get", + "alerting:observability.rules.custom_threshold/observability/alert/find", + "alerting:observability.rules.custom_threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/observability/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/alerts/alert/get", + "alerting:observability.rules.custom_threshold/alerts/alert/find", + "alerting:observability.rules.custom_threshold/alerts/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/alerts/alert/getAlertSummary", + "alerting:.es-query/observability/alert/get", + "alerting:.es-query/observability/alert/find", + "alerting:.es-query/observability/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/observability/alert/getAlertSummary", + "alerting:.es-query/alerts/alert/get", + "alerting:.es-query/alerts/alert/find", + "alerting:.es-query/alerts/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/alerts/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/getAlertSummary", ], "read": Array [ "login:", @@ -8525,58 +17059,26 @@ export default function ({ getService }: FtrProviderContext) { "alerting:slo.rules.burnRate/slo/rule/getRuleExecutionKPI", "alerting:slo.rules.burnRate/slo/rule/getBackfill", "alerting:slo.rules.burnRate/slo/rule/findBackfill", + "alerting:slo.rules.burnRate/alerts/rule/get", + "alerting:slo.rules.burnRate/alerts/rule/getRuleState", + "alerting:slo.rules.burnRate/alerts/rule/getAlertSummary", + "alerting:slo.rules.burnRate/alerts/rule/getExecutionLog", + "alerting:slo.rules.burnRate/alerts/rule/getActionErrorLog", + "alerting:slo.rules.burnRate/alerts/rule/find", + "alerting:slo.rules.burnRate/alerts/rule/getRuleExecutionKPI", + "alerting:slo.rules.burnRate/alerts/rule/getBackfill", + "alerting:slo.rules.burnRate/alerts/rule/findBackfill", "alerting:slo.rules.burnRate/slo/alert/get", "alerting:slo.rules.burnRate/slo/alert/find", "alerting:slo.rules.burnRate/slo/alert/getAuthorizedAlertsIndices", "alerting:slo.rules.burnRate/slo/alert/getAlertSummary", + "alerting:slo.rules.burnRate/alerts/alert/get", + "alerting:slo.rules.burnRate/alerts/alert/find", + "alerting:slo.rules.burnRate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:slo.rules.burnRate/alerts/alert/getAlertSummary", "app:observability", "ui:navLinks/observability", "ui:observability/read", - "alerting:slo.rules.burnRate/observability/rule/get", - "alerting:slo.rules.burnRate/observability/rule/getRuleState", - "alerting:slo.rules.burnRate/observability/rule/getAlertSummary", - "alerting:slo.rules.burnRate/observability/rule/getExecutionLog", - "alerting:slo.rules.burnRate/observability/rule/getActionErrorLog", - "alerting:slo.rules.burnRate/observability/rule/find", - "alerting:slo.rules.burnRate/observability/rule/getRuleExecutionKPI", - "alerting:slo.rules.burnRate/observability/rule/getBackfill", - "alerting:slo.rules.burnRate/observability/rule/findBackfill", - "alerting:observability.rules.custom_threshold/observability/rule/get", - "alerting:observability.rules.custom_threshold/observability/rule/getRuleState", - "alerting:observability.rules.custom_threshold/observability/rule/getAlertSummary", - "alerting:observability.rules.custom_threshold/observability/rule/getExecutionLog", - "alerting:observability.rules.custom_threshold/observability/rule/getActionErrorLog", - "alerting:observability.rules.custom_threshold/observability/rule/find", - "alerting:observability.rules.custom_threshold/observability/rule/getRuleExecutionKPI", - "alerting:observability.rules.custom_threshold/observability/rule/getBackfill", - "alerting:observability.rules.custom_threshold/observability/rule/findBackfill", - "alerting:.es-query/observability/rule/get", - "alerting:.es-query/observability/rule/getRuleState", - "alerting:.es-query/observability/rule/getAlertSummary", - "alerting:.es-query/observability/rule/getExecutionLog", - "alerting:.es-query/observability/rule/getActionErrorLog", - "alerting:.es-query/observability/rule/find", - "alerting:.es-query/observability/rule/getRuleExecutionKPI", - "alerting:.es-query/observability/rule/getBackfill", - "alerting:.es-query/observability/rule/findBackfill", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/get", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleState", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getAlertSummary", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getExecutionLog", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getActionErrorLog", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/find", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleExecutionKPI", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getBackfill", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/findBackfill", - "alerting:metrics.alert.inventory.threshold/observability/rule/get", - "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleState", - "alerting:metrics.alert.inventory.threshold/observability/rule/getAlertSummary", - "alerting:metrics.alert.inventory.threshold/observability/rule/getExecutionLog", - "alerting:metrics.alert.inventory.threshold/observability/rule/getActionErrorLog", - "alerting:metrics.alert.inventory.threshold/observability/rule/find", - "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleExecutionKPI", - "alerting:metrics.alert.inventory.threshold/observability/rule/getBackfill", - "alerting:metrics.alert.inventory.threshold/observability/rule/findBackfill", "alerting:apm.error_rate/observability/rule/get", "alerting:apm.error_rate/observability/rule/getRuleState", "alerting:apm.error_rate/observability/rule/getAlertSummary", @@ -8586,6 +17088,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.error_rate/observability/rule/getRuleExecutionKPI", "alerting:apm.error_rate/observability/rule/getBackfill", "alerting:apm.error_rate/observability/rule/findBackfill", + "alerting:apm.error_rate/alerts/rule/get", + "alerting:apm.error_rate/alerts/rule/getRuleState", + "alerting:apm.error_rate/alerts/rule/getAlertSummary", + "alerting:apm.error_rate/alerts/rule/getExecutionLog", + "alerting:apm.error_rate/alerts/rule/getActionErrorLog", + "alerting:apm.error_rate/alerts/rule/find", + "alerting:apm.error_rate/alerts/rule/getRuleExecutionKPI", + "alerting:apm.error_rate/alerts/rule/getBackfill", + "alerting:apm.error_rate/alerts/rule/findBackfill", "alerting:apm.transaction_error_rate/observability/rule/get", "alerting:apm.transaction_error_rate/observability/rule/getRuleState", "alerting:apm.transaction_error_rate/observability/rule/getAlertSummary", @@ -8595,6 +17106,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.transaction_error_rate/observability/rule/getRuleExecutionKPI", "alerting:apm.transaction_error_rate/observability/rule/getBackfill", "alerting:apm.transaction_error_rate/observability/rule/findBackfill", + "alerting:apm.transaction_error_rate/alerts/rule/get", + "alerting:apm.transaction_error_rate/alerts/rule/getRuleState", + "alerting:apm.transaction_error_rate/alerts/rule/getAlertSummary", + "alerting:apm.transaction_error_rate/alerts/rule/getExecutionLog", + "alerting:apm.transaction_error_rate/alerts/rule/getActionErrorLog", + "alerting:apm.transaction_error_rate/alerts/rule/find", + "alerting:apm.transaction_error_rate/alerts/rule/getRuleExecutionKPI", + "alerting:apm.transaction_error_rate/alerts/rule/getBackfill", + "alerting:apm.transaction_error_rate/alerts/rule/findBackfill", "alerting:apm.transaction_duration/observability/rule/get", "alerting:apm.transaction_duration/observability/rule/getRuleState", "alerting:apm.transaction_duration/observability/rule/getAlertSummary", @@ -8604,6 +17124,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.transaction_duration/observability/rule/getRuleExecutionKPI", "alerting:apm.transaction_duration/observability/rule/getBackfill", "alerting:apm.transaction_duration/observability/rule/findBackfill", + "alerting:apm.transaction_duration/alerts/rule/get", + "alerting:apm.transaction_duration/alerts/rule/getRuleState", + "alerting:apm.transaction_duration/alerts/rule/getAlertSummary", + "alerting:apm.transaction_duration/alerts/rule/getExecutionLog", + "alerting:apm.transaction_duration/alerts/rule/getActionErrorLog", + "alerting:apm.transaction_duration/alerts/rule/find", + "alerting:apm.transaction_duration/alerts/rule/getRuleExecutionKPI", + "alerting:apm.transaction_duration/alerts/rule/getBackfill", + "alerting:apm.transaction_duration/alerts/rule/findBackfill", "alerting:apm.anomaly/observability/rule/get", "alerting:apm.anomaly/observability/rule/getRuleState", "alerting:apm.anomaly/observability/rule/getAlertSummary", @@ -8613,6 +17142,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.anomaly/observability/rule/getRuleExecutionKPI", "alerting:apm.anomaly/observability/rule/getBackfill", "alerting:apm.anomaly/observability/rule/findBackfill", + "alerting:apm.anomaly/alerts/rule/get", + "alerting:apm.anomaly/alerts/rule/getRuleState", + "alerting:apm.anomaly/alerts/rule/getAlertSummary", + "alerting:apm.anomaly/alerts/rule/getExecutionLog", + "alerting:apm.anomaly/alerts/rule/getActionErrorLog", + "alerting:apm.anomaly/alerts/rule/find", + "alerting:apm.anomaly/alerts/rule/getRuleExecutionKPI", + "alerting:apm.anomaly/alerts/rule/getBackfill", + "alerting:apm.anomaly/alerts/rule/findBackfill", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/get", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/getRuleState", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/getAlertSummary", @@ -8622,6 +17160,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/getRuleExecutionKPI", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/getBackfill", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/findBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/get", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getRuleState", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getAlertSummary", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getExecutionLog", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getActionErrorLog", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/find", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/findBackfill", "alerting:xpack.synthetics.alerts.tls/observability/rule/get", "alerting:xpack.synthetics.alerts.tls/observability/rule/getRuleState", "alerting:xpack.synthetics.alerts.tls/observability/rule/getAlertSummary", @@ -8631,50 +17178,336 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.synthetics.alerts.tls/observability/rule/getRuleExecutionKPI", "alerting:xpack.synthetics.alerts.tls/observability/rule/getBackfill", "alerting:xpack.synthetics.alerts.tls/observability/rule/findBackfill", - "alerting:slo.rules.burnRate/observability/alert/get", - "alerting:slo.rules.burnRate/observability/alert/find", - "alerting:slo.rules.burnRate/observability/alert/getAuthorizedAlertsIndices", - "alerting:slo.rules.burnRate/observability/alert/getAlertSummary", - "alerting:observability.rules.custom_threshold/observability/alert/get", - "alerting:observability.rules.custom_threshold/observability/alert/find", - "alerting:observability.rules.custom_threshold/observability/alert/getAuthorizedAlertsIndices", - "alerting:observability.rules.custom_threshold/observability/alert/getAlertSummary", - "alerting:.es-query/observability/alert/get", - "alerting:.es-query/observability/alert/find", - "alerting:.es-query/observability/alert/getAuthorizedAlertsIndices", - "alerting:.es-query/observability/alert/getAlertSummary", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/get", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/find", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAuthorizedAlertsIndices", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAlertSummary", - "alerting:metrics.alert.inventory.threshold/observability/alert/get", - "alerting:metrics.alert.inventory.threshold/observability/alert/find", - "alerting:metrics.alert.inventory.threshold/observability/alert/getAuthorizedAlertsIndices", - "alerting:metrics.alert.inventory.threshold/observability/alert/getAlertSummary", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/get", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getRuleState", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getAlertSummary", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getExecutionLog", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getActionErrorLog", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/find", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getBackfill", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/findBackfill", + "alerting:metrics.alert.threshold/observability/rule/get", + "alerting:metrics.alert.threshold/observability/rule/getRuleState", + "alerting:metrics.alert.threshold/observability/rule/getAlertSummary", + "alerting:metrics.alert.threshold/observability/rule/getExecutionLog", + "alerting:metrics.alert.threshold/observability/rule/getActionErrorLog", + "alerting:metrics.alert.threshold/observability/rule/find", + "alerting:metrics.alert.threshold/observability/rule/getRuleExecutionKPI", + "alerting:metrics.alert.threshold/observability/rule/getBackfill", + "alerting:metrics.alert.threshold/observability/rule/findBackfill", + "alerting:metrics.alert.threshold/alerts/rule/get", + "alerting:metrics.alert.threshold/alerts/rule/getRuleState", + "alerting:metrics.alert.threshold/alerts/rule/getAlertSummary", + "alerting:metrics.alert.threshold/alerts/rule/getExecutionLog", + "alerting:metrics.alert.threshold/alerts/rule/getActionErrorLog", + "alerting:metrics.alert.threshold/alerts/rule/find", + "alerting:metrics.alert.threshold/alerts/rule/getRuleExecutionKPI", + "alerting:metrics.alert.threshold/alerts/rule/getBackfill", + "alerting:metrics.alert.threshold/alerts/rule/findBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/get", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleState", + "alerting:metrics.alert.inventory.threshold/observability/rule/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/rule/getExecutionLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/getActionErrorLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/find", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleExecutionKPI", + "alerting:metrics.alert.inventory.threshold/observability/rule/getBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/findBackfill", + "alerting:metrics.alert.inventory.threshold/alerts/rule/get", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getRuleState", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getExecutionLog", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getActionErrorLog", + "alerting:metrics.alert.inventory.threshold/alerts/rule/find", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getRuleExecutionKPI", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getBackfill", + "alerting:metrics.alert.inventory.threshold/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.tls/observability/rule/get", + "alerting:xpack.uptime.alerts.tls/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.tls/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tls/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tls/observability/rule/find", + "alerting:xpack.uptime.alerts.tls/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tls/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.tls/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.tls/alerts/rule/get", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tls/alerts/rule/find", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.tls/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/get", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/find", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/get", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/find", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/get", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/find", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/get", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/find", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/get", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/find", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/get", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/find", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/findBackfill", + "alerting:logs.alert.document.count/observability/rule/get", + "alerting:logs.alert.document.count/observability/rule/getRuleState", + "alerting:logs.alert.document.count/observability/rule/getAlertSummary", + "alerting:logs.alert.document.count/observability/rule/getExecutionLog", + "alerting:logs.alert.document.count/observability/rule/getActionErrorLog", + "alerting:logs.alert.document.count/observability/rule/find", + "alerting:logs.alert.document.count/observability/rule/getRuleExecutionKPI", + "alerting:logs.alert.document.count/observability/rule/getBackfill", + "alerting:logs.alert.document.count/observability/rule/findBackfill", + "alerting:logs.alert.document.count/alerts/rule/get", + "alerting:logs.alert.document.count/alerts/rule/getRuleState", + "alerting:logs.alert.document.count/alerts/rule/getAlertSummary", + "alerting:logs.alert.document.count/alerts/rule/getExecutionLog", + "alerting:logs.alert.document.count/alerts/rule/getActionErrorLog", + "alerting:logs.alert.document.count/alerts/rule/find", + "alerting:logs.alert.document.count/alerts/rule/getRuleExecutionKPI", + "alerting:logs.alert.document.count/alerts/rule/getBackfill", + "alerting:logs.alert.document.count/alerts/rule/findBackfill", + "alerting:slo.rules.burnRate/observability/rule/get", + "alerting:slo.rules.burnRate/observability/rule/getRuleState", + "alerting:slo.rules.burnRate/observability/rule/getAlertSummary", + "alerting:slo.rules.burnRate/observability/rule/getExecutionLog", + "alerting:slo.rules.burnRate/observability/rule/getActionErrorLog", + "alerting:slo.rules.burnRate/observability/rule/find", + "alerting:slo.rules.burnRate/observability/rule/getRuleExecutionKPI", + "alerting:slo.rules.burnRate/observability/rule/getBackfill", + "alerting:slo.rules.burnRate/observability/rule/findBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/get", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleState", + "alerting:observability.rules.custom_threshold/observability/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/observability/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/observability/rule/find", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/observability/rule/getBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/findBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/get", + "alerting:observability.rules.custom_threshold/alerts/rule/getRuleState", + "alerting:observability.rules.custom_threshold/alerts/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/alerts/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/alerts/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/alerts/rule/find", + "alerting:observability.rules.custom_threshold/alerts/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/alerts/rule/getBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/findBackfill", + "alerting:.es-query/observability/rule/get", + "alerting:.es-query/observability/rule/getRuleState", + "alerting:.es-query/observability/rule/getAlertSummary", + "alerting:.es-query/observability/rule/getExecutionLog", + "alerting:.es-query/observability/rule/getActionErrorLog", + "alerting:.es-query/observability/rule/find", + "alerting:.es-query/observability/rule/getRuleExecutionKPI", + "alerting:.es-query/observability/rule/getBackfill", + "alerting:.es-query/observability/rule/findBackfill", + "alerting:.es-query/alerts/rule/get", + "alerting:.es-query/alerts/rule/getRuleState", + "alerting:.es-query/alerts/rule/getAlertSummary", + "alerting:.es-query/alerts/rule/getExecutionLog", + "alerting:.es-query/alerts/rule/getActionErrorLog", + "alerting:.es-query/alerts/rule/find", + "alerting:.es-query/alerts/rule/getRuleExecutionKPI", + "alerting:.es-query/alerts/rule/getBackfill", + "alerting:.es-query/alerts/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/findBackfill", "alerting:apm.error_rate/observability/alert/get", "alerting:apm.error_rate/observability/alert/find", "alerting:apm.error_rate/observability/alert/getAuthorizedAlertsIndices", "alerting:apm.error_rate/observability/alert/getAlertSummary", + "alerting:apm.error_rate/alerts/alert/get", + "alerting:apm.error_rate/alerts/alert/find", + "alerting:apm.error_rate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.error_rate/alerts/alert/getAlertSummary", "alerting:apm.transaction_error_rate/observability/alert/get", "alerting:apm.transaction_error_rate/observability/alert/find", "alerting:apm.transaction_error_rate/observability/alert/getAuthorizedAlertsIndices", "alerting:apm.transaction_error_rate/observability/alert/getAlertSummary", + "alerting:apm.transaction_error_rate/alerts/alert/get", + "alerting:apm.transaction_error_rate/alerts/alert/find", + "alerting:apm.transaction_error_rate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_error_rate/alerts/alert/getAlertSummary", "alerting:apm.transaction_duration/observability/alert/get", "alerting:apm.transaction_duration/observability/alert/find", "alerting:apm.transaction_duration/observability/alert/getAuthorizedAlertsIndices", "alerting:apm.transaction_duration/observability/alert/getAlertSummary", + "alerting:apm.transaction_duration/alerts/alert/get", + "alerting:apm.transaction_duration/alerts/alert/find", + "alerting:apm.transaction_duration/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_duration/alerts/alert/getAlertSummary", "alerting:apm.anomaly/observability/alert/get", "alerting:apm.anomaly/observability/alert/find", "alerting:apm.anomaly/observability/alert/getAuthorizedAlertsIndices", "alerting:apm.anomaly/observability/alert/getAlertSummary", + "alerting:apm.anomaly/alerts/alert/get", + "alerting:apm.anomaly/alerts/alert/find", + "alerting:apm.anomaly/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.anomaly/alerts/alert/getAlertSummary", "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/get", "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/find", "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/getAuthorizedAlertsIndices", "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/getAlertSummary", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/get", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/find", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/getAlertSummary", "alerting:xpack.synthetics.alerts.tls/observability/alert/get", "alerting:xpack.synthetics.alerts.tls/observability/alert/find", "alerting:xpack.synthetics.alerts.tls/observability/alert/getAuthorizedAlertsIndices", "alerting:xpack.synthetics.alerts.tls/observability/alert/getAlertSummary", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/get", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/find", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/getAlertSummary", + "alerting:metrics.alert.threshold/observability/alert/get", + "alerting:metrics.alert.threshold/observability/alert/find", + "alerting:metrics.alert.threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.threshold/observability/alert/getAlertSummary", + "alerting:metrics.alert.threshold/alerts/alert/get", + "alerting:metrics.alert.threshold/alerts/alert/find", + "alerting:metrics.alert.threshold/alerts/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.threshold/alerts/alert/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/alert/get", + "alerting:metrics.alert.inventory.threshold/observability/alert/find", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/alerts/alert/get", + "alerting:metrics.alert.inventory.threshold/alerts/alert/find", + "alerting:metrics.alert.inventory.threshold/alerts/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.inventory.threshold/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/observability/alert/get", + "alerting:xpack.uptime.alerts.tls/observability/alert/find", + "alerting:xpack.uptime.alerts.tls/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tls/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/alerts/alert/get", + "alerting:xpack.uptime.alerts.tls/alerts/alert/find", + "alerting:xpack.uptime.alerts.tls/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tls/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/get", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/find", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/get", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/find", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/get", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/find", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/get", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/find", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/get", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/find", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/get", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/find", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/getAlertSummary", + "alerting:logs.alert.document.count/observability/alert/get", + "alerting:logs.alert.document.count/observability/alert/find", + "alerting:logs.alert.document.count/observability/alert/getAuthorizedAlertsIndices", + "alerting:logs.alert.document.count/observability/alert/getAlertSummary", + "alerting:logs.alert.document.count/alerts/alert/get", + "alerting:logs.alert.document.count/alerts/alert/find", + "alerting:logs.alert.document.count/alerts/alert/getAuthorizedAlertsIndices", + "alerting:logs.alert.document.count/alerts/alert/getAlertSummary", + "alerting:slo.rules.burnRate/observability/alert/get", + "alerting:slo.rules.burnRate/observability/alert/find", + "alerting:slo.rules.burnRate/observability/alert/getAuthorizedAlertsIndices", + "alerting:slo.rules.burnRate/observability/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/alert/get", + "alerting:observability.rules.custom_threshold/observability/alert/find", + "alerting:observability.rules.custom_threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/observability/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/alerts/alert/get", + "alerting:observability.rules.custom_threshold/alerts/alert/find", + "alerting:observability.rules.custom_threshold/alerts/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/alerts/alert/getAlertSummary", + "alerting:.es-query/observability/alert/get", + "alerting:.es-query/observability/alert/find", + "alerting:.es-query/observability/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/observability/alert/getAlertSummary", + "alerting:.es-query/alerts/alert/get", + "alerting:.es-query/alerts/alert/find", + "alerting:.es-query/alerts/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/alerts/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/getAlertSummary", ], }, "uptime": Object { @@ -8684,6 +17517,7 @@ export default function ({ getService }: FtrProviderContext) { "api:uptime-write", "api:lists-all", "api:rac", + "api:private-location-write", "app:uptime", "app:kibana", "app:synthetics", @@ -8728,30 +17562,6 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:uptime-synthetics-api-key/delete", "saved_object:uptime-synthetics-api-key/bulk_delete", "saved_object:uptime-synthetics-api-key/share_to_space", - "saved_object:synthetics-private-location/bulk_get", - "saved_object:synthetics-private-location/get", - "saved_object:synthetics-private-location/find", - "saved_object:synthetics-private-location/open_point_in_time", - "saved_object:synthetics-private-location/close_point_in_time", - "saved_object:synthetics-private-location/create", - "saved_object:synthetics-private-location/bulk_create", - "saved_object:synthetics-private-location/update", - "saved_object:synthetics-private-location/bulk_update", - "saved_object:synthetics-private-location/delete", - "saved_object:synthetics-private-location/bulk_delete", - "saved_object:synthetics-private-location/share_to_space", - "saved_object:synthetics-privates-locations/bulk_get", - "saved_object:synthetics-privates-locations/get", - "saved_object:synthetics-privates-locations/find", - "saved_object:synthetics-privates-locations/open_point_in_time", - "saved_object:synthetics-privates-locations/close_point_in_time", - "saved_object:synthetics-privates-locations/create", - "saved_object:synthetics-privates-locations/bulk_create", - "saved_object:synthetics-privates-locations/update", - "saved_object:synthetics-privates-locations/bulk_update", - "saved_object:synthetics-privates-locations/delete", - "saved_object:synthetics-privates-locations/bulk_delete", - "saved_object:synthetics-privates-locations/share_to_space", "saved_object:synthetics-param/bulk_get", "saved_object:synthetics-param/get", "saved_object:synthetics-param/find", @@ -8788,6 +17598,30 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:telemetry/delete", "saved_object:telemetry/bulk_delete", "saved_object:telemetry/share_to_space", + "saved_object:synthetics-private-location/bulk_get", + "saved_object:synthetics-private-location/get", + "saved_object:synthetics-private-location/find", + "saved_object:synthetics-private-location/open_point_in_time", + "saved_object:synthetics-private-location/close_point_in_time", + "saved_object:synthetics-private-location/create", + "saved_object:synthetics-private-location/bulk_create", + "saved_object:synthetics-private-location/update", + "saved_object:synthetics-private-location/bulk_update", + "saved_object:synthetics-private-location/delete", + "saved_object:synthetics-private-location/bulk_delete", + "saved_object:synthetics-private-location/share_to_space", + "saved_object:synthetics-privates-locations/bulk_get", + "saved_object:synthetics-privates-locations/get", + "saved_object:synthetics-privates-locations/find", + "saved_object:synthetics-privates-locations/open_point_in_time", + "saved_object:synthetics-privates-locations/close_point_in_time", + "saved_object:synthetics-privates-locations/create", + "saved_object:synthetics-privates-locations/bulk_create", + "saved_object:synthetics-privates-locations/update", + "saved_object:synthetics-privates-locations/bulk_update", + "saved_object:synthetics-privates-locations/delete", + "saved_object:synthetics-privates-locations/bulk_delete", + "saved_object:synthetics-privates-locations/share_to_space", "saved_object:config/bulk_get", "saved_object:config/get", "saved_object:config/find", @@ -8808,6 +17642,7 @@ export default function ({ getService }: FtrProviderContext) { "ui:uptime/show", "ui:uptime/alerting:save", "ui:uptime/elasticManagedLocationsEnabled", + "ui:uptime/canManagePrivateLocations", "alerting:xpack.uptime.alerts.tls/uptime/rule/get", "alerting:xpack.uptime.alerts.tls/uptime/rule/getRuleState", "alerting:xpack.uptime.alerts.tls/uptime/rule/getAlertSummary", @@ -8836,6 +17671,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.uptime.alerts.tls/uptime/rule/runSoon", "alerting:xpack.uptime.alerts.tls/uptime/rule/scheduleBackfill", "alerting:xpack.uptime.alerts.tls/uptime/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.tls/alerts/rule/get", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tls/alerts/rule/find", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.tls/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.tls/alerts/rule/create", + "alerting:xpack.uptime.alerts.tls/alerts/rule/delete", + "alerting:xpack.uptime.alerts.tls/alerts/rule/update", + "alerting:xpack.uptime.alerts.tls/alerts/rule/updateApiKey", + "alerting:xpack.uptime.alerts.tls/alerts/rule/enable", + "alerting:xpack.uptime.alerts.tls/alerts/rule/disable", + "alerting:xpack.uptime.alerts.tls/alerts/rule/muteAll", + "alerting:xpack.uptime.alerts.tls/alerts/rule/unmuteAll", + "alerting:xpack.uptime.alerts.tls/alerts/rule/muteAlert", + "alerting:xpack.uptime.alerts.tls/alerts/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.tls/alerts/rule/snooze", + "alerting:xpack.uptime.alerts.tls/alerts/rule/bulkEdit", + "alerting:xpack.uptime.alerts.tls/alerts/rule/bulkDelete", + "alerting:xpack.uptime.alerts.tls/alerts/rule/bulkEnable", + "alerting:xpack.uptime.alerts.tls/alerts/rule/bulkDisable", + "alerting:xpack.uptime.alerts.tls/alerts/rule/unsnooze", + "alerting:xpack.uptime.alerts.tls/alerts/rule/runSoon", + "alerting:xpack.uptime.alerts.tls/alerts/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.tls/alerts/rule/deleteBackfill", "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/get", "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/getRuleState", "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/getAlertSummary", @@ -8864,6 +17727,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/runSoon", "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/scheduleBackfill", "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/get", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/find", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/create", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/delete", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/update", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/updateApiKey", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/enable", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/disable", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/muteAll", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/unmuteAll", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/muteAlert", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/snooze", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/bulkEdit", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/bulkDelete", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/bulkEnable", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/bulkDisable", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/unsnooze", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/runSoon", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/deleteBackfill", "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/get", "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/getRuleState", "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/getAlertSummary", @@ -8892,6 +17783,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/runSoon", "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/scheduleBackfill", "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/get", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/find", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/create", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/delete", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/update", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/updateApiKey", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/enable", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/disable", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/muteAll", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/unmuteAll", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/muteAlert", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/snooze", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/bulkEdit", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/bulkDelete", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/bulkEnable", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/bulkDisable", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/unsnooze", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/runSoon", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/deleteBackfill", "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/get", "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/getRuleState", "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/getAlertSummary", @@ -8919,238 +17838,212 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/unsnooze", "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/runSoon", "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/scheduleBackfill", - "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/deleteBackfill", - "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/get", - "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/getRuleState", - "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/getAlertSummary", - "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/getExecutionLog", - "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/getActionErrorLog", - "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/find", - "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/getRuleExecutionKPI", - "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/getBackfill", - "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/findBackfill", - "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/create", - "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/delete", - "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/update", - "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/updateApiKey", - "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/enable", - "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/disable", - "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/muteAll", - "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/unmuteAll", - "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/muteAlert", - "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/unmuteAlert", - "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/snooze", - "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/bulkEdit", - "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/bulkDelete", - "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/bulkEnable", - "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/bulkDisable", - "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/unsnooze", - "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/runSoon", - "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/scheduleBackfill", - "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/deleteBackfill", - "alerting:xpack.synthetics.alerts.tls/uptime/rule/get", - "alerting:xpack.synthetics.alerts.tls/uptime/rule/getRuleState", - "alerting:xpack.synthetics.alerts.tls/uptime/rule/getAlertSummary", - "alerting:xpack.synthetics.alerts.tls/uptime/rule/getExecutionLog", - "alerting:xpack.synthetics.alerts.tls/uptime/rule/getActionErrorLog", - "alerting:xpack.synthetics.alerts.tls/uptime/rule/find", - "alerting:xpack.synthetics.alerts.tls/uptime/rule/getRuleExecutionKPI", - "alerting:xpack.synthetics.alerts.tls/uptime/rule/getBackfill", - "alerting:xpack.synthetics.alerts.tls/uptime/rule/findBackfill", - "alerting:xpack.synthetics.alerts.tls/uptime/rule/create", - "alerting:xpack.synthetics.alerts.tls/uptime/rule/delete", - "alerting:xpack.synthetics.alerts.tls/uptime/rule/update", - "alerting:xpack.synthetics.alerts.tls/uptime/rule/updateApiKey", - "alerting:xpack.synthetics.alerts.tls/uptime/rule/enable", - "alerting:xpack.synthetics.alerts.tls/uptime/rule/disable", - "alerting:xpack.synthetics.alerts.tls/uptime/rule/muteAll", - "alerting:xpack.synthetics.alerts.tls/uptime/rule/unmuteAll", - "alerting:xpack.synthetics.alerts.tls/uptime/rule/muteAlert", - "alerting:xpack.synthetics.alerts.tls/uptime/rule/unmuteAlert", - "alerting:xpack.synthetics.alerts.tls/uptime/rule/snooze", - "alerting:xpack.synthetics.alerts.tls/uptime/rule/bulkEdit", - "alerting:xpack.synthetics.alerts.tls/uptime/rule/bulkDelete", - "alerting:xpack.synthetics.alerts.tls/uptime/rule/bulkEnable", - "alerting:xpack.synthetics.alerts.tls/uptime/rule/bulkDisable", - "alerting:xpack.synthetics.alerts.tls/uptime/rule/unsnooze", - "alerting:xpack.synthetics.alerts.tls/uptime/rule/runSoon", - "alerting:xpack.synthetics.alerts.tls/uptime/rule/scheduleBackfill", - "alerting:xpack.synthetics.alerts.tls/uptime/rule/deleteBackfill", - "alerting:xpack.uptime.alerts.tls/uptime/alert/get", - "alerting:xpack.uptime.alerts.tls/uptime/alert/find", - "alerting:xpack.uptime.alerts.tls/uptime/alert/getAuthorizedAlertsIndices", - "alerting:xpack.uptime.alerts.tls/uptime/alert/getAlertSummary", - "alerting:xpack.uptime.alerts.tls/uptime/alert/update", - "alerting:xpack.uptime.alerts.tlsCertificate/uptime/alert/get", - "alerting:xpack.uptime.alerts.tlsCertificate/uptime/alert/find", - "alerting:xpack.uptime.alerts.tlsCertificate/uptime/alert/getAuthorizedAlertsIndices", - "alerting:xpack.uptime.alerts.tlsCertificate/uptime/alert/getAlertSummary", - "alerting:xpack.uptime.alerts.tlsCertificate/uptime/alert/update", - "alerting:xpack.uptime.alerts.monitorStatus/uptime/alert/get", - "alerting:xpack.uptime.alerts.monitorStatus/uptime/alert/find", - "alerting:xpack.uptime.alerts.monitorStatus/uptime/alert/getAuthorizedAlertsIndices", - "alerting:xpack.uptime.alerts.monitorStatus/uptime/alert/getAlertSummary", - "alerting:xpack.uptime.alerts.monitorStatus/uptime/alert/update", - "alerting:xpack.uptime.alerts.durationAnomaly/uptime/alert/get", - "alerting:xpack.uptime.alerts.durationAnomaly/uptime/alert/find", - "alerting:xpack.uptime.alerts.durationAnomaly/uptime/alert/getAuthorizedAlertsIndices", - "alerting:xpack.uptime.alerts.durationAnomaly/uptime/alert/getAlertSummary", - "alerting:xpack.uptime.alerts.durationAnomaly/uptime/alert/update", - "alerting:xpack.synthetics.alerts.monitorStatus/uptime/alert/get", - "alerting:xpack.synthetics.alerts.monitorStatus/uptime/alert/find", - "alerting:xpack.synthetics.alerts.monitorStatus/uptime/alert/getAuthorizedAlertsIndices", - "alerting:xpack.synthetics.alerts.monitorStatus/uptime/alert/getAlertSummary", - "alerting:xpack.synthetics.alerts.monitorStatus/uptime/alert/update", - "alerting:xpack.synthetics.alerts.tls/uptime/alert/get", - "alerting:xpack.synthetics.alerts.tls/uptime/alert/find", - "alerting:xpack.synthetics.alerts.tls/uptime/alert/getAuthorizedAlertsIndices", - "alerting:xpack.synthetics.alerts.tls/uptime/alert/getAlertSummary", - "alerting:xpack.synthetics.alerts.tls/uptime/alert/update", - "app:observability", - "ui:catalogue/observability", - "ui:navLinks/observability", - "ui:observability/read", - "ui:observability/write", - "alerting:slo.rules.burnRate/observability/rule/get", - "alerting:slo.rules.burnRate/observability/rule/getRuleState", - "alerting:slo.rules.burnRate/observability/rule/getAlertSummary", - "alerting:slo.rules.burnRate/observability/rule/getExecutionLog", - "alerting:slo.rules.burnRate/observability/rule/getActionErrorLog", - "alerting:slo.rules.burnRate/observability/rule/find", - "alerting:slo.rules.burnRate/observability/rule/getRuleExecutionKPI", - "alerting:slo.rules.burnRate/observability/rule/getBackfill", - "alerting:slo.rules.burnRate/observability/rule/findBackfill", - "alerting:slo.rules.burnRate/observability/rule/create", - "alerting:slo.rules.burnRate/observability/rule/delete", - "alerting:slo.rules.burnRate/observability/rule/update", - "alerting:slo.rules.burnRate/observability/rule/updateApiKey", - "alerting:slo.rules.burnRate/observability/rule/enable", - "alerting:slo.rules.burnRate/observability/rule/disable", - "alerting:slo.rules.burnRate/observability/rule/muteAll", - "alerting:slo.rules.burnRate/observability/rule/unmuteAll", - "alerting:slo.rules.burnRate/observability/rule/muteAlert", - "alerting:slo.rules.burnRate/observability/rule/unmuteAlert", - "alerting:slo.rules.burnRate/observability/rule/snooze", - "alerting:slo.rules.burnRate/observability/rule/bulkEdit", - "alerting:slo.rules.burnRate/observability/rule/bulkDelete", - "alerting:slo.rules.burnRate/observability/rule/bulkEnable", - "alerting:slo.rules.burnRate/observability/rule/bulkDisable", - "alerting:slo.rules.burnRate/observability/rule/unsnooze", - "alerting:slo.rules.burnRate/observability/rule/runSoon", - "alerting:slo.rules.burnRate/observability/rule/scheduleBackfill", - "alerting:slo.rules.burnRate/observability/rule/deleteBackfill", - "alerting:observability.rules.custom_threshold/observability/rule/get", - "alerting:observability.rules.custom_threshold/observability/rule/getRuleState", - "alerting:observability.rules.custom_threshold/observability/rule/getAlertSummary", - "alerting:observability.rules.custom_threshold/observability/rule/getExecutionLog", - "alerting:observability.rules.custom_threshold/observability/rule/getActionErrorLog", - "alerting:observability.rules.custom_threshold/observability/rule/find", - "alerting:observability.rules.custom_threshold/observability/rule/getRuleExecutionKPI", - "alerting:observability.rules.custom_threshold/observability/rule/getBackfill", - "alerting:observability.rules.custom_threshold/observability/rule/findBackfill", - "alerting:observability.rules.custom_threshold/observability/rule/create", - "alerting:observability.rules.custom_threshold/observability/rule/delete", - "alerting:observability.rules.custom_threshold/observability/rule/update", - "alerting:observability.rules.custom_threshold/observability/rule/updateApiKey", - "alerting:observability.rules.custom_threshold/observability/rule/enable", - "alerting:observability.rules.custom_threshold/observability/rule/disable", - "alerting:observability.rules.custom_threshold/observability/rule/muteAll", - "alerting:observability.rules.custom_threshold/observability/rule/unmuteAll", - "alerting:observability.rules.custom_threshold/observability/rule/muteAlert", - "alerting:observability.rules.custom_threshold/observability/rule/unmuteAlert", - "alerting:observability.rules.custom_threshold/observability/rule/snooze", - "alerting:observability.rules.custom_threshold/observability/rule/bulkEdit", - "alerting:observability.rules.custom_threshold/observability/rule/bulkDelete", - "alerting:observability.rules.custom_threshold/observability/rule/bulkEnable", - "alerting:observability.rules.custom_threshold/observability/rule/bulkDisable", - "alerting:observability.rules.custom_threshold/observability/rule/unsnooze", - "alerting:observability.rules.custom_threshold/observability/rule/runSoon", - "alerting:observability.rules.custom_threshold/observability/rule/scheduleBackfill", - "alerting:observability.rules.custom_threshold/observability/rule/deleteBackfill", - "alerting:.es-query/observability/rule/get", - "alerting:.es-query/observability/rule/getRuleState", - "alerting:.es-query/observability/rule/getAlertSummary", - "alerting:.es-query/observability/rule/getExecutionLog", - "alerting:.es-query/observability/rule/getActionErrorLog", - "alerting:.es-query/observability/rule/find", - "alerting:.es-query/observability/rule/getRuleExecutionKPI", - "alerting:.es-query/observability/rule/getBackfill", - "alerting:.es-query/observability/rule/findBackfill", - "alerting:.es-query/observability/rule/create", - "alerting:.es-query/observability/rule/delete", - "alerting:.es-query/observability/rule/update", - "alerting:.es-query/observability/rule/updateApiKey", - "alerting:.es-query/observability/rule/enable", - "alerting:.es-query/observability/rule/disable", - "alerting:.es-query/observability/rule/muteAll", - "alerting:.es-query/observability/rule/unmuteAll", - "alerting:.es-query/observability/rule/muteAlert", - "alerting:.es-query/observability/rule/unmuteAlert", - "alerting:.es-query/observability/rule/snooze", - "alerting:.es-query/observability/rule/bulkEdit", - "alerting:.es-query/observability/rule/bulkDelete", - "alerting:.es-query/observability/rule/bulkEnable", - "alerting:.es-query/observability/rule/bulkDisable", - "alerting:.es-query/observability/rule/unsnooze", - "alerting:.es-query/observability/rule/runSoon", - "alerting:.es-query/observability/rule/scheduleBackfill", - "alerting:.es-query/observability/rule/deleteBackfill", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/get", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleState", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getAlertSummary", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getExecutionLog", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getActionErrorLog", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/find", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleExecutionKPI", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getBackfill", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/findBackfill", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/create", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/delete", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/update", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/updateApiKey", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/enable", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/disable", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/muteAll", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unmuteAll", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/muteAlert", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unmuteAlert", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/snooze", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkEdit", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkDelete", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkEnable", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkDisable", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unsnooze", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/runSoon", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/scheduleBackfill", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/deleteBackfill", - "alerting:metrics.alert.inventory.threshold/observability/rule/get", - "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleState", - "alerting:metrics.alert.inventory.threshold/observability/rule/getAlertSummary", - "alerting:metrics.alert.inventory.threshold/observability/rule/getExecutionLog", - "alerting:metrics.alert.inventory.threshold/observability/rule/getActionErrorLog", - "alerting:metrics.alert.inventory.threshold/observability/rule/find", - "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleExecutionKPI", - "alerting:metrics.alert.inventory.threshold/observability/rule/getBackfill", - "alerting:metrics.alert.inventory.threshold/observability/rule/findBackfill", - "alerting:metrics.alert.inventory.threshold/observability/rule/create", - "alerting:metrics.alert.inventory.threshold/observability/rule/delete", - "alerting:metrics.alert.inventory.threshold/observability/rule/update", - "alerting:metrics.alert.inventory.threshold/observability/rule/updateApiKey", - "alerting:metrics.alert.inventory.threshold/observability/rule/enable", - "alerting:metrics.alert.inventory.threshold/observability/rule/disable", - "alerting:metrics.alert.inventory.threshold/observability/rule/muteAll", - "alerting:metrics.alert.inventory.threshold/observability/rule/unmuteAll", - "alerting:metrics.alert.inventory.threshold/observability/rule/muteAlert", - "alerting:metrics.alert.inventory.threshold/observability/rule/unmuteAlert", - "alerting:metrics.alert.inventory.threshold/observability/rule/snooze", - "alerting:metrics.alert.inventory.threshold/observability/rule/bulkEdit", - "alerting:metrics.alert.inventory.threshold/observability/rule/bulkDelete", - "alerting:metrics.alert.inventory.threshold/observability/rule/bulkEnable", - "alerting:metrics.alert.inventory.threshold/observability/rule/bulkDisable", - "alerting:metrics.alert.inventory.threshold/observability/rule/unsnooze", - "alerting:metrics.alert.inventory.threshold/observability/rule/runSoon", - "alerting:metrics.alert.inventory.threshold/observability/rule/scheduleBackfill", - "alerting:metrics.alert.inventory.threshold/observability/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/get", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/find", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/create", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/delete", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/update", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/updateApiKey", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/enable", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/disable", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/muteAll", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/unmuteAll", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/muteAlert", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/snooze", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/bulkEdit", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/bulkDelete", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/bulkEnable", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/bulkDisable", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/unsnooze", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/runSoon", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/deleteBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/get", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/getRuleState", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/getAlertSummary", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/getExecutionLog", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/getActionErrorLog", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/find", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/getRuleExecutionKPI", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/getBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/findBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/create", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/delete", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/update", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/updateApiKey", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/enable", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/disable", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/muteAll", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/unmuteAll", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/muteAlert", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/unmuteAlert", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/snooze", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/bulkEdit", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/bulkDelete", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/bulkEnable", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/bulkDisable", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/unsnooze", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/runSoon", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/scheduleBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/deleteBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/get", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getRuleState", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getAlertSummary", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getExecutionLog", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getActionErrorLog", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/find", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/findBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/create", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/delete", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/update", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/updateApiKey", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/enable", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/disable", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/muteAll", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/unmuteAll", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/muteAlert", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/unmuteAlert", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/snooze", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/bulkEdit", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/bulkDelete", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/bulkEnable", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/bulkDisable", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/unsnooze", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/runSoon", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/scheduleBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/deleteBackfill", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/get", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/getRuleState", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/getAlertSummary", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/getExecutionLog", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/getActionErrorLog", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/find", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/getRuleExecutionKPI", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/getBackfill", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/findBackfill", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/create", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/delete", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/update", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/updateApiKey", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/enable", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/disable", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/muteAll", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/unmuteAll", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/muteAlert", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/unmuteAlert", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/snooze", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/bulkEdit", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/bulkDelete", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/bulkEnable", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/bulkDisable", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/unsnooze", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/runSoon", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/scheduleBackfill", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/deleteBackfill", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/get", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getRuleState", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getAlertSummary", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getExecutionLog", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getActionErrorLog", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/find", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getBackfill", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/findBackfill", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/create", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/delete", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/update", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/updateApiKey", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/enable", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/disable", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/muteAll", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/unmuteAll", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/muteAlert", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/unmuteAlert", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/snooze", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/bulkEdit", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/bulkDelete", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/bulkEnable", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/bulkDisable", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/unsnooze", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/runSoon", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/scheduleBackfill", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.tls/uptime/alert/get", + "alerting:xpack.uptime.alerts.tls/uptime/alert/find", + "alerting:xpack.uptime.alerts.tls/uptime/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tls/uptime/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/uptime/alert/update", + "alerting:xpack.uptime.alerts.tls/alerts/alert/get", + "alerting:xpack.uptime.alerts.tls/alerts/alert/find", + "alerting:xpack.uptime.alerts.tls/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tls/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/alerts/alert/update", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/alert/get", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/alert/find", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/alert/update", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/get", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/find", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/update", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/alert/get", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/alert/find", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/alert/update", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/get", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/find", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/update", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/alert/get", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/alert/find", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/alert/update", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/get", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/find", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/update", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/alert/get", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/alert/find", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/alert/getAuthorizedAlertsIndices", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/alert/getAlertSummary", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/alert/update", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/get", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/find", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/getAlertSummary", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/update", + "alerting:xpack.synthetics.alerts.tls/uptime/alert/get", + "alerting:xpack.synthetics.alerts.tls/uptime/alert/find", + "alerting:xpack.synthetics.alerts.tls/uptime/alert/getAuthorizedAlertsIndices", + "alerting:xpack.synthetics.alerts.tls/uptime/alert/getAlertSummary", + "alerting:xpack.synthetics.alerts.tls/uptime/alert/update", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/get", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/find", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/getAlertSummary", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/update", + "app:observability", + "ui:catalogue/observability", + "ui:navLinks/observability", + "ui:observability/read", + "ui:observability/write", "alerting:apm.error_rate/observability/rule/get", "alerting:apm.error_rate/observability/rule/getRuleState", "alerting:apm.error_rate/observability/rule/getAlertSummary", @@ -9179,6 +18072,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.error_rate/observability/rule/runSoon", "alerting:apm.error_rate/observability/rule/scheduleBackfill", "alerting:apm.error_rate/observability/rule/deleteBackfill", + "alerting:apm.error_rate/alerts/rule/get", + "alerting:apm.error_rate/alerts/rule/getRuleState", + "alerting:apm.error_rate/alerts/rule/getAlertSummary", + "alerting:apm.error_rate/alerts/rule/getExecutionLog", + "alerting:apm.error_rate/alerts/rule/getActionErrorLog", + "alerting:apm.error_rate/alerts/rule/find", + "alerting:apm.error_rate/alerts/rule/getRuleExecutionKPI", + "alerting:apm.error_rate/alerts/rule/getBackfill", + "alerting:apm.error_rate/alerts/rule/findBackfill", + "alerting:apm.error_rate/alerts/rule/create", + "alerting:apm.error_rate/alerts/rule/delete", + "alerting:apm.error_rate/alerts/rule/update", + "alerting:apm.error_rate/alerts/rule/updateApiKey", + "alerting:apm.error_rate/alerts/rule/enable", + "alerting:apm.error_rate/alerts/rule/disable", + "alerting:apm.error_rate/alerts/rule/muteAll", + "alerting:apm.error_rate/alerts/rule/unmuteAll", + "alerting:apm.error_rate/alerts/rule/muteAlert", + "alerting:apm.error_rate/alerts/rule/unmuteAlert", + "alerting:apm.error_rate/alerts/rule/snooze", + "alerting:apm.error_rate/alerts/rule/bulkEdit", + "alerting:apm.error_rate/alerts/rule/bulkDelete", + "alerting:apm.error_rate/alerts/rule/bulkEnable", + "alerting:apm.error_rate/alerts/rule/bulkDisable", + "alerting:apm.error_rate/alerts/rule/unsnooze", + "alerting:apm.error_rate/alerts/rule/runSoon", + "alerting:apm.error_rate/alerts/rule/scheduleBackfill", + "alerting:apm.error_rate/alerts/rule/deleteBackfill", "alerting:apm.transaction_error_rate/observability/rule/get", "alerting:apm.transaction_error_rate/observability/rule/getRuleState", "alerting:apm.transaction_error_rate/observability/rule/getAlertSummary", @@ -9207,6 +18128,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.transaction_error_rate/observability/rule/runSoon", "alerting:apm.transaction_error_rate/observability/rule/scheduleBackfill", "alerting:apm.transaction_error_rate/observability/rule/deleteBackfill", + "alerting:apm.transaction_error_rate/alerts/rule/get", + "alerting:apm.transaction_error_rate/alerts/rule/getRuleState", + "alerting:apm.transaction_error_rate/alerts/rule/getAlertSummary", + "alerting:apm.transaction_error_rate/alerts/rule/getExecutionLog", + "alerting:apm.transaction_error_rate/alerts/rule/getActionErrorLog", + "alerting:apm.transaction_error_rate/alerts/rule/find", + "alerting:apm.transaction_error_rate/alerts/rule/getRuleExecutionKPI", + "alerting:apm.transaction_error_rate/alerts/rule/getBackfill", + "alerting:apm.transaction_error_rate/alerts/rule/findBackfill", + "alerting:apm.transaction_error_rate/alerts/rule/create", + "alerting:apm.transaction_error_rate/alerts/rule/delete", + "alerting:apm.transaction_error_rate/alerts/rule/update", + "alerting:apm.transaction_error_rate/alerts/rule/updateApiKey", + "alerting:apm.transaction_error_rate/alerts/rule/enable", + "alerting:apm.transaction_error_rate/alerts/rule/disable", + "alerting:apm.transaction_error_rate/alerts/rule/muteAll", + "alerting:apm.transaction_error_rate/alerts/rule/unmuteAll", + "alerting:apm.transaction_error_rate/alerts/rule/muteAlert", + "alerting:apm.transaction_error_rate/alerts/rule/unmuteAlert", + "alerting:apm.transaction_error_rate/alerts/rule/snooze", + "alerting:apm.transaction_error_rate/alerts/rule/bulkEdit", + "alerting:apm.transaction_error_rate/alerts/rule/bulkDelete", + "alerting:apm.transaction_error_rate/alerts/rule/bulkEnable", + "alerting:apm.transaction_error_rate/alerts/rule/bulkDisable", + "alerting:apm.transaction_error_rate/alerts/rule/unsnooze", + "alerting:apm.transaction_error_rate/alerts/rule/runSoon", + "alerting:apm.transaction_error_rate/alerts/rule/scheduleBackfill", + "alerting:apm.transaction_error_rate/alerts/rule/deleteBackfill", "alerting:apm.transaction_duration/observability/rule/get", "alerting:apm.transaction_duration/observability/rule/getRuleState", "alerting:apm.transaction_duration/observability/rule/getAlertSummary", @@ -9235,6 +18184,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.transaction_duration/observability/rule/runSoon", "alerting:apm.transaction_duration/observability/rule/scheduleBackfill", "alerting:apm.transaction_duration/observability/rule/deleteBackfill", + "alerting:apm.transaction_duration/alerts/rule/get", + "alerting:apm.transaction_duration/alerts/rule/getRuleState", + "alerting:apm.transaction_duration/alerts/rule/getAlertSummary", + "alerting:apm.transaction_duration/alerts/rule/getExecutionLog", + "alerting:apm.transaction_duration/alerts/rule/getActionErrorLog", + "alerting:apm.transaction_duration/alerts/rule/find", + "alerting:apm.transaction_duration/alerts/rule/getRuleExecutionKPI", + "alerting:apm.transaction_duration/alerts/rule/getBackfill", + "alerting:apm.transaction_duration/alerts/rule/findBackfill", + "alerting:apm.transaction_duration/alerts/rule/create", + "alerting:apm.transaction_duration/alerts/rule/delete", + "alerting:apm.transaction_duration/alerts/rule/update", + "alerting:apm.transaction_duration/alerts/rule/updateApiKey", + "alerting:apm.transaction_duration/alerts/rule/enable", + "alerting:apm.transaction_duration/alerts/rule/disable", + "alerting:apm.transaction_duration/alerts/rule/muteAll", + "alerting:apm.transaction_duration/alerts/rule/unmuteAll", + "alerting:apm.transaction_duration/alerts/rule/muteAlert", + "alerting:apm.transaction_duration/alerts/rule/unmuteAlert", + "alerting:apm.transaction_duration/alerts/rule/snooze", + "alerting:apm.transaction_duration/alerts/rule/bulkEdit", + "alerting:apm.transaction_duration/alerts/rule/bulkDelete", + "alerting:apm.transaction_duration/alerts/rule/bulkEnable", + "alerting:apm.transaction_duration/alerts/rule/bulkDisable", + "alerting:apm.transaction_duration/alerts/rule/unsnooze", + "alerting:apm.transaction_duration/alerts/rule/runSoon", + "alerting:apm.transaction_duration/alerts/rule/scheduleBackfill", + "alerting:apm.transaction_duration/alerts/rule/deleteBackfill", "alerting:apm.anomaly/observability/rule/get", "alerting:apm.anomaly/observability/rule/getRuleState", "alerting:apm.anomaly/observability/rule/getAlertSummary", @@ -9263,6 +18240,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.anomaly/observability/rule/runSoon", "alerting:apm.anomaly/observability/rule/scheduleBackfill", "alerting:apm.anomaly/observability/rule/deleteBackfill", + "alerting:apm.anomaly/alerts/rule/get", + "alerting:apm.anomaly/alerts/rule/getRuleState", + "alerting:apm.anomaly/alerts/rule/getAlertSummary", + "alerting:apm.anomaly/alerts/rule/getExecutionLog", + "alerting:apm.anomaly/alerts/rule/getActionErrorLog", + "alerting:apm.anomaly/alerts/rule/find", + "alerting:apm.anomaly/alerts/rule/getRuleExecutionKPI", + "alerting:apm.anomaly/alerts/rule/getBackfill", + "alerting:apm.anomaly/alerts/rule/findBackfill", + "alerting:apm.anomaly/alerts/rule/create", + "alerting:apm.anomaly/alerts/rule/delete", + "alerting:apm.anomaly/alerts/rule/update", + "alerting:apm.anomaly/alerts/rule/updateApiKey", + "alerting:apm.anomaly/alerts/rule/enable", + "alerting:apm.anomaly/alerts/rule/disable", + "alerting:apm.anomaly/alerts/rule/muteAll", + "alerting:apm.anomaly/alerts/rule/unmuteAll", + "alerting:apm.anomaly/alerts/rule/muteAlert", + "alerting:apm.anomaly/alerts/rule/unmuteAlert", + "alerting:apm.anomaly/alerts/rule/snooze", + "alerting:apm.anomaly/alerts/rule/bulkEdit", + "alerting:apm.anomaly/alerts/rule/bulkDelete", + "alerting:apm.anomaly/alerts/rule/bulkEnable", + "alerting:apm.anomaly/alerts/rule/bulkDisable", + "alerting:apm.anomaly/alerts/rule/unsnooze", + "alerting:apm.anomaly/alerts/rule/runSoon", + "alerting:apm.anomaly/alerts/rule/scheduleBackfill", + "alerting:apm.anomaly/alerts/rule/deleteBackfill", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/get", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/getRuleState", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/getAlertSummary", @@ -9319,51 +18324,550 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.synthetics.alerts.tls/observability/rule/runSoon", "alerting:xpack.synthetics.alerts.tls/observability/rule/scheduleBackfill", "alerting:xpack.synthetics.alerts.tls/observability/rule/deleteBackfill", - "alerting:slo.rules.burnRate/observability/alert/get", - "alerting:slo.rules.burnRate/observability/alert/find", - "alerting:slo.rules.burnRate/observability/alert/getAuthorizedAlertsIndices", - "alerting:slo.rules.burnRate/observability/alert/getAlertSummary", - "alerting:slo.rules.burnRate/observability/alert/update", - "alerting:observability.rules.custom_threshold/observability/alert/get", - "alerting:observability.rules.custom_threshold/observability/alert/find", - "alerting:observability.rules.custom_threshold/observability/alert/getAuthorizedAlertsIndices", - "alerting:observability.rules.custom_threshold/observability/alert/getAlertSummary", - "alerting:observability.rules.custom_threshold/observability/alert/update", - "alerting:.es-query/observability/alert/get", - "alerting:.es-query/observability/alert/find", - "alerting:.es-query/observability/alert/getAuthorizedAlertsIndices", - "alerting:.es-query/observability/alert/getAlertSummary", - "alerting:.es-query/observability/alert/update", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/get", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/find", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAuthorizedAlertsIndices", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAlertSummary", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/update", - "alerting:metrics.alert.inventory.threshold/observability/alert/get", - "alerting:metrics.alert.inventory.threshold/observability/alert/find", - "alerting:metrics.alert.inventory.threshold/observability/alert/getAuthorizedAlertsIndices", - "alerting:metrics.alert.inventory.threshold/observability/alert/getAlertSummary", - "alerting:metrics.alert.inventory.threshold/observability/alert/update", + "alerting:metrics.alert.threshold/observability/rule/get", + "alerting:metrics.alert.threshold/observability/rule/getRuleState", + "alerting:metrics.alert.threshold/observability/rule/getAlertSummary", + "alerting:metrics.alert.threshold/observability/rule/getExecutionLog", + "alerting:metrics.alert.threshold/observability/rule/getActionErrorLog", + "alerting:metrics.alert.threshold/observability/rule/find", + "alerting:metrics.alert.threshold/observability/rule/getRuleExecutionKPI", + "alerting:metrics.alert.threshold/observability/rule/getBackfill", + "alerting:metrics.alert.threshold/observability/rule/findBackfill", + "alerting:metrics.alert.threshold/observability/rule/create", + "alerting:metrics.alert.threshold/observability/rule/delete", + "alerting:metrics.alert.threshold/observability/rule/update", + "alerting:metrics.alert.threshold/observability/rule/updateApiKey", + "alerting:metrics.alert.threshold/observability/rule/enable", + "alerting:metrics.alert.threshold/observability/rule/disable", + "alerting:metrics.alert.threshold/observability/rule/muteAll", + "alerting:metrics.alert.threshold/observability/rule/unmuteAll", + "alerting:metrics.alert.threshold/observability/rule/muteAlert", + "alerting:metrics.alert.threshold/observability/rule/unmuteAlert", + "alerting:metrics.alert.threshold/observability/rule/snooze", + "alerting:metrics.alert.threshold/observability/rule/bulkEdit", + "alerting:metrics.alert.threshold/observability/rule/bulkDelete", + "alerting:metrics.alert.threshold/observability/rule/bulkEnable", + "alerting:metrics.alert.threshold/observability/rule/bulkDisable", + "alerting:metrics.alert.threshold/observability/rule/unsnooze", + "alerting:metrics.alert.threshold/observability/rule/runSoon", + "alerting:metrics.alert.threshold/observability/rule/scheduleBackfill", + "alerting:metrics.alert.threshold/observability/rule/deleteBackfill", + "alerting:metrics.alert.threshold/alerts/rule/get", + "alerting:metrics.alert.threshold/alerts/rule/getRuleState", + "alerting:metrics.alert.threshold/alerts/rule/getAlertSummary", + "alerting:metrics.alert.threshold/alerts/rule/getExecutionLog", + "alerting:metrics.alert.threshold/alerts/rule/getActionErrorLog", + "alerting:metrics.alert.threshold/alerts/rule/find", + "alerting:metrics.alert.threshold/alerts/rule/getRuleExecutionKPI", + "alerting:metrics.alert.threshold/alerts/rule/getBackfill", + "alerting:metrics.alert.threshold/alerts/rule/findBackfill", + "alerting:metrics.alert.threshold/alerts/rule/create", + "alerting:metrics.alert.threshold/alerts/rule/delete", + "alerting:metrics.alert.threshold/alerts/rule/update", + "alerting:metrics.alert.threshold/alerts/rule/updateApiKey", + "alerting:metrics.alert.threshold/alerts/rule/enable", + "alerting:metrics.alert.threshold/alerts/rule/disable", + "alerting:metrics.alert.threshold/alerts/rule/muteAll", + "alerting:metrics.alert.threshold/alerts/rule/unmuteAll", + "alerting:metrics.alert.threshold/alerts/rule/muteAlert", + "alerting:metrics.alert.threshold/alerts/rule/unmuteAlert", + "alerting:metrics.alert.threshold/alerts/rule/snooze", + "alerting:metrics.alert.threshold/alerts/rule/bulkEdit", + "alerting:metrics.alert.threshold/alerts/rule/bulkDelete", + "alerting:metrics.alert.threshold/alerts/rule/bulkEnable", + "alerting:metrics.alert.threshold/alerts/rule/bulkDisable", + "alerting:metrics.alert.threshold/alerts/rule/unsnooze", + "alerting:metrics.alert.threshold/alerts/rule/runSoon", + "alerting:metrics.alert.threshold/alerts/rule/scheduleBackfill", + "alerting:metrics.alert.threshold/alerts/rule/deleteBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/get", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleState", + "alerting:metrics.alert.inventory.threshold/observability/rule/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/rule/getExecutionLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/getActionErrorLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/find", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleExecutionKPI", + "alerting:metrics.alert.inventory.threshold/observability/rule/getBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/findBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/create", + "alerting:metrics.alert.inventory.threshold/observability/rule/delete", + "alerting:metrics.alert.inventory.threshold/observability/rule/update", + "alerting:metrics.alert.inventory.threshold/observability/rule/updateApiKey", + "alerting:metrics.alert.inventory.threshold/observability/rule/enable", + "alerting:metrics.alert.inventory.threshold/observability/rule/disable", + "alerting:metrics.alert.inventory.threshold/observability/rule/muteAll", + "alerting:metrics.alert.inventory.threshold/observability/rule/unmuteAll", + "alerting:metrics.alert.inventory.threshold/observability/rule/muteAlert", + "alerting:metrics.alert.inventory.threshold/observability/rule/unmuteAlert", + "alerting:metrics.alert.inventory.threshold/observability/rule/snooze", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkEdit", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkDelete", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkEnable", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkDisable", + "alerting:metrics.alert.inventory.threshold/observability/rule/unsnooze", + "alerting:metrics.alert.inventory.threshold/observability/rule/runSoon", + "alerting:metrics.alert.inventory.threshold/observability/rule/scheduleBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/deleteBackfill", + "alerting:metrics.alert.inventory.threshold/alerts/rule/get", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getRuleState", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getExecutionLog", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getActionErrorLog", + "alerting:metrics.alert.inventory.threshold/alerts/rule/find", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getRuleExecutionKPI", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getBackfill", + "alerting:metrics.alert.inventory.threshold/alerts/rule/findBackfill", + "alerting:metrics.alert.inventory.threshold/alerts/rule/create", + "alerting:metrics.alert.inventory.threshold/alerts/rule/delete", + "alerting:metrics.alert.inventory.threshold/alerts/rule/update", + "alerting:metrics.alert.inventory.threshold/alerts/rule/updateApiKey", + "alerting:metrics.alert.inventory.threshold/alerts/rule/enable", + "alerting:metrics.alert.inventory.threshold/alerts/rule/disable", + "alerting:metrics.alert.inventory.threshold/alerts/rule/muteAll", + "alerting:metrics.alert.inventory.threshold/alerts/rule/unmuteAll", + "alerting:metrics.alert.inventory.threshold/alerts/rule/muteAlert", + "alerting:metrics.alert.inventory.threshold/alerts/rule/unmuteAlert", + "alerting:metrics.alert.inventory.threshold/alerts/rule/snooze", + "alerting:metrics.alert.inventory.threshold/alerts/rule/bulkEdit", + "alerting:metrics.alert.inventory.threshold/alerts/rule/bulkDelete", + "alerting:metrics.alert.inventory.threshold/alerts/rule/bulkEnable", + "alerting:metrics.alert.inventory.threshold/alerts/rule/bulkDisable", + "alerting:metrics.alert.inventory.threshold/alerts/rule/unsnooze", + "alerting:metrics.alert.inventory.threshold/alerts/rule/runSoon", + "alerting:metrics.alert.inventory.threshold/alerts/rule/scheduleBackfill", + "alerting:metrics.alert.inventory.threshold/alerts/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.tls/observability/rule/get", + "alerting:xpack.uptime.alerts.tls/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.tls/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tls/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tls/observability/rule/find", + "alerting:xpack.uptime.alerts.tls/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tls/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.tls/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.tls/observability/rule/create", + "alerting:xpack.uptime.alerts.tls/observability/rule/delete", + "alerting:xpack.uptime.alerts.tls/observability/rule/update", + "alerting:xpack.uptime.alerts.tls/observability/rule/updateApiKey", + "alerting:xpack.uptime.alerts.tls/observability/rule/enable", + "alerting:xpack.uptime.alerts.tls/observability/rule/disable", + "alerting:xpack.uptime.alerts.tls/observability/rule/muteAll", + "alerting:xpack.uptime.alerts.tls/observability/rule/unmuteAll", + "alerting:xpack.uptime.alerts.tls/observability/rule/muteAlert", + "alerting:xpack.uptime.alerts.tls/observability/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.tls/observability/rule/snooze", + "alerting:xpack.uptime.alerts.tls/observability/rule/bulkEdit", + "alerting:xpack.uptime.alerts.tls/observability/rule/bulkDelete", + "alerting:xpack.uptime.alerts.tls/observability/rule/bulkEnable", + "alerting:xpack.uptime.alerts.tls/observability/rule/bulkDisable", + "alerting:xpack.uptime.alerts.tls/observability/rule/unsnooze", + "alerting:xpack.uptime.alerts.tls/observability/rule/runSoon", + "alerting:xpack.uptime.alerts.tls/observability/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.tls/observability/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/get", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/find", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/create", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/delete", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/update", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/updateApiKey", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/enable", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/disable", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/muteAll", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/unmuteAll", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/muteAlert", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/snooze", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/bulkEdit", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/bulkDelete", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/bulkEnable", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/bulkDisable", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/unsnooze", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/runSoon", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/get", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/find", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/create", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/delete", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/update", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/updateApiKey", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/enable", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/disable", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/muteAll", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/unmuteAll", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/muteAlert", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/snooze", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/bulkEdit", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/bulkDelete", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/bulkEnable", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/bulkDisable", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/unsnooze", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/runSoon", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/get", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/find", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/create", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/delete", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/update", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/updateApiKey", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/enable", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/disable", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/muteAll", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/unmuteAll", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/muteAlert", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/snooze", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/bulkEdit", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/bulkDelete", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/bulkEnable", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/bulkDisable", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/unsnooze", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/runSoon", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/deleteBackfill", + "alerting:logs.alert.document.count/observability/rule/get", + "alerting:logs.alert.document.count/observability/rule/getRuleState", + "alerting:logs.alert.document.count/observability/rule/getAlertSummary", + "alerting:logs.alert.document.count/observability/rule/getExecutionLog", + "alerting:logs.alert.document.count/observability/rule/getActionErrorLog", + "alerting:logs.alert.document.count/observability/rule/find", + "alerting:logs.alert.document.count/observability/rule/getRuleExecutionKPI", + "alerting:logs.alert.document.count/observability/rule/getBackfill", + "alerting:logs.alert.document.count/observability/rule/findBackfill", + "alerting:logs.alert.document.count/observability/rule/create", + "alerting:logs.alert.document.count/observability/rule/delete", + "alerting:logs.alert.document.count/observability/rule/update", + "alerting:logs.alert.document.count/observability/rule/updateApiKey", + "alerting:logs.alert.document.count/observability/rule/enable", + "alerting:logs.alert.document.count/observability/rule/disable", + "alerting:logs.alert.document.count/observability/rule/muteAll", + "alerting:logs.alert.document.count/observability/rule/unmuteAll", + "alerting:logs.alert.document.count/observability/rule/muteAlert", + "alerting:logs.alert.document.count/observability/rule/unmuteAlert", + "alerting:logs.alert.document.count/observability/rule/snooze", + "alerting:logs.alert.document.count/observability/rule/bulkEdit", + "alerting:logs.alert.document.count/observability/rule/bulkDelete", + "alerting:logs.alert.document.count/observability/rule/bulkEnable", + "alerting:logs.alert.document.count/observability/rule/bulkDisable", + "alerting:logs.alert.document.count/observability/rule/unsnooze", + "alerting:logs.alert.document.count/observability/rule/runSoon", + "alerting:logs.alert.document.count/observability/rule/scheduleBackfill", + "alerting:logs.alert.document.count/observability/rule/deleteBackfill", + "alerting:logs.alert.document.count/alerts/rule/get", + "alerting:logs.alert.document.count/alerts/rule/getRuleState", + "alerting:logs.alert.document.count/alerts/rule/getAlertSummary", + "alerting:logs.alert.document.count/alerts/rule/getExecutionLog", + "alerting:logs.alert.document.count/alerts/rule/getActionErrorLog", + "alerting:logs.alert.document.count/alerts/rule/find", + "alerting:logs.alert.document.count/alerts/rule/getRuleExecutionKPI", + "alerting:logs.alert.document.count/alerts/rule/getBackfill", + "alerting:logs.alert.document.count/alerts/rule/findBackfill", + "alerting:logs.alert.document.count/alerts/rule/create", + "alerting:logs.alert.document.count/alerts/rule/delete", + "alerting:logs.alert.document.count/alerts/rule/update", + "alerting:logs.alert.document.count/alerts/rule/updateApiKey", + "alerting:logs.alert.document.count/alerts/rule/enable", + "alerting:logs.alert.document.count/alerts/rule/disable", + "alerting:logs.alert.document.count/alerts/rule/muteAll", + "alerting:logs.alert.document.count/alerts/rule/unmuteAll", + "alerting:logs.alert.document.count/alerts/rule/muteAlert", + "alerting:logs.alert.document.count/alerts/rule/unmuteAlert", + "alerting:logs.alert.document.count/alerts/rule/snooze", + "alerting:logs.alert.document.count/alerts/rule/bulkEdit", + "alerting:logs.alert.document.count/alerts/rule/bulkDelete", + "alerting:logs.alert.document.count/alerts/rule/bulkEnable", + "alerting:logs.alert.document.count/alerts/rule/bulkDisable", + "alerting:logs.alert.document.count/alerts/rule/unsnooze", + "alerting:logs.alert.document.count/alerts/rule/runSoon", + "alerting:logs.alert.document.count/alerts/rule/scheduleBackfill", + "alerting:logs.alert.document.count/alerts/rule/deleteBackfill", + "alerting:slo.rules.burnRate/observability/rule/get", + "alerting:slo.rules.burnRate/observability/rule/getRuleState", + "alerting:slo.rules.burnRate/observability/rule/getAlertSummary", + "alerting:slo.rules.burnRate/observability/rule/getExecutionLog", + "alerting:slo.rules.burnRate/observability/rule/getActionErrorLog", + "alerting:slo.rules.burnRate/observability/rule/find", + "alerting:slo.rules.burnRate/observability/rule/getRuleExecutionKPI", + "alerting:slo.rules.burnRate/observability/rule/getBackfill", + "alerting:slo.rules.burnRate/observability/rule/findBackfill", + "alerting:slo.rules.burnRate/observability/rule/create", + "alerting:slo.rules.burnRate/observability/rule/delete", + "alerting:slo.rules.burnRate/observability/rule/update", + "alerting:slo.rules.burnRate/observability/rule/updateApiKey", + "alerting:slo.rules.burnRate/observability/rule/enable", + "alerting:slo.rules.burnRate/observability/rule/disable", + "alerting:slo.rules.burnRate/observability/rule/muteAll", + "alerting:slo.rules.burnRate/observability/rule/unmuteAll", + "alerting:slo.rules.burnRate/observability/rule/muteAlert", + "alerting:slo.rules.burnRate/observability/rule/unmuteAlert", + "alerting:slo.rules.burnRate/observability/rule/snooze", + "alerting:slo.rules.burnRate/observability/rule/bulkEdit", + "alerting:slo.rules.burnRate/observability/rule/bulkDelete", + "alerting:slo.rules.burnRate/observability/rule/bulkEnable", + "alerting:slo.rules.burnRate/observability/rule/bulkDisable", + "alerting:slo.rules.burnRate/observability/rule/unsnooze", + "alerting:slo.rules.burnRate/observability/rule/runSoon", + "alerting:slo.rules.burnRate/observability/rule/scheduleBackfill", + "alerting:slo.rules.burnRate/observability/rule/deleteBackfill", + "alerting:slo.rules.burnRate/alerts/rule/get", + "alerting:slo.rules.burnRate/alerts/rule/getRuleState", + "alerting:slo.rules.burnRate/alerts/rule/getAlertSummary", + "alerting:slo.rules.burnRate/alerts/rule/getExecutionLog", + "alerting:slo.rules.burnRate/alerts/rule/getActionErrorLog", + "alerting:slo.rules.burnRate/alerts/rule/find", + "alerting:slo.rules.burnRate/alerts/rule/getRuleExecutionKPI", + "alerting:slo.rules.burnRate/alerts/rule/getBackfill", + "alerting:slo.rules.burnRate/alerts/rule/findBackfill", + "alerting:slo.rules.burnRate/alerts/rule/create", + "alerting:slo.rules.burnRate/alerts/rule/delete", + "alerting:slo.rules.burnRate/alerts/rule/update", + "alerting:slo.rules.burnRate/alerts/rule/updateApiKey", + "alerting:slo.rules.burnRate/alerts/rule/enable", + "alerting:slo.rules.burnRate/alerts/rule/disable", + "alerting:slo.rules.burnRate/alerts/rule/muteAll", + "alerting:slo.rules.burnRate/alerts/rule/unmuteAll", + "alerting:slo.rules.burnRate/alerts/rule/muteAlert", + "alerting:slo.rules.burnRate/alerts/rule/unmuteAlert", + "alerting:slo.rules.burnRate/alerts/rule/snooze", + "alerting:slo.rules.burnRate/alerts/rule/bulkEdit", + "alerting:slo.rules.burnRate/alerts/rule/bulkDelete", + "alerting:slo.rules.burnRate/alerts/rule/bulkEnable", + "alerting:slo.rules.burnRate/alerts/rule/bulkDisable", + "alerting:slo.rules.burnRate/alerts/rule/unsnooze", + "alerting:slo.rules.burnRate/alerts/rule/runSoon", + "alerting:slo.rules.burnRate/alerts/rule/scheduleBackfill", + "alerting:slo.rules.burnRate/alerts/rule/deleteBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/get", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleState", + "alerting:observability.rules.custom_threshold/observability/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/observability/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/observability/rule/find", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/observability/rule/getBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/findBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/create", + "alerting:observability.rules.custom_threshold/observability/rule/delete", + "alerting:observability.rules.custom_threshold/observability/rule/update", + "alerting:observability.rules.custom_threshold/observability/rule/updateApiKey", + "alerting:observability.rules.custom_threshold/observability/rule/enable", + "alerting:observability.rules.custom_threshold/observability/rule/disable", + "alerting:observability.rules.custom_threshold/observability/rule/muteAll", + "alerting:observability.rules.custom_threshold/observability/rule/unmuteAll", + "alerting:observability.rules.custom_threshold/observability/rule/muteAlert", + "alerting:observability.rules.custom_threshold/observability/rule/unmuteAlert", + "alerting:observability.rules.custom_threshold/observability/rule/snooze", + "alerting:observability.rules.custom_threshold/observability/rule/bulkEdit", + "alerting:observability.rules.custom_threshold/observability/rule/bulkDelete", + "alerting:observability.rules.custom_threshold/observability/rule/bulkEnable", + "alerting:observability.rules.custom_threshold/observability/rule/bulkDisable", + "alerting:observability.rules.custom_threshold/observability/rule/unsnooze", + "alerting:observability.rules.custom_threshold/observability/rule/runSoon", + "alerting:observability.rules.custom_threshold/observability/rule/scheduleBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/deleteBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/get", + "alerting:observability.rules.custom_threshold/alerts/rule/getRuleState", + "alerting:observability.rules.custom_threshold/alerts/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/alerts/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/alerts/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/alerts/rule/find", + "alerting:observability.rules.custom_threshold/alerts/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/alerts/rule/getBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/findBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/create", + "alerting:observability.rules.custom_threshold/alerts/rule/delete", + "alerting:observability.rules.custom_threshold/alerts/rule/update", + "alerting:observability.rules.custom_threshold/alerts/rule/updateApiKey", + "alerting:observability.rules.custom_threshold/alerts/rule/enable", + "alerting:observability.rules.custom_threshold/alerts/rule/disable", + "alerting:observability.rules.custom_threshold/alerts/rule/muteAll", + "alerting:observability.rules.custom_threshold/alerts/rule/unmuteAll", + "alerting:observability.rules.custom_threshold/alerts/rule/muteAlert", + "alerting:observability.rules.custom_threshold/alerts/rule/unmuteAlert", + "alerting:observability.rules.custom_threshold/alerts/rule/snooze", + "alerting:observability.rules.custom_threshold/alerts/rule/bulkEdit", + "alerting:observability.rules.custom_threshold/alerts/rule/bulkDelete", + "alerting:observability.rules.custom_threshold/alerts/rule/bulkEnable", + "alerting:observability.rules.custom_threshold/alerts/rule/bulkDisable", + "alerting:observability.rules.custom_threshold/alerts/rule/unsnooze", + "alerting:observability.rules.custom_threshold/alerts/rule/runSoon", + "alerting:observability.rules.custom_threshold/alerts/rule/scheduleBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/deleteBackfill", + "alerting:.es-query/observability/rule/get", + "alerting:.es-query/observability/rule/getRuleState", + "alerting:.es-query/observability/rule/getAlertSummary", + "alerting:.es-query/observability/rule/getExecutionLog", + "alerting:.es-query/observability/rule/getActionErrorLog", + "alerting:.es-query/observability/rule/find", + "alerting:.es-query/observability/rule/getRuleExecutionKPI", + "alerting:.es-query/observability/rule/getBackfill", + "alerting:.es-query/observability/rule/findBackfill", + "alerting:.es-query/observability/rule/create", + "alerting:.es-query/observability/rule/delete", + "alerting:.es-query/observability/rule/update", + "alerting:.es-query/observability/rule/updateApiKey", + "alerting:.es-query/observability/rule/enable", + "alerting:.es-query/observability/rule/disable", + "alerting:.es-query/observability/rule/muteAll", + "alerting:.es-query/observability/rule/unmuteAll", + "alerting:.es-query/observability/rule/muteAlert", + "alerting:.es-query/observability/rule/unmuteAlert", + "alerting:.es-query/observability/rule/snooze", + "alerting:.es-query/observability/rule/bulkEdit", + "alerting:.es-query/observability/rule/bulkDelete", + "alerting:.es-query/observability/rule/bulkEnable", + "alerting:.es-query/observability/rule/bulkDisable", + "alerting:.es-query/observability/rule/unsnooze", + "alerting:.es-query/observability/rule/runSoon", + "alerting:.es-query/observability/rule/scheduleBackfill", + "alerting:.es-query/observability/rule/deleteBackfill", + "alerting:.es-query/alerts/rule/get", + "alerting:.es-query/alerts/rule/getRuleState", + "alerting:.es-query/alerts/rule/getAlertSummary", + "alerting:.es-query/alerts/rule/getExecutionLog", + "alerting:.es-query/alerts/rule/getActionErrorLog", + "alerting:.es-query/alerts/rule/find", + "alerting:.es-query/alerts/rule/getRuleExecutionKPI", + "alerting:.es-query/alerts/rule/getBackfill", + "alerting:.es-query/alerts/rule/findBackfill", + "alerting:.es-query/alerts/rule/create", + "alerting:.es-query/alerts/rule/delete", + "alerting:.es-query/alerts/rule/update", + "alerting:.es-query/alerts/rule/updateApiKey", + "alerting:.es-query/alerts/rule/enable", + "alerting:.es-query/alerts/rule/disable", + "alerting:.es-query/alerts/rule/muteAll", + "alerting:.es-query/alerts/rule/unmuteAll", + "alerting:.es-query/alerts/rule/muteAlert", + "alerting:.es-query/alerts/rule/unmuteAlert", + "alerting:.es-query/alerts/rule/snooze", + "alerting:.es-query/alerts/rule/bulkEdit", + "alerting:.es-query/alerts/rule/bulkDelete", + "alerting:.es-query/alerts/rule/bulkEnable", + "alerting:.es-query/alerts/rule/bulkDisable", + "alerting:.es-query/alerts/rule/unsnooze", + "alerting:.es-query/alerts/rule/runSoon", + "alerting:.es-query/alerts/rule/scheduleBackfill", + "alerting:.es-query/alerts/rule/deleteBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/create", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/delete", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/update", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/updateApiKey", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/enable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/disable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/muteAll", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unmuteAll", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/muteAlert", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unmuteAlert", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/snooze", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkEdit", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkDelete", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkEnable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkDisable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unsnooze", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/runSoon", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/scheduleBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/deleteBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/create", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/delete", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/update", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/updateApiKey", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/enable", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/disable", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/muteAll", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/unmuteAll", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/muteAlert", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/unmuteAlert", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/snooze", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/bulkEdit", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/bulkDelete", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/bulkEnable", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/bulkDisable", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/unsnooze", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/runSoon", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/scheduleBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/deleteBackfill", "alerting:apm.error_rate/observability/alert/get", "alerting:apm.error_rate/observability/alert/find", "alerting:apm.error_rate/observability/alert/getAuthorizedAlertsIndices", "alerting:apm.error_rate/observability/alert/getAlertSummary", "alerting:apm.error_rate/observability/alert/update", + "alerting:apm.error_rate/alerts/alert/get", + "alerting:apm.error_rate/alerts/alert/find", + "alerting:apm.error_rate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.error_rate/alerts/alert/getAlertSummary", + "alerting:apm.error_rate/alerts/alert/update", "alerting:apm.transaction_error_rate/observability/alert/get", "alerting:apm.transaction_error_rate/observability/alert/find", "alerting:apm.transaction_error_rate/observability/alert/getAuthorizedAlertsIndices", "alerting:apm.transaction_error_rate/observability/alert/getAlertSummary", "alerting:apm.transaction_error_rate/observability/alert/update", + "alerting:apm.transaction_error_rate/alerts/alert/get", + "alerting:apm.transaction_error_rate/alerts/alert/find", + "alerting:apm.transaction_error_rate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_error_rate/alerts/alert/getAlertSummary", + "alerting:apm.transaction_error_rate/alerts/alert/update", "alerting:apm.transaction_duration/observability/alert/get", "alerting:apm.transaction_duration/observability/alert/find", "alerting:apm.transaction_duration/observability/alert/getAuthorizedAlertsIndices", "alerting:apm.transaction_duration/observability/alert/getAlertSummary", "alerting:apm.transaction_duration/observability/alert/update", + "alerting:apm.transaction_duration/alerts/alert/get", + "alerting:apm.transaction_duration/alerts/alert/find", + "alerting:apm.transaction_duration/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_duration/alerts/alert/getAlertSummary", + "alerting:apm.transaction_duration/alerts/alert/update", "alerting:apm.anomaly/observability/alert/get", "alerting:apm.anomaly/observability/alert/find", "alerting:apm.anomaly/observability/alert/getAuthorizedAlertsIndices", "alerting:apm.anomaly/observability/alert/getAlertSummary", "alerting:apm.anomaly/observability/alert/update", + "alerting:apm.anomaly/alerts/alert/get", + "alerting:apm.anomaly/alerts/alert/find", + "alerting:apm.anomaly/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.anomaly/alerts/alert/getAlertSummary", + "alerting:apm.anomaly/alerts/alert/update", "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/get", "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/find", "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/getAuthorizedAlertsIndices", @@ -9374,6 +18878,125 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.synthetics.alerts.tls/observability/alert/getAuthorizedAlertsIndices", "alerting:xpack.synthetics.alerts.tls/observability/alert/getAlertSummary", "alerting:xpack.synthetics.alerts.tls/observability/alert/update", + "alerting:metrics.alert.threshold/observability/alert/get", + "alerting:metrics.alert.threshold/observability/alert/find", + "alerting:metrics.alert.threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.threshold/observability/alert/getAlertSummary", + "alerting:metrics.alert.threshold/observability/alert/update", + "alerting:metrics.alert.threshold/alerts/alert/get", + "alerting:metrics.alert.threshold/alerts/alert/find", + "alerting:metrics.alert.threshold/alerts/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.threshold/alerts/alert/getAlertSummary", + "alerting:metrics.alert.threshold/alerts/alert/update", + "alerting:metrics.alert.inventory.threshold/observability/alert/get", + "alerting:metrics.alert.inventory.threshold/observability/alert/find", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/alert/update", + "alerting:metrics.alert.inventory.threshold/alerts/alert/get", + "alerting:metrics.alert.inventory.threshold/alerts/alert/find", + "alerting:metrics.alert.inventory.threshold/alerts/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.inventory.threshold/alerts/alert/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/alerts/alert/update", + "alerting:xpack.uptime.alerts.tls/observability/alert/get", + "alerting:xpack.uptime.alerts.tls/observability/alert/find", + "alerting:xpack.uptime.alerts.tls/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tls/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/observability/alert/update", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/get", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/find", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/update", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/get", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/find", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/update", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/get", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/find", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/update", + "alerting:logs.alert.document.count/observability/alert/get", + "alerting:logs.alert.document.count/observability/alert/find", + "alerting:logs.alert.document.count/observability/alert/getAuthorizedAlertsIndices", + "alerting:logs.alert.document.count/observability/alert/getAlertSummary", + "alerting:logs.alert.document.count/observability/alert/update", + "alerting:logs.alert.document.count/alerts/alert/get", + "alerting:logs.alert.document.count/alerts/alert/find", + "alerting:logs.alert.document.count/alerts/alert/getAuthorizedAlertsIndices", + "alerting:logs.alert.document.count/alerts/alert/getAlertSummary", + "alerting:logs.alert.document.count/alerts/alert/update", + "alerting:slo.rules.burnRate/observability/alert/get", + "alerting:slo.rules.burnRate/observability/alert/find", + "alerting:slo.rules.burnRate/observability/alert/getAuthorizedAlertsIndices", + "alerting:slo.rules.burnRate/observability/alert/getAlertSummary", + "alerting:slo.rules.burnRate/observability/alert/update", + "alerting:slo.rules.burnRate/alerts/alert/get", + "alerting:slo.rules.burnRate/alerts/alert/find", + "alerting:slo.rules.burnRate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:slo.rules.burnRate/alerts/alert/getAlertSummary", + "alerting:slo.rules.burnRate/alerts/alert/update", + "alerting:observability.rules.custom_threshold/observability/alert/get", + "alerting:observability.rules.custom_threshold/observability/alert/find", + "alerting:observability.rules.custom_threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/observability/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/alert/update", + "alerting:observability.rules.custom_threshold/alerts/alert/get", + "alerting:observability.rules.custom_threshold/alerts/alert/find", + "alerting:observability.rules.custom_threshold/alerts/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/alerts/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/alerts/alert/update", + "alerting:.es-query/observability/alert/get", + "alerting:.es-query/observability/alert/find", + "alerting:.es-query/observability/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/observability/alert/getAlertSummary", + "alerting:.es-query/observability/alert/update", + "alerting:.es-query/alerts/alert/get", + "alerting:.es-query/alerts/alert/find", + "alerting:.es-query/alerts/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/alerts/alert/getAlertSummary", + "alerting:.es-query/alerts/alert/update", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/update", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/update", + ], + "can_manage_private_locations": Array [ + "login:", + "api:private-location-write", + "saved_object:synthetics-private-location/bulk_get", + "saved_object:synthetics-private-location/get", + "saved_object:synthetics-private-location/find", + "saved_object:synthetics-private-location/open_point_in_time", + "saved_object:synthetics-private-location/close_point_in_time", + "saved_object:synthetics-private-location/create", + "saved_object:synthetics-private-location/bulk_create", + "saved_object:synthetics-private-location/update", + "saved_object:synthetics-private-location/bulk_update", + "saved_object:synthetics-private-location/delete", + "saved_object:synthetics-private-location/bulk_delete", + "saved_object:synthetics-private-location/share_to_space", + "saved_object:synthetics-privates-locations/bulk_get", + "saved_object:synthetics-privates-locations/get", + "saved_object:synthetics-privates-locations/find", + "saved_object:synthetics-privates-locations/open_point_in_time", + "saved_object:synthetics-privates-locations/close_point_in_time", + "saved_object:synthetics-privates-locations/create", + "saved_object:synthetics-privates-locations/bulk_create", + "saved_object:synthetics-privates-locations/update", + "saved_object:synthetics-privates-locations/bulk_update", + "saved_object:synthetics-privates-locations/delete", + "saved_object:synthetics-privates-locations/bulk_delete", + "saved_object:synthetics-privates-locations/share_to_space", + "ui:uptime/canManagePrivateLocations", ], "elastic_managed_locations_enabled": Array [ "login:", @@ -9429,30 +19052,6 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:uptime-synthetics-api-key/delete", "saved_object:uptime-synthetics-api-key/bulk_delete", "saved_object:uptime-synthetics-api-key/share_to_space", - "saved_object:synthetics-private-location/bulk_get", - "saved_object:synthetics-private-location/get", - "saved_object:synthetics-private-location/find", - "saved_object:synthetics-private-location/open_point_in_time", - "saved_object:synthetics-private-location/close_point_in_time", - "saved_object:synthetics-private-location/create", - "saved_object:synthetics-private-location/bulk_create", - "saved_object:synthetics-private-location/update", - "saved_object:synthetics-private-location/bulk_update", - "saved_object:synthetics-private-location/delete", - "saved_object:synthetics-private-location/bulk_delete", - "saved_object:synthetics-private-location/share_to_space", - "saved_object:synthetics-privates-locations/bulk_get", - "saved_object:synthetics-privates-locations/get", - "saved_object:synthetics-privates-locations/find", - "saved_object:synthetics-privates-locations/open_point_in_time", - "saved_object:synthetics-privates-locations/close_point_in_time", - "saved_object:synthetics-privates-locations/create", - "saved_object:synthetics-privates-locations/bulk_create", - "saved_object:synthetics-privates-locations/update", - "saved_object:synthetics-privates-locations/bulk_update", - "saved_object:synthetics-privates-locations/delete", - "saved_object:synthetics-privates-locations/bulk_delete", - "saved_object:synthetics-privates-locations/share_to_space", "saved_object:synthetics-param/bulk_get", "saved_object:synthetics-param/get", "saved_object:synthetics-param/find", @@ -9489,6 +19088,16 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:telemetry/delete", "saved_object:telemetry/bulk_delete", "saved_object:telemetry/share_to_space", + "saved_object:synthetics-private-location/bulk_get", + "saved_object:synthetics-private-location/get", + "saved_object:synthetics-private-location/find", + "saved_object:synthetics-private-location/open_point_in_time", + "saved_object:synthetics-private-location/close_point_in_time", + "saved_object:synthetics-privates-locations/bulk_get", + "saved_object:synthetics-privates-locations/get", + "saved_object:synthetics-privates-locations/find", + "saved_object:synthetics-privates-locations/open_point_in_time", + "saved_object:synthetics-privates-locations/close_point_in_time", "saved_object:config/bulk_get", "saved_object:config/get", "saved_object:config/find", @@ -9536,6 +19145,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.uptime.alerts.tls/uptime/rule/runSoon", "alerting:xpack.uptime.alerts.tls/uptime/rule/scheduleBackfill", "alerting:xpack.uptime.alerts.tls/uptime/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.tls/alerts/rule/get", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tls/alerts/rule/find", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.tls/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.tls/alerts/rule/create", + "alerting:xpack.uptime.alerts.tls/alerts/rule/delete", + "alerting:xpack.uptime.alerts.tls/alerts/rule/update", + "alerting:xpack.uptime.alerts.tls/alerts/rule/updateApiKey", + "alerting:xpack.uptime.alerts.tls/alerts/rule/enable", + "alerting:xpack.uptime.alerts.tls/alerts/rule/disable", + "alerting:xpack.uptime.alerts.tls/alerts/rule/muteAll", + "alerting:xpack.uptime.alerts.tls/alerts/rule/unmuteAll", + "alerting:xpack.uptime.alerts.tls/alerts/rule/muteAlert", + "alerting:xpack.uptime.alerts.tls/alerts/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.tls/alerts/rule/snooze", + "alerting:xpack.uptime.alerts.tls/alerts/rule/bulkEdit", + "alerting:xpack.uptime.alerts.tls/alerts/rule/bulkDelete", + "alerting:xpack.uptime.alerts.tls/alerts/rule/bulkEnable", + "alerting:xpack.uptime.alerts.tls/alerts/rule/bulkDisable", + "alerting:xpack.uptime.alerts.tls/alerts/rule/unsnooze", + "alerting:xpack.uptime.alerts.tls/alerts/rule/runSoon", + "alerting:xpack.uptime.alerts.tls/alerts/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.tls/alerts/rule/deleteBackfill", "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/get", "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/getRuleState", "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/getAlertSummary", @@ -9564,6 +19201,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/runSoon", "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/scheduleBackfill", "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/get", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/find", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/create", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/delete", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/update", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/updateApiKey", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/enable", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/disable", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/muteAll", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/unmuteAll", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/muteAlert", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/snooze", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/bulkEdit", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/bulkDelete", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/bulkEnable", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/bulkDisable", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/unsnooze", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/runSoon", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/deleteBackfill", "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/get", "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/getRuleState", "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/getAlertSummary", @@ -9592,6 +19257,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/runSoon", "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/scheduleBackfill", "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/get", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/find", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/create", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/delete", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/update", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/updateApiKey", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/enable", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/disable", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/muteAll", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/unmuteAll", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/muteAlert", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/snooze", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/bulkEdit", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/bulkDelete", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/bulkEnable", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/bulkDisable", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/unsnooze", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/runSoon", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/deleteBackfill", "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/get", "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/getRuleState", "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/getAlertSummary", @@ -9620,6 +19313,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/runSoon", "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/scheduleBackfill", "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/get", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/find", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/create", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/delete", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/update", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/updateApiKey", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/enable", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/disable", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/muteAll", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/unmuteAll", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/muteAlert", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/snooze", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/bulkEdit", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/bulkDelete", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/bulkEnable", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/bulkDisable", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/unsnooze", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/runSoon", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/deleteBackfill", "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/get", "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/getRuleState", "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/getAlertSummary", @@ -9648,6 +19369,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/runSoon", "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/scheduleBackfill", "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/deleteBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/get", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getRuleState", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getAlertSummary", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getExecutionLog", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getActionErrorLog", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/find", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/findBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/create", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/delete", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/update", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/updateApiKey", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/enable", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/disable", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/muteAll", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/unmuteAll", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/muteAlert", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/unmuteAlert", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/snooze", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/bulkEdit", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/bulkDelete", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/bulkEnable", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/bulkDisable", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/unsnooze", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/runSoon", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/scheduleBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/deleteBackfill", "alerting:xpack.synthetics.alerts.tls/uptime/rule/get", "alerting:xpack.synthetics.alerts.tls/uptime/rule/getRuleState", "alerting:xpack.synthetics.alerts.tls/uptime/rule/getAlertSummary", @@ -9676,181 +19425,99 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.synthetics.alerts.tls/uptime/rule/runSoon", "alerting:xpack.synthetics.alerts.tls/uptime/rule/scheduleBackfill", "alerting:xpack.synthetics.alerts.tls/uptime/rule/deleteBackfill", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/get", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getRuleState", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getAlertSummary", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getExecutionLog", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getActionErrorLog", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/find", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getBackfill", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/findBackfill", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/create", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/delete", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/update", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/updateApiKey", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/enable", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/disable", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/muteAll", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/unmuteAll", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/muteAlert", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/unmuteAlert", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/snooze", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/bulkEdit", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/bulkDelete", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/bulkEnable", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/bulkDisable", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/unsnooze", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/runSoon", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/scheduleBackfill", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/deleteBackfill", "alerting:xpack.uptime.alerts.tls/uptime/alert/get", "alerting:xpack.uptime.alerts.tls/uptime/alert/find", "alerting:xpack.uptime.alerts.tls/uptime/alert/getAuthorizedAlertsIndices", "alerting:xpack.uptime.alerts.tls/uptime/alert/getAlertSummary", "alerting:xpack.uptime.alerts.tls/uptime/alert/update", + "alerting:xpack.uptime.alerts.tls/alerts/alert/get", + "alerting:xpack.uptime.alerts.tls/alerts/alert/find", + "alerting:xpack.uptime.alerts.tls/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tls/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/alerts/alert/update", "alerting:xpack.uptime.alerts.tlsCertificate/uptime/alert/get", "alerting:xpack.uptime.alerts.tlsCertificate/uptime/alert/find", "alerting:xpack.uptime.alerts.tlsCertificate/uptime/alert/getAuthorizedAlertsIndices", "alerting:xpack.uptime.alerts.tlsCertificate/uptime/alert/getAlertSummary", "alerting:xpack.uptime.alerts.tlsCertificate/uptime/alert/update", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/get", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/find", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/update", "alerting:xpack.uptime.alerts.monitorStatus/uptime/alert/get", "alerting:xpack.uptime.alerts.monitorStatus/uptime/alert/find", "alerting:xpack.uptime.alerts.monitorStatus/uptime/alert/getAuthorizedAlertsIndices", "alerting:xpack.uptime.alerts.monitorStatus/uptime/alert/getAlertSummary", "alerting:xpack.uptime.alerts.monitorStatus/uptime/alert/update", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/get", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/find", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/update", "alerting:xpack.uptime.alerts.durationAnomaly/uptime/alert/get", "alerting:xpack.uptime.alerts.durationAnomaly/uptime/alert/find", "alerting:xpack.uptime.alerts.durationAnomaly/uptime/alert/getAuthorizedAlertsIndices", "alerting:xpack.uptime.alerts.durationAnomaly/uptime/alert/getAlertSummary", "alerting:xpack.uptime.alerts.durationAnomaly/uptime/alert/update", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/get", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/find", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/update", "alerting:xpack.synthetics.alerts.monitorStatus/uptime/alert/get", "alerting:xpack.synthetics.alerts.monitorStatus/uptime/alert/find", "alerting:xpack.synthetics.alerts.monitorStatus/uptime/alert/getAuthorizedAlertsIndices", "alerting:xpack.synthetics.alerts.monitorStatus/uptime/alert/getAlertSummary", "alerting:xpack.synthetics.alerts.monitorStatus/uptime/alert/update", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/get", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/find", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/getAlertSummary", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/update", "alerting:xpack.synthetics.alerts.tls/uptime/alert/get", "alerting:xpack.synthetics.alerts.tls/uptime/alert/find", "alerting:xpack.synthetics.alerts.tls/uptime/alert/getAuthorizedAlertsIndices", "alerting:xpack.synthetics.alerts.tls/uptime/alert/getAlertSummary", "alerting:xpack.synthetics.alerts.tls/uptime/alert/update", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/get", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/find", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/getAlertSummary", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/update", "app:observability", "ui:catalogue/observability", "ui:navLinks/observability", "ui:observability/read", "ui:observability/write", - "alerting:slo.rules.burnRate/observability/rule/get", - "alerting:slo.rules.burnRate/observability/rule/getRuleState", - "alerting:slo.rules.burnRate/observability/rule/getAlertSummary", - "alerting:slo.rules.burnRate/observability/rule/getExecutionLog", - "alerting:slo.rules.burnRate/observability/rule/getActionErrorLog", - "alerting:slo.rules.burnRate/observability/rule/find", - "alerting:slo.rules.burnRate/observability/rule/getRuleExecutionKPI", - "alerting:slo.rules.burnRate/observability/rule/getBackfill", - "alerting:slo.rules.burnRate/observability/rule/findBackfill", - "alerting:slo.rules.burnRate/observability/rule/create", - "alerting:slo.rules.burnRate/observability/rule/delete", - "alerting:slo.rules.burnRate/observability/rule/update", - "alerting:slo.rules.burnRate/observability/rule/updateApiKey", - "alerting:slo.rules.burnRate/observability/rule/enable", - "alerting:slo.rules.burnRate/observability/rule/disable", - "alerting:slo.rules.burnRate/observability/rule/muteAll", - "alerting:slo.rules.burnRate/observability/rule/unmuteAll", - "alerting:slo.rules.burnRate/observability/rule/muteAlert", - "alerting:slo.rules.burnRate/observability/rule/unmuteAlert", - "alerting:slo.rules.burnRate/observability/rule/snooze", - "alerting:slo.rules.burnRate/observability/rule/bulkEdit", - "alerting:slo.rules.burnRate/observability/rule/bulkDelete", - "alerting:slo.rules.burnRate/observability/rule/bulkEnable", - "alerting:slo.rules.burnRate/observability/rule/bulkDisable", - "alerting:slo.rules.burnRate/observability/rule/unsnooze", - "alerting:slo.rules.burnRate/observability/rule/runSoon", - "alerting:slo.rules.burnRate/observability/rule/scheduleBackfill", - "alerting:slo.rules.burnRate/observability/rule/deleteBackfill", - "alerting:observability.rules.custom_threshold/observability/rule/get", - "alerting:observability.rules.custom_threshold/observability/rule/getRuleState", - "alerting:observability.rules.custom_threshold/observability/rule/getAlertSummary", - "alerting:observability.rules.custom_threshold/observability/rule/getExecutionLog", - "alerting:observability.rules.custom_threshold/observability/rule/getActionErrorLog", - "alerting:observability.rules.custom_threshold/observability/rule/find", - "alerting:observability.rules.custom_threshold/observability/rule/getRuleExecutionKPI", - "alerting:observability.rules.custom_threshold/observability/rule/getBackfill", - "alerting:observability.rules.custom_threshold/observability/rule/findBackfill", - "alerting:observability.rules.custom_threshold/observability/rule/create", - "alerting:observability.rules.custom_threshold/observability/rule/delete", - "alerting:observability.rules.custom_threshold/observability/rule/update", - "alerting:observability.rules.custom_threshold/observability/rule/updateApiKey", - "alerting:observability.rules.custom_threshold/observability/rule/enable", - "alerting:observability.rules.custom_threshold/observability/rule/disable", - "alerting:observability.rules.custom_threshold/observability/rule/muteAll", - "alerting:observability.rules.custom_threshold/observability/rule/unmuteAll", - "alerting:observability.rules.custom_threshold/observability/rule/muteAlert", - "alerting:observability.rules.custom_threshold/observability/rule/unmuteAlert", - "alerting:observability.rules.custom_threshold/observability/rule/snooze", - "alerting:observability.rules.custom_threshold/observability/rule/bulkEdit", - "alerting:observability.rules.custom_threshold/observability/rule/bulkDelete", - "alerting:observability.rules.custom_threshold/observability/rule/bulkEnable", - "alerting:observability.rules.custom_threshold/observability/rule/bulkDisable", - "alerting:observability.rules.custom_threshold/observability/rule/unsnooze", - "alerting:observability.rules.custom_threshold/observability/rule/runSoon", - "alerting:observability.rules.custom_threshold/observability/rule/scheduleBackfill", - "alerting:observability.rules.custom_threshold/observability/rule/deleteBackfill", - "alerting:.es-query/observability/rule/get", - "alerting:.es-query/observability/rule/getRuleState", - "alerting:.es-query/observability/rule/getAlertSummary", - "alerting:.es-query/observability/rule/getExecutionLog", - "alerting:.es-query/observability/rule/getActionErrorLog", - "alerting:.es-query/observability/rule/find", - "alerting:.es-query/observability/rule/getRuleExecutionKPI", - "alerting:.es-query/observability/rule/getBackfill", - "alerting:.es-query/observability/rule/findBackfill", - "alerting:.es-query/observability/rule/create", - "alerting:.es-query/observability/rule/delete", - "alerting:.es-query/observability/rule/update", - "alerting:.es-query/observability/rule/updateApiKey", - "alerting:.es-query/observability/rule/enable", - "alerting:.es-query/observability/rule/disable", - "alerting:.es-query/observability/rule/muteAll", - "alerting:.es-query/observability/rule/unmuteAll", - "alerting:.es-query/observability/rule/muteAlert", - "alerting:.es-query/observability/rule/unmuteAlert", - "alerting:.es-query/observability/rule/snooze", - "alerting:.es-query/observability/rule/bulkEdit", - "alerting:.es-query/observability/rule/bulkDelete", - "alerting:.es-query/observability/rule/bulkEnable", - "alerting:.es-query/observability/rule/bulkDisable", - "alerting:.es-query/observability/rule/unsnooze", - "alerting:.es-query/observability/rule/runSoon", - "alerting:.es-query/observability/rule/scheduleBackfill", - "alerting:.es-query/observability/rule/deleteBackfill", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/get", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleState", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getAlertSummary", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getExecutionLog", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getActionErrorLog", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/find", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleExecutionKPI", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getBackfill", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/findBackfill", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/create", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/delete", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/update", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/updateApiKey", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/enable", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/disable", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/muteAll", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unmuteAll", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/muteAlert", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unmuteAlert", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/snooze", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkEdit", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkDelete", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkEnable", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkDisable", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unsnooze", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/runSoon", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/scheduleBackfill", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/deleteBackfill", - "alerting:metrics.alert.inventory.threshold/observability/rule/get", - "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleState", - "alerting:metrics.alert.inventory.threshold/observability/rule/getAlertSummary", - "alerting:metrics.alert.inventory.threshold/observability/rule/getExecutionLog", - "alerting:metrics.alert.inventory.threshold/observability/rule/getActionErrorLog", - "alerting:metrics.alert.inventory.threshold/observability/rule/find", - "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleExecutionKPI", - "alerting:metrics.alert.inventory.threshold/observability/rule/getBackfill", - "alerting:metrics.alert.inventory.threshold/observability/rule/findBackfill", - "alerting:metrics.alert.inventory.threshold/observability/rule/create", - "alerting:metrics.alert.inventory.threshold/observability/rule/delete", - "alerting:metrics.alert.inventory.threshold/observability/rule/update", - "alerting:metrics.alert.inventory.threshold/observability/rule/updateApiKey", - "alerting:metrics.alert.inventory.threshold/observability/rule/enable", - "alerting:metrics.alert.inventory.threshold/observability/rule/disable", - "alerting:metrics.alert.inventory.threshold/observability/rule/muteAll", - "alerting:metrics.alert.inventory.threshold/observability/rule/unmuteAll", - "alerting:metrics.alert.inventory.threshold/observability/rule/muteAlert", - "alerting:metrics.alert.inventory.threshold/observability/rule/unmuteAlert", - "alerting:metrics.alert.inventory.threshold/observability/rule/snooze", - "alerting:metrics.alert.inventory.threshold/observability/rule/bulkEdit", - "alerting:metrics.alert.inventory.threshold/observability/rule/bulkDelete", - "alerting:metrics.alert.inventory.threshold/observability/rule/bulkEnable", - "alerting:metrics.alert.inventory.threshold/observability/rule/bulkDisable", - "alerting:metrics.alert.inventory.threshold/observability/rule/unsnooze", - "alerting:metrics.alert.inventory.threshold/observability/rule/runSoon", - "alerting:metrics.alert.inventory.threshold/observability/rule/scheduleBackfill", - "alerting:metrics.alert.inventory.threshold/observability/rule/deleteBackfill", "alerting:apm.error_rate/observability/rule/get", "alerting:apm.error_rate/observability/rule/getRuleState", "alerting:apm.error_rate/observability/rule/getAlertSummary", @@ -9879,6 +19546,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.error_rate/observability/rule/runSoon", "alerting:apm.error_rate/observability/rule/scheduleBackfill", "alerting:apm.error_rate/observability/rule/deleteBackfill", + "alerting:apm.error_rate/alerts/rule/get", + "alerting:apm.error_rate/alerts/rule/getRuleState", + "alerting:apm.error_rate/alerts/rule/getAlertSummary", + "alerting:apm.error_rate/alerts/rule/getExecutionLog", + "alerting:apm.error_rate/alerts/rule/getActionErrorLog", + "alerting:apm.error_rate/alerts/rule/find", + "alerting:apm.error_rate/alerts/rule/getRuleExecutionKPI", + "alerting:apm.error_rate/alerts/rule/getBackfill", + "alerting:apm.error_rate/alerts/rule/findBackfill", + "alerting:apm.error_rate/alerts/rule/create", + "alerting:apm.error_rate/alerts/rule/delete", + "alerting:apm.error_rate/alerts/rule/update", + "alerting:apm.error_rate/alerts/rule/updateApiKey", + "alerting:apm.error_rate/alerts/rule/enable", + "alerting:apm.error_rate/alerts/rule/disable", + "alerting:apm.error_rate/alerts/rule/muteAll", + "alerting:apm.error_rate/alerts/rule/unmuteAll", + "alerting:apm.error_rate/alerts/rule/muteAlert", + "alerting:apm.error_rate/alerts/rule/unmuteAlert", + "alerting:apm.error_rate/alerts/rule/snooze", + "alerting:apm.error_rate/alerts/rule/bulkEdit", + "alerting:apm.error_rate/alerts/rule/bulkDelete", + "alerting:apm.error_rate/alerts/rule/bulkEnable", + "alerting:apm.error_rate/alerts/rule/bulkDisable", + "alerting:apm.error_rate/alerts/rule/unsnooze", + "alerting:apm.error_rate/alerts/rule/runSoon", + "alerting:apm.error_rate/alerts/rule/scheduleBackfill", + "alerting:apm.error_rate/alerts/rule/deleteBackfill", "alerting:apm.transaction_error_rate/observability/rule/get", "alerting:apm.transaction_error_rate/observability/rule/getRuleState", "alerting:apm.transaction_error_rate/observability/rule/getAlertSummary", @@ -9907,6 +19602,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.transaction_error_rate/observability/rule/runSoon", "alerting:apm.transaction_error_rate/observability/rule/scheduleBackfill", "alerting:apm.transaction_error_rate/observability/rule/deleteBackfill", + "alerting:apm.transaction_error_rate/alerts/rule/get", + "alerting:apm.transaction_error_rate/alerts/rule/getRuleState", + "alerting:apm.transaction_error_rate/alerts/rule/getAlertSummary", + "alerting:apm.transaction_error_rate/alerts/rule/getExecutionLog", + "alerting:apm.transaction_error_rate/alerts/rule/getActionErrorLog", + "alerting:apm.transaction_error_rate/alerts/rule/find", + "alerting:apm.transaction_error_rate/alerts/rule/getRuleExecutionKPI", + "alerting:apm.transaction_error_rate/alerts/rule/getBackfill", + "alerting:apm.transaction_error_rate/alerts/rule/findBackfill", + "alerting:apm.transaction_error_rate/alerts/rule/create", + "alerting:apm.transaction_error_rate/alerts/rule/delete", + "alerting:apm.transaction_error_rate/alerts/rule/update", + "alerting:apm.transaction_error_rate/alerts/rule/updateApiKey", + "alerting:apm.transaction_error_rate/alerts/rule/enable", + "alerting:apm.transaction_error_rate/alerts/rule/disable", + "alerting:apm.transaction_error_rate/alerts/rule/muteAll", + "alerting:apm.transaction_error_rate/alerts/rule/unmuteAll", + "alerting:apm.transaction_error_rate/alerts/rule/muteAlert", + "alerting:apm.transaction_error_rate/alerts/rule/unmuteAlert", + "alerting:apm.transaction_error_rate/alerts/rule/snooze", + "alerting:apm.transaction_error_rate/alerts/rule/bulkEdit", + "alerting:apm.transaction_error_rate/alerts/rule/bulkDelete", + "alerting:apm.transaction_error_rate/alerts/rule/bulkEnable", + "alerting:apm.transaction_error_rate/alerts/rule/bulkDisable", + "alerting:apm.transaction_error_rate/alerts/rule/unsnooze", + "alerting:apm.transaction_error_rate/alerts/rule/runSoon", + "alerting:apm.transaction_error_rate/alerts/rule/scheduleBackfill", + "alerting:apm.transaction_error_rate/alerts/rule/deleteBackfill", "alerting:apm.transaction_duration/observability/rule/get", "alerting:apm.transaction_duration/observability/rule/getRuleState", "alerting:apm.transaction_duration/observability/rule/getAlertSummary", @@ -9935,6 +19658,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.transaction_duration/observability/rule/runSoon", "alerting:apm.transaction_duration/observability/rule/scheduleBackfill", "alerting:apm.transaction_duration/observability/rule/deleteBackfill", + "alerting:apm.transaction_duration/alerts/rule/get", + "alerting:apm.transaction_duration/alerts/rule/getRuleState", + "alerting:apm.transaction_duration/alerts/rule/getAlertSummary", + "alerting:apm.transaction_duration/alerts/rule/getExecutionLog", + "alerting:apm.transaction_duration/alerts/rule/getActionErrorLog", + "alerting:apm.transaction_duration/alerts/rule/find", + "alerting:apm.transaction_duration/alerts/rule/getRuleExecutionKPI", + "alerting:apm.transaction_duration/alerts/rule/getBackfill", + "alerting:apm.transaction_duration/alerts/rule/findBackfill", + "alerting:apm.transaction_duration/alerts/rule/create", + "alerting:apm.transaction_duration/alerts/rule/delete", + "alerting:apm.transaction_duration/alerts/rule/update", + "alerting:apm.transaction_duration/alerts/rule/updateApiKey", + "alerting:apm.transaction_duration/alerts/rule/enable", + "alerting:apm.transaction_duration/alerts/rule/disable", + "alerting:apm.transaction_duration/alerts/rule/muteAll", + "alerting:apm.transaction_duration/alerts/rule/unmuteAll", + "alerting:apm.transaction_duration/alerts/rule/muteAlert", + "alerting:apm.transaction_duration/alerts/rule/unmuteAlert", + "alerting:apm.transaction_duration/alerts/rule/snooze", + "alerting:apm.transaction_duration/alerts/rule/bulkEdit", + "alerting:apm.transaction_duration/alerts/rule/bulkDelete", + "alerting:apm.transaction_duration/alerts/rule/bulkEnable", + "alerting:apm.transaction_duration/alerts/rule/bulkDisable", + "alerting:apm.transaction_duration/alerts/rule/unsnooze", + "alerting:apm.transaction_duration/alerts/rule/runSoon", + "alerting:apm.transaction_duration/alerts/rule/scheduleBackfill", + "alerting:apm.transaction_duration/alerts/rule/deleteBackfill", "alerting:apm.anomaly/observability/rule/get", "alerting:apm.anomaly/observability/rule/getRuleState", "alerting:apm.anomaly/observability/rule/getAlertSummary", @@ -9963,6 +19714,34 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.anomaly/observability/rule/runSoon", "alerting:apm.anomaly/observability/rule/scheduleBackfill", "alerting:apm.anomaly/observability/rule/deleteBackfill", + "alerting:apm.anomaly/alerts/rule/get", + "alerting:apm.anomaly/alerts/rule/getRuleState", + "alerting:apm.anomaly/alerts/rule/getAlertSummary", + "alerting:apm.anomaly/alerts/rule/getExecutionLog", + "alerting:apm.anomaly/alerts/rule/getActionErrorLog", + "alerting:apm.anomaly/alerts/rule/find", + "alerting:apm.anomaly/alerts/rule/getRuleExecutionKPI", + "alerting:apm.anomaly/alerts/rule/getBackfill", + "alerting:apm.anomaly/alerts/rule/findBackfill", + "alerting:apm.anomaly/alerts/rule/create", + "alerting:apm.anomaly/alerts/rule/delete", + "alerting:apm.anomaly/alerts/rule/update", + "alerting:apm.anomaly/alerts/rule/updateApiKey", + "alerting:apm.anomaly/alerts/rule/enable", + "alerting:apm.anomaly/alerts/rule/disable", + "alerting:apm.anomaly/alerts/rule/muteAll", + "alerting:apm.anomaly/alerts/rule/unmuteAll", + "alerting:apm.anomaly/alerts/rule/muteAlert", + "alerting:apm.anomaly/alerts/rule/unmuteAlert", + "alerting:apm.anomaly/alerts/rule/snooze", + "alerting:apm.anomaly/alerts/rule/bulkEdit", + "alerting:apm.anomaly/alerts/rule/bulkDelete", + "alerting:apm.anomaly/alerts/rule/bulkEnable", + "alerting:apm.anomaly/alerts/rule/bulkDisable", + "alerting:apm.anomaly/alerts/rule/unsnooze", + "alerting:apm.anomaly/alerts/rule/runSoon", + "alerting:apm.anomaly/alerts/rule/scheduleBackfill", + "alerting:apm.anomaly/alerts/rule/deleteBackfill", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/get", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/getRuleState", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/getAlertSummary", @@ -10014,56 +19793,555 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.synthetics.alerts.tls/observability/rule/bulkEdit", "alerting:xpack.synthetics.alerts.tls/observability/rule/bulkDelete", "alerting:xpack.synthetics.alerts.tls/observability/rule/bulkEnable", - "alerting:xpack.synthetics.alerts.tls/observability/rule/bulkDisable", - "alerting:xpack.synthetics.alerts.tls/observability/rule/unsnooze", - "alerting:xpack.synthetics.alerts.tls/observability/rule/runSoon", - "alerting:xpack.synthetics.alerts.tls/observability/rule/scheduleBackfill", - "alerting:xpack.synthetics.alerts.tls/observability/rule/deleteBackfill", - "alerting:slo.rules.burnRate/observability/alert/get", - "alerting:slo.rules.burnRate/observability/alert/find", - "alerting:slo.rules.burnRate/observability/alert/getAuthorizedAlertsIndices", - "alerting:slo.rules.burnRate/observability/alert/getAlertSummary", - "alerting:slo.rules.burnRate/observability/alert/update", - "alerting:observability.rules.custom_threshold/observability/alert/get", - "alerting:observability.rules.custom_threshold/observability/alert/find", - "alerting:observability.rules.custom_threshold/observability/alert/getAuthorizedAlertsIndices", - "alerting:observability.rules.custom_threshold/observability/alert/getAlertSummary", - "alerting:observability.rules.custom_threshold/observability/alert/update", - "alerting:.es-query/observability/alert/get", - "alerting:.es-query/observability/alert/find", - "alerting:.es-query/observability/alert/getAuthorizedAlertsIndices", - "alerting:.es-query/observability/alert/getAlertSummary", - "alerting:.es-query/observability/alert/update", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/get", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/find", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAuthorizedAlertsIndices", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAlertSummary", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/update", - "alerting:metrics.alert.inventory.threshold/observability/alert/get", - "alerting:metrics.alert.inventory.threshold/observability/alert/find", - "alerting:metrics.alert.inventory.threshold/observability/alert/getAuthorizedAlertsIndices", - "alerting:metrics.alert.inventory.threshold/observability/alert/getAlertSummary", - "alerting:metrics.alert.inventory.threshold/observability/alert/update", + "alerting:xpack.synthetics.alerts.tls/observability/rule/bulkDisable", + "alerting:xpack.synthetics.alerts.tls/observability/rule/unsnooze", + "alerting:xpack.synthetics.alerts.tls/observability/rule/runSoon", + "alerting:xpack.synthetics.alerts.tls/observability/rule/scheduleBackfill", + "alerting:xpack.synthetics.alerts.tls/observability/rule/deleteBackfill", + "alerting:metrics.alert.threshold/observability/rule/get", + "alerting:metrics.alert.threshold/observability/rule/getRuleState", + "alerting:metrics.alert.threshold/observability/rule/getAlertSummary", + "alerting:metrics.alert.threshold/observability/rule/getExecutionLog", + "alerting:metrics.alert.threshold/observability/rule/getActionErrorLog", + "alerting:metrics.alert.threshold/observability/rule/find", + "alerting:metrics.alert.threshold/observability/rule/getRuleExecutionKPI", + "alerting:metrics.alert.threshold/observability/rule/getBackfill", + "alerting:metrics.alert.threshold/observability/rule/findBackfill", + "alerting:metrics.alert.threshold/observability/rule/create", + "alerting:metrics.alert.threshold/observability/rule/delete", + "alerting:metrics.alert.threshold/observability/rule/update", + "alerting:metrics.alert.threshold/observability/rule/updateApiKey", + "alerting:metrics.alert.threshold/observability/rule/enable", + "alerting:metrics.alert.threshold/observability/rule/disable", + "alerting:metrics.alert.threshold/observability/rule/muteAll", + "alerting:metrics.alert.threshold/observability/rule/unmuteAll", + "alerting:metrics.alert.threshold/observability/rule/muteAlert", + "alerting:metrics.alert.threshold/observability/rule/unmuteAlert", + "alerting:metrics.alert.threshold/observability/rule/snooze", + "alerting:metrics.alert.threshold/observability/rule/bulkEdit", + "alerting:metrics.alert.threshold/observability/rule/bulkDelete", + "alerting:metrics.alert.threshold/observability/rule/bulkEnable", + "alerting:metrics.alert.threshold/observability/rule/bulkDisable", + "alerting:metrics.alert.threshold/observability/rule/unsnooze", + "alerting:metrics.alert.threshold/observability/rule/runSoon", + "alerting:metrics.alert.threshold/observability/rule/scheduleBackfill", + "alerting:metrics.alert.threshold/observability/rule/deleteBackfill", + "alerting:metrics.alert.threshold/alerts/rule/get", + "alerting:metrics.alert.threshold/alerts/rule/getRuleState", + "alerting:metrics.alert.threshold/alerts/rule/getAlertSummary", + "alerting:metrics.alert.threshold/alerts/rule/getExecutionLog", + "alerting:metrics.alert.threshold/alerts/rule/getActionErrorLog", + "alerting:metrics.alert.threshold/alerts/rule/find", + "alerting:metrics.alert.threshold/alerts/rule/getRuleExecutionKPI", + "alerting:metrics.alert.threshold/alerts/rule/getBackfill", + "alerting:metrics.alert.threshold/alerts/rule/findBackfill", + "alerting:metrics.alert.threshold/alerts/rule/create", + "alerting:metrics.alert.threshold/alerts/rule/delete", + "alerting:metrics.alert.threshold/alerts/rule/update", + "alerting:metrics.alert.threshold/alerts/rule/updateApiKey", + "alerting:metrics.alert.threshold/alerts/rule/enable", + "alerting:metrics.alert.threshold/alerts/rule/disable", + "alerting:metrics.alert.threshold/alerts/rule/muteAll", + "alerting:metrics.alert.threshold/alerts/rule/unmuteAll", + "alerting:metrics.alert.threshold/alerts/rule/muteAlert", + "alerting:metrics.alert.threshold/alerts/rule/unmuteAlert", + "alerting:metrics.alert.threshold/alerts/rule/snooze", + "alerting:metrics.alert.threshold/alerts/rule/bulkEdit", + "alerting:metrics.alert.threshold/alerts/rule/bulkDelete", + "alerting:metrics.alert.threshold/alerts/rule/bulkEnable", + "alerting:metrics.alert.threshold/alerts/rule/bulkDisable", + "alerting:metrics.alert.threshold/alerts/rule/unsnooze", + "alerting:metrics.alert.threshold/alerts/rule/runSoon", + "alerting:metrics.alert.threshold/alerts/rule/scheduleBackfill", + "alerting:metrics.alert.threshold/alerts/rule/deleteBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/get", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleState", + "alerting:metrics.alert.inventory.threshold/observability/rule/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/rule/getExecutionLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/getActionErrorLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/find", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleExecutionKPI", + "alerting:metrics.alert.inventory.threshold/observability/rule/getBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/findBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/create", + "alerting:metrics.alert.inventory.threshold/observability/rule/delete", + "alerting:metrics.alert.inventory.threshold/observability/rule/update", + "alerting:metrics.alert.inventory.threshold/observability/rule/updateApiKey", + "alerting:metrics.alert.inventory.threshold/observability/rule/enable", + "alerting:metrics.alert.inventory.threshold/observability/rule/disable", + "alerting:metrics.alert.inventory.threshold/observability/rule/muteAll", + "alerting:metrics.alert.inventory.threshold/observability/rule/unmuteAll", + "alerting:metrics.alert.inventory.threshold/observability/rule/muteAlert", + "alerting:metrics.alert.inventory.threshold/observability/rule/unmuteAlert", + "alerting:metrics.alert.inventory.threshold/observability/rule/snooze", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkEdit", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkDelete", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkEnable", + "alerting:metrics.alert.inventory.threshold/observability/rule/bulkDisable", + "alerting:metrics.alert.inventory.threshold/observability/rule/unsnooze", + "alerting:metrics.alert.inventory.threshold/observability/rule/runSoon", + "alerting:metrics.alert.inventory.threshold/observability/rule/scheduleBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/deleteBackfill", + "alerting:metrics.alert.inventory.threshold/alerts/rule/get", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getRuleState", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getExecutionLog", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getActionErrorLog", + "alerting:metrics.alert.inventory.threshold/alerts/rule/find", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getRuleExecutionKPI", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getBackfill", + "alerting:metrics.alert.inventory.threshold/alerts/rule/findBackfill", + "alerting:metrics.alert.inventory.threshold/alerts/rule/create", + "alerting:metrics.alert.inventory.threshold/alerts/rule/delete", + "alerting:metrics.alert.inventory.threshold/alerts/rule/update", + "alerting:metrics.alert.inventory.threshold/alerts/rule/updateApiKey", + "alerting:metrics.alert.inventory.threshold/alerts/rule/enable", + "alerting:metrics.alert.inventory.threshold/alerts/rule/disable", + "alerting:metrics.alert.inventory.threshold/alerts/rule/muteAll", + "alerting:metrics.alert.inventory.threshold/alerts/rule/unmuteAll", + "alerting:metrics.alert.inventory.threshold/alerts/rule/muteAlert", + "alerting:metrics.alert.inventory.threshold/alerts/rule/unmuteAlert", + "alerting:metrics.alert.inventory.threshold/alerts/rule/snooze", + "alerting:metrics.alert.inventory.threshold/alerts/rule/bulkEdit", + "alerting:metrics.alert.inventory.threshold/alerts/rule/bulkDelete", + "alerting:metrics.alert.inventory.threshold/alerts/rule/bulkEnable", + "alerting:metrics.alert.inventory.threshold/alerts/rule/bulkDisable", + "alerting:metrics.alert.inventory.threshold/alerts/rule/unsnooze", + "alerting:metrics.alert.inventory.threshold/alerts/rule/runSoon", + "alerting:metrics.alert.inventory.threshold/alerts/rule/scheduleBackfill", + "alerting:metrics.alert.inventory.threshold/alerts/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.tls/observability/rule/get", + "alerting:xpack.uptime.alerts.tls/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.tls/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tls/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tls/observability/rule/find", + "alerting:xpack.uptime.alerts.tls/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tls/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.tls/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.tls/observability/rule/create", + "alerting:xpack.uptime.alerts.tls/observability/rule/delete", + "alerting:xpack.uptime.alerts.tls/observability/rule/update", + "alerting:xpack.uptime.alerts.tls/observability/rule/updateApiKey", + "alerting:xpack.uptime.alerts.tls/observability/rule/enable", + "alerting:xpack.uptime.alerts.tls/observability/rule/disable", + "alerting:xpack.uptime.alerts.tls/observability/rule/muteAll", + "alerting:xpack.uptime.alerts.tls/observability/rule/unmuteAll", + "alerting:xpack.uptime.alerts.tls/observability/rule/muteAlert", + "alerting:xpack.uptime.alerts.tls/observability/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.tls/observability/rule/snooze", + "alerting:xpack.uptime.alerts.tls/observability/rule/bulkEdit", + "alerting:xpack.uptime.alerts.tls/observability/rule/bulkDelete", + "alerting:xpack.uptime.alerts.tls/observability/rule/bulkEnable", + "alerting:xpack.uptime.alerts.tls/observability/rule/bulkDisable", + "alerting:xpack.uptime.alerts.tls/observability/rule/unsnooze", + "alerting:xpack.uptime.alerts.tls/observability/rule/runSoon", + "alerting:xpack.uptime.alerts.tls/observability/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.tls/observability/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/get", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/find", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/create", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/delete", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/update", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/updateApiKey", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/enable", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/disable", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/muteAll", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/unmuteAll", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/muteAlert", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/snooze", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/bulkEdit", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/bulkDelete", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/bulkEnable", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/bulkDisable", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/unsnooze", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/runSoon", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/get", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/find", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/create", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/delete", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/update", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/updateApiKey", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/enable", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/disable", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/muteAll", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/unmuteAll", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/muteAlert", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/snooze", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/bulkEdit", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/bulkDelete", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/bulkEnable", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/bulkDisable", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/unsnooze", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/runSoon", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/deleteBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/get", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/find", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/create", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/delete", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/update", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/updateApiKey", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/enable", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/disable", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/muteAll", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/unmuteAll", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/muteAlert", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/unmuteAlert", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/snooze", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/bulkEdit", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/bulkDelete", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/bulkEnable", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/bulkDisable", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/unsnooze", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/runSoon", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/scheduleBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/deleteBackfill", + "alerting:logs.alert.document.count/observability/rule/get", + "alerting:logs.alert.document.count/observability/rule/getRuleState", + "alerting:logs.alert.document.count/observability/rule/getAlertSummary", + "alerting:logs.alert.document.count/observability/rule/getExecutionLog", + "alerting:logs.alert.document.count/observability/rule/getActionErrorLog", + "alerting:logs.alert.document.count/observability/rule/find", + "alerting:logs.alert.document.count/observability/rule/getRuleExecutionKPI", + "alerting:logs.alert.document.count/observability/rule/getBackfill", + "alerting:logs.alert.document.count/observability/rule/findBackfill", + "alerting:logs.alert.document.count/observability/rule/create", + "alerting:logs.alert.document.count/observability/rule/delete", + "alerting:logs.alert.document.count/observability/rule/update", + "alerting:logs.alert.document.count/observability/rule/updateApiKey", + "alerting:logs.alert.document.count/observability/rule/enable", + "alerting:logs.alert.document.count/observability/rule/disable", + "alerting:logs.alert.document.count/observability/rule/muteAll", + "alerting:logs.alert.document.count/observability/rule/unmuteAll", + "alerting:logs.alert.document.count/observability/rule/muteAlert", + "alerting:logs.alert.document.count/observability/rule/unmuteAlert", + "alerting:logs.alert.document.count/observability/rule/snooze", + "alerting:logs.alert.document.count/observability/rule/bulkEdit", + "alerting:logs.alert.document.count/observability/rule/bulkDelete", + "alerting:logs.alert.document.count/observability/rule/bulkEnable", + "alerting:logs.alert.document.count/observability/rule/bulkDisable", + "alerting:logs.alert.document.count/observability/rule/unsnooze", + "alerting:logs.alert.document.count/observability/rule/runSoon", + "alerting:logs.alert.document.count/observability/rule/scheduleBackfill", + "alerting:logs.alert.document.count/observability/rule/deleteBackfill", + "alerting:logs.alert.document.count/alerts/rule/get", + "alerting:logs.alert.document.count/alerts/rule/getRuleState", + "alerting:logs.alert.document.count/alerts/rule/getAlertSummary", + "alerting:logs.alert.document.count/alerts/rule/getExecutionLog", + "alerting:logs.alert.document.count/alerts/rule/getActionErrorLog", + "alerting:logs.alert.document.count/alerts/rule/find", + "alerting:logs.alert.document.count/alerts/rule/getRuleExecutionKPI", + "alerting:logs.alert.document.count/alerts/rule/getBackfill", + "alerting:logs.alert.document.count/alerts/rule/findBackfill", + "alerting:logs.alert.document.count/alerts/rule/create", + "alerting:logs.alert.document.count/alerts/rule/delete", + "alerting:logs.alert.document.count/alerts/rule/update", + "alerting:logs.alert.document.count/alerts/rule/updateApiKey", + "alerting:logs.alert.document.count/alerts/rule/enable", + "alerting:logs.alert.document.count/alerts/rule/disable", + "alerting:logs.alert.document.count/alerts/rule/muteAll", + "alerting:logs.alert.document.count/alerts/rule/unmuteAll", + "alerting:logs.alert.document.count/alerts/rule/muteAlert", + "alerting:logs.alert.document.count/alerts/rule/unmuteAlert", + "alerting:logs.alert.document.count/alerts/rule/snooze", + "alerting:logs.alert.document.count/alerts/rule/bulkEdit", + "alerting:logs.alert.document.count/alerts/rule/bulkDelete", + "alerting:logs.alert.document.count/alerts/rule/bulkEnable", + "alerting:logs.alert.document.count/alerts/rule/bulkDisable", + "alerting:logs.alert.document.count/alerts/rule/unsnooze", + "alerting:logs.alert.document.count/alerts/rule/runSoon", + "alerting:logs.alert.document.count/alerts/rule/scheduleBackfill", + "alerting:logs.alert.document.count/alerts/rule/deleteBackfill", + "alerting:slo.rules.burnRate/observability/rule/get", + "alerting:slo.rules.burnRate/observability/rule/getRuleState", + "alerting:slo.rules.burnRate/observability/rule/getAlertSummary", + "alerting:slo.rules.burnRate/observability/rule/getExecutionLog", + "alerting:slo.rules.burnRate/observability/rule/getActionErrorLog", + "alerting:slo.rules.burnRate/observability/rule/find", + "alerting:slo.rules.burnRate/observability/rule/getRuleExecutionKPI", + "alerting:slo.rules.burnRate/observability/rule/getBackfill", + "alerting:slo.rules.burnRate/observability/rule/findBackfill", + "alerting:slo.rules.burnRate/observability/rule/create", + "alerting:slo.rules.burnRate/observability/rule/delete", + "alerting:slo.rules.burnRate/observability/rule/update", + "alerting:slo.rules.burnRate/observability/rule/updateApiKey", + "alerting:slo.rules.burnRate/observability/rule/enable", + "alerting:slo.rules.burnRate/observability/rule/disable", + "alerting:slo.rules.burnRate/observability/rule/muteAll", + "alerting:slo.rules.burnRate/observability/rule/unmuteAll", + "alerting:slo.rules.burnRate/observability/rule/muteAlert", + "alerting:slo.rules.burnRate/observability/rule/unmuteAlert", + "alerting:slo.rules.burnRate/observability/rule/snooze", + "alerting:slo.rules.burnRate/observability/rule/bulkEdit", + "alerting:slo.rules.burnRate/observability/rule/bulkDelete", + "alerting:slo.rules.burnRate/observability/rule/bulkEnable", + "alerting:slo.rules.burnRate/observability/rule/bulkDisable", + "alerting:slo.rules.burnRate/observability/rule/unsnooze", + "alerting:slo.rules.burnRate/observability/rule/runSoon", + "alerting:slo.rules.burnRate/observability/rule/scheduleBackfill", + "alerting:slo.rules.burnRate/observability/rule/deleteBackfill", + "alerting:slo.rules.burnRate/alerts/rule/get", + "alerting:slo.rules.burnRate/alerts/rule/getRuleState", + "alerting:slo.rules.burnRate/alerts/rule/getAlertSummary", + "alerting:slo.rules.burnRate/alerts/rule/getExecutionLog", + "alerting:slo.rules.burnRate/alerts/rule/getActionErrorLog", + "alerting:slo.rules.burnRate/alerts/rule/find", + "alerting:slo.rules.burnRate/alerts/rule/getRuleExecutionKPI", + "alerting:slo.rules.burnRate/alerts/rule/getBackfill", + "alerting:slo.rules.burnRate/alerts/rule/findBackfill", + "alerting:slo.rules.burnRate/alerts/rule/create", + "alerting:slo.rules.burnRate/alerts/rule/delete", + "alerting:slo.rules.burnRate/alerts/rule/update", + "alerting:slo.rules.burnRate/alerts/rule/updateApiKey", + "alerting:slo.rules.burnRate/alerts/rule/enable", + "alerting:slo.rules.burnRate/alerts/rule/disable", + "alerting:slo.rules.burnRate/alerts/rule/muteAll", + "alerting:slo.rules.burnRate/alerts/rule/unmuteAll", + "alerting:slo.rules.burnRate/alerts/rule/muteAlert", + "alerting:slo.rules.burnRate/alerts/rule/unmuteAlert", + "alerting:slo.rules.burnRate/alerts/rule/snooze", + "alerting:slo.rules.burnRate/alerts/rule/bulkEdit", + "alerting:slo.rules.burnRate/alerts/rule/bulkDelete", + "alerting:slo.rules.burnRate/alerts/rule/bulkEnable", + "alerting:slo.rules.burnRate/alerts/rule/bulkDisable", + "alerting:slo.rules.burnRate/alerts/rule/unsnooze", + "alerting:slo.rules.burnRate/alerts/rule/runSoon", + "alerting:slo.rules.burnRate/alerts/rule/scheduleBackfill", + "alerting:slo.rules.burnRate/alerts/rule/deleteBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/get", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleState", + "alerting:observability.rules.custom_threshold/observability/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/observability/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/observability/rule/find", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/observability/rule/getBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/findBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/create", + "alerting:observability.rules.custom_threshold/observability/rule/delete", + "alerting:observability.rules.custom_threshold/observability/rule/update", + "alerting:observability.rules.custom_threshold/observability/rule/updateApiKey", + "alerting:observability.rules.custom_threshold/observability/rule/enable", + "alerting:observability.rules.custom_threshold/observability/rule/disable", + "alerting:observability.rules.custom_threshold/observability/rule/muteAll", + "alerting:observability.rules.custom_threshold/observability/rule/unmuteAll", + "alerting:observability.rules.custom_threshold/observability/rule/muteAlert", + "alerting:observability.rules.custom_threshold/observability/rule/unmuteAlert", + "alerting:observability.rules.custom_threshold/observability/rule/snooze", + "alerting:observability.rules.custom_threshold/observability/rule/bulkEdit", + "alerting:observability.rules.custom_threshold/observability/rule/bulkDelete", + "alerting:observability.rules.custom_threshold/observability/rule/bulkEnable", + "alerting:observability.rules.custom_threshold/observability/rule/bulkDisable", + "alerting:observability.rules.custom_threshold/observability/rule/unsnooze", + "alerting:observability.rules.custom_threshold/observability/rule/runSoon", + "alerting:observability.rules.custom_threshold/observability/rule/scheduleBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/deleteBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/get", + "alerting:observability.rules.custom_threshold/alerts/rule/getRuleState", + "alerting:observability.rules.custom_threshold/alerts/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/alerts/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/alerts/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/alerts/rule/find", + "alerting:observability.rules.custom_threshold/alerts/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/alerts/rule/getBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/findBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/create", + "alerting:observability.rules.custom_threshold/alerts/rule/delete", + "alerting:observability.rules.custom_threshold/alerts/rule/update", + "alerting:observability.rules.custom_threshold/alerts/rule/updateApiKey", + "alerting:observability.rules.custom_threshold/alerts/rule/enable", + "alerting:observability.rules.custom_threshold/alerts/rule/disable", + "alerting:observability.rules.custom_threshold/alerts/rule/muteAll", + "alerting:observability.rules.custom_threshold/alerts/rule/unmuteAll", + "alerting:observability.rules.custom_threshold/alerts/rule/muteAlert", + "alerting:observability.rules.custom_threshold/alerts/rule/unmuteAlert", + "alerting:observability.rules.custom_threshold/alerts/rule/snooze", + "alerting:observability.rules.custom_threshold/alerts/rule/bulkEdit", + "alerting:observability.rules.custom_threshold/alerts/rule/bulkDelete", + "alerting:observability.rules.custom_threshold/alerts/rule/bulkEnable", + "alerting:observability.rules.custom_threshold/alerts/rule/bulkDisable", + "alerting:observability.rules.custom_threshold/alerts/rule/unsnooze", + "alerting:observability.rules.custom_threshold/alerts/rule/runSoon", + "alerting:observability.rules.custom_threshold/alerts/rule/scheduleBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/deleteBackfill", + "alerting:.es-query/observability/rule/get", + "alerting:.es-query/observability/rule/getRuleState", + "alerting:.es-query/observability/rule/getAlertSummary", + "alerting:.es-query/observability/rule/getExecutionLog", + "alerting:.es-query/observability/rule/getActionErrorLog", + "alerting:.es-query/observability/rule/find", + "alerting:.es-query/observability/rule/getRuleExecutionKPI", + "alerting:.es-query/observability/rule/getBackfill", + "alerting:.es-query/observability/rule/findBackfill", + "alerting:.es-query/observability/rule/create", + "alerting:.es-query/observability/rule/delete", + "alerting:.es-query/observability/rule/update", + "alerting:.es-query/observability/rule/updateApiKey", + "alerting:.es-query/observability/rule/enable", + "alerting:.es-query/observability/rule/disable", + "alerting:.es-query/observability/rule/muteAll", + "alerting:.es-query/observability/rule/unmuteAll", + "alerting:.es-query/observability/rule/muteAlert", + "alerting:.es-query/observability/rule/unmuteAlert", + "alerting:.es-query/observability/rule/snooze", + "alerting:.es-query/observability/rule/bulkEdit", + "alerting:.es-query/observability/rule/bulkDelete", + "alerting:.es-query/observability/rule/bulkEnable", + "alerting:.es-query/observability/rule/bulkDisable", + "alerting:.es-query/observability/rule/unsnooze", + "alerting:.es-query/observability/rule/runSoon", + "alerting:.es-query/observability/rule/scheduleBackfill", + "alerting:.es-query/observability/rule/deleteBackfill", + "alerting:.es-query/alerts/rule/get", + "alerting:.es-query/alerts/rule/getRuleState", + "alerting:.es-query/alerts/rule/getAlertSummary", + "alerting:.es-query/alerts/rule/getExecutionLog", + "alerting:.es-query/alerts/rule/getActionErrorLog", + "alerting:.es-query/alerts/rule/find", + "alerting:.es-query/alerts/rule/getRuleExecutionKPI", + "alerting:.es-query/alerts/rule/getBackfill", + "alerting:.es-query/alerts/rule/findBackfill", + "alerting:.es-query/alerts/rule/create", + "alerting:.es-query/alerts/rule/delete", + "alerting:.es-query/alerts/rule/update", + "alerting:.es-query/alerts/rule/updateApiKey", + "alerting:.es-query/alerts/rule/enable", + "alerting:.es-query/alerts/rule/disable", + "alerting:.es-query/alerts/rule/muteAll", + "alerting:.es-query/alerts/rule/unmuteAll", + "alerting:.es-query/alerts/rule/muteAlert", + "alerting:.es-query/alerts/rule/unmuteAlert", + "alerting:.es-query/alerts/rule/snooze", + "alerting:.es-query/alerts/rule/bulkEdit", + "alerting:.es-query/alerts/rule/bulkDelete", + "alerting:.es-query/alerts/rule/bulkEnable", + "alerting:.es-query/alerts/rule/bulkDisable", + "alerting:.es-query/alerts/rule/unsnooze", + "alerting:.es-query/alerts/rule/runSoon", + "alerting:.es-query/alerts/rule/scheduleBackfill", + "alerting:.es-query/alerts/rule/deleteBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/create", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/delete", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/update", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/updateApiKey", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/enable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/disable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/muteAll", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unmuteAll", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/muteAlert", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unmuteAlert", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/snooze", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkEdit", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkDelete", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkEnable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/bulkDisable", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/unsnooze", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/runSoon", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/scheduleBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/deleteBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/create", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/delete", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/update", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/updateApiKey", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/enable", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/disable", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/muteAll", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/unmuteAll", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/muteAlert", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/unmuteAlert", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/snooze", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/bulkEdit", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/bulkDelete", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/bulkEnable", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/bulkDisable", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/unsnooze", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/runSoon", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/scheduleBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/deleteBackfill", "alerting:apm.error_rate/observability/alert/get", "alerting:apm.error_rate/observability/alert/find", "alerting:apm.error_rate/observability/alert/getAuthorizedAlertsIndices", "alerting:apm.error_rate/observability/alert/getAlertSummary", "alerting:apm.error_rate/observability/alert/update", + "alerting:apm.error_rate/alerts/alert/get", + "alerting:apm.error_rate/alerts/alert/find", + "alerting:apm.error_rate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.error_rate/alerts/alert/getAlertSummary", + "alerting:apm.error_rate/alerts/alert/update", "alerting:apm.transaction_error_rate/observability/alert/get", "alerting:apm.transaction_error_rate/observability/alert/find", "alerting:apm.transaction_error_rate/observability/alert/getAuthorizedAlertsIndices", "alerting:apm.transaction_error_rate/observability/alert/getAlertSummary", "alerting:apm.transaction_error_rate/observability/alert/update", + "alerting:apm.transaction_error_rate/alerts/alert/get", + "alerting:apm.transaction_error_rate/alerts/alert/find", + "alerting:apm.transaction_error_rate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_error_rate/alerts/alert/getAlertSummary", + "alerting:apm.transaction_error_rate/alerts/alert/update", "alerting:apm.transaction_duration/observability/alert/get", "alerting:apm.transaction_duration/observability/alert/find", "alerting:apm.transaction_duration/observability/alert/getAuthorizedAlertsIndices", "alerting:apm.transaction_duration/observability/alert/getAlertSummary", "alerting:apm.transaction_duration/observability/alert/update", + "alerting:apm.transaction_duration/alerts/alert/get", + "alerting:apm.transaction_duration/alerts/alert/find", + "alerting:apm.transaction_duration/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_duration/alerts/alert/getAlertSummary", + "alerting:apm.transaction_duration/alerts/alert/update", "alerting:apm.anomaly/observability/alert/get", "alerting:apm.anomaly/observability/alert/find", "alerting:apm.anomaly/observability/alert/getAuthorizedAlertsIndices", "alerting:apm.anomaly/observability/alert/getAlertSummary", "alerting:apm.anomaly/observability/alert/update", + "alerting:apm.anomaly/alerts/alert/get", + "alerting:apm.anomaly/alerts/alert/find", + "alerting:apm.anomaly/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.anomaly/alerts/alert/getAlertSummary", + "alerting:apm.anomaly/alerts/alert/update", "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/get", "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/find", "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/getAuthorizedAlertsIndices", @@ -10074,6 +20352,96 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.synthetics.alerts.tls/observability/alert/getAuthorizedAlertsIndices", "alerting:xpack.synthetics.alerts.tls/observability/alert/getAlertSummary", "alerting:xpack.synthetics.alerts.tls/observability/alert/update", + "alerting:metrics.alert.threshold/observability/alert/get", + "alerting:metrics.alert.threshold/observability/alert/find", + "alerting:metrics.alert.threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.threshold/observability/alert/getAlertSummary", + "alerting:metrics.alert.threshold/observability/alert/update", + "alerting:metrics.alert.threshold/alerts/alert/get", + "alerting:metrics.alert.threshold/alerts/alert/find", + "alerting:metrics.alert.threshold/alerts/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.threshold/alerts/alert/getAlertSummary", + "alerting:metrics.alert.threshold/alerts/alert/update", + "alerting:metrics.alert.inventory.threshold/observability/alert/get", + "alerting:metrics.alert.inventory.threshold/observability/alert/find", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/alert/update", + "alerting:metrics.alert.inventory.threshold/alerts/alert/get", + "alerting:metrics.alert.inventory.threshold/alerts/alert/find", + "alerting:metrics.alert.inventory.threshold/alerts/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.inventory.threshold/alerts/alert/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/alerts/alert/update", + "alerting:xpack.uptime.alerts.tls/observability/alert/get", + "alerting:xpack.uptime.alerts.tls/observability/alert/find", + "alerting:xpack.uptime.alerts.tls/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tls/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/observability/alert/update", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/get", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/find", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/update", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/get", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/find", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/update", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/get", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/find", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/update", + "alerting:logs.alert.document.count/observability/alert/get", + "alerting:logs.alert.document.count/observability/alert/find", + "alerting:logs.alert.document.count/observability/alert/getAuthorizedAlertsIndices", + "alerting:logs.alert.document.count/observability/alert/getAlertSummary", + "alerting:logs.alert.document.count/observability/alert/update", + "alerting:logs.alert.document.count/alerts/alert/get", + "alerting:logs.alert.document.count/alerts/alert/find", + "alerting:logs.alert.document.count/alerts/alert/getAuthorizedAlertsIndices", + "alerting:logs.alert.document.count/alerts/alert/getAlertSummary", + "alerting:logs.alert.document.count/alerts/alert/update", + "alerting:slo.rules.burnRate/observability/alert/get", + "alerting:slo.rules.burnRate/observability/alert/find", + "alerting:slo.rules.burnRate/observability/alert/getAuthorizedAlertsIndices", + "alerting:slo.rules.burnRate/observability/alert/getAlertSummary", + "alerting:slo.rules.burnRate/observability/alert/update", + "alerting:slo.rules.burnRate/alerts/alert/get", + "alerting:slo.rules.burnRate/alerts/alert/find", + "alerting:slo.rules.burnRate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:slo.rules.burnRate/alerts/alert/getAlertSummary", + "alerting:slo.rules.burnRate/alerts/alert/update", + "alerting:observability.rules.custom_threshold/observability/alert/get", + "alerting:observability.rules.custom_threshold/observability/alert/find", + "alerting:observability.rules.custom_threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/observability/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/alert/update", + "alerting:observability.rules.custom_threshold/alerts/alert/get", + "alerting:observability.rules.custom_threshold/alerts/alert/find", + "alerting:observability.rules.custom_threshold/alerts/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/alerts/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/alerts/alert/update", + "alerting:.es-query/observability/alert/get", + "alerting:.es-query/observability/alert/find", + "alerting:.es-query/observability/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/observability/alert/getAlertSummary", + "alerting:.es-query/observability/alert/update", + "alerting:.es-query/alerts/alert/get", + "alerting:.es-query/alerts/alert/find", + "alerting:.es-query/alerts/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/alerts/alert/getAlertSummary", + "alerting:.es-query/alerts/alert/update", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/update", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/update", ], "minimal_read": Array [ "login:", @@ -10154,6 +20522,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.uptime.alerts.tls/uptime/rule/getRuleExecutionKPI", "alerting:xpack.uptime.alerts.tls/uptime/rule/getBackfill", "alerting:xpack.uptime.alerts.tls/uptime/rule/findBackfill", + "alerting:xpack.uptime.alerts.tls/alerts/rule/get", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tls/alerts/rule/find", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.tls/alerts/rule/findBackfill", "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/get", "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/getRuleState", "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/getAlertSummary", @@ -10163,6 +20540,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/getRuleExecutionKPI", "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/getBackfill", "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/findBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/get", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/find", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/findBackfill", "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/get", "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/getRuleState", "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/getAlertSummary", @@ -10172,6 +20558,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/getRuleExecutionKPI", "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/getBackfill", "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/findBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/get", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/find", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/findBackfill", "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/get", "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/getRuleState", "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/getAlertSummary", @@ -10181,97 +20576,103 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/getRuleExecutionKPI", "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/getBackfill", "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/findBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/get", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/find", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/findBackfill", "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/get", "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/getRuleState", "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/getAlertSummary", "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/getExecutionLog", "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/getActionErrorLog", - "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/find", - "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/getRuleExecutionKPI", - "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/getBackfill", - "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/findBackfill", - "alerting:xpack.synthetics.alerts.tls/uptime/rule/get", - "alerting:xpack.synthetics.alerts.tls/uptime/rule/getRuleState", - "alerting:xpack.synthetics.alerts.tls/uptime/rule/getAlertSummary", - "alerting:xpack.synthetics.alerts.tls/uptime/rule/getExecutionLog", - "alerting:xpack.synthetics.alerts.tls/uptime/rule/getActionErrorLog", - "alerting:xpack.synthetics.alerts.tls/uptime/rule/find", - "alerting:xpack.synthetics.alerts.tls/uptime/rule/getRuleExecutionKPI", - "alerting:xpack.synthetics.alerts.tls/uptime/rule/getBackfill", - "alerting:xpack.synthetics.alerts.tls/uptime/rule/findBackfill", - "alerting:xpack.uptime.alerts.tls/uptime/alert/get", - "alerting:xpack.uptime.alerts.tls/uptime/alert/find", - "alerting:xpack.uptime.alerts.tls/uptime/alert/getAuthorizedAlertsIndices", - "alerting:xpack.uptime.alerts.tls/uptime/alert/getAlertSummary", - "alerting:xpack.uptime.alerts.tlsCertificate/uptime/alert/get", - "alerting:xpack.uptime.alerts.tlsCertificate/uptime/alert/find", - "alerting:xpack.uptime.alerts.tlsCertificate/uptime/alert/getAuthorizedAlertsIndices", - "alerting:xpack.uptime.alerts.tlsCertificate/uptime/alert/getAlertSummary", - "alerting:xpack.uptime.alerts.monitorStatus/uptime/alert/get", - "alerting:xpack.uptime.alerts.monitorStatus/uptime/alert/find", - "alerting:xpack.uptime.alerts.monitorStatus/uptime/alert/getAuthorizedAlertsIndices", - "alerting:xpack.uptime.alerts.monitorStatus/uptime/alert/getAlertSummary", - "alerting:xpack.uptime.alerts.durationAnomaly/uptime/alert/get", - "alerting:xpack.uptime.alerts.durationAnomaly/uptime/alert/find", - "alerting:xpack.uptime.alerts.durationAnomaly/uptime/alert/getAuthorizedAlertsIndices", - "alerting:xpack.uptime.alerts.durationAnomaly/uptime/alert/getAlertSummary", - "alerting:xpack.synthetics.alerts.monitorStatus/uptime/alert/get", - "alerting:xpack.synthetics.alerts.monitorStatus/uptime/alert/find", - "alerting:xpack.synthetics.alerts.monitorStatus/uptime/alert/getAuthorizedAlertsIndices", - "alerting:xpack.synthetics.alerts.monitorStatus/uptime/alert/getAlertSummary", - "alerting:xpack.synthetics.alerts.tls/uptime/alert/get", - "alerting:xpack.synthetics.alerts.tls/uptime/alert/find", - "alerting:xpack.synthetics.alerts.tls/uptime/alert/getAuthorizedAlertsIndices", - "alerting:xpack.synthetics.alerts.tls/uptime/alert/getAlertSummary", - "app:observability", - "ui:catalogue/observability", - "ui:navLinks/observability", - "ui:observability/read", - "alerting:slo.rules.burnRate/observability/rule/get", - "alerting:slo.rules.burnRate/observability/rule/getRuleState", - "alerting:slo.rules.burnRate/observability/rule/getAlertSummary", - "alerting:slo.rules.burnRate/observability/rule/getExecutionLog", - "alerting:slo.rules.burnRate/observability/rule/getActionErrorLog", - "alerting:slo.rules.burnRate/observability/rule/find", - "alerting:slo.rules.burnRate/observability/rule/getRuleExecutionKPI", - "alerting:slo.rules.burnRate/observability/rule/getBackfill", - "alerting:slo.rules.burnRate/observability/rule/findBackfill", - "alerting:observability.rules.custom_threshold/observability/rule/get", - "alerting:observability.rules.custom_threshold/observability/rule/getRuleState", - "alerting:observability.rules.custom_threshold/observability/rule/getAlertSummary", - "alerting:observability.rules.custom_threshold/observability/rule/getExecutionLog", - "alerting:observability.rules.custom_threshold/observability/rule/getActionErrorLog", - "alerting:observability.rules.custom_threshold/observability/rule/find", - "alerting:observability.rules.custom_threshold/observability/rule/getRuleExecutionKPI", - "alerting:observability.rules.custom_threshold/observability/rule/getBackfill", - "alerting:observability.rules.custom_threshold/observability/rule/findBackfill", - "alerting:.es-query/observability/rule/get", - "alerting:.es-query/observability/rule/getRuleState", - "alerting:.es-query/observability/rule/getAlertSummary", - "alerting:.es-query/observability/rule/getExecutionLog", - "alerting:.es-query/observability/rule/getActionErrorLog", - "alerting:.es-query/observability/rule/find", - "alerting:.es-query/observability/rule/getRuleExecutionKPI", - "alerting:.es-query/observability/rule/getBackfill", - "alerting:.es-query/observability/rule/findBackfill", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/get", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleState", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getAlertSummary", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getExecutionLog", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getActionErrorLog", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/find", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleExecutionKPI", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getBackfill", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/findBackfill", - "alerting:metrics.alert.inventory.threshold/observability/rule/get", - "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleState", - "alerting:metrics.alert.inventory.threshold/observability/rule/getAlertSummary", - "alerting:metrics.alert.inventory.threshold/observability/rule/getExecutionLog", - "alerting:metrics.alert.inventory.threshold/observability/rule/getActionErrorLog", - "alerting:metrics.alert.inventory.threshold/observability/rule/find", - "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleExecutionKPI", - "alerting:metrics.alert.inventory.threshold/observability/rule/getBackfill", - "alerting:metrics.alert.inventory.threshold/observability/rule/findBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/find", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/getRuleExecutionKPI", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/getBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/findBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/get", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getRuleState", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getAlertSummary", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getExecutionLog", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getActionErrorLog", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/find", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/findBackfill", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/get", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/getRuleState", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/getAlertSummary", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/getExecutionLog", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/getActionErrorLog", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/find", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/getRuleExecutionKPI", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/getBackfill", + "alerting:xpack.synthetics.alerts.tls/uptime/rule/findBackfill", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/get", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getRuleState", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getAlertSummary", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getExecutionLog", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getActionErrorLog", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/find", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getBackfill", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.tls/uptime/alert/get", + "alerting:xpack.uptime.alerts.tls/uptime/alert/find", + "alerting:xpack.uptime.alerts.tls/uptime/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tls/uptime/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/alerts/alert/get", + "alerting:xpack.uptime.alerts.tls/alerts/alert/find", + "alerting:xpack.uptime.alerts.tls/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tls/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/alert/get", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/alert/find", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tlsCertificate/uptime/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/get", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/find", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/alert/get", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/alert/find", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.monitorStatus/uptime/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/get", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/find", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/alert/get", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/alert/find", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.durationAnomaly/uptime/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/get", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/find", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/getAlertSummary", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/alert/get", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/alert/find", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/alert/getAuthorizedAlertsIndices", + "alerting:xpack.synthetics.alerts.monitorStatus/uptime/alert/getAlertSummary", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/get", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/find", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/getAlertSummary", + "alerting:xpack.synthetics.alerts.tls/uptime/alert/get", + "alerting:xpack.synthetics.alerts.tls/uptime/alert/find", + "alerting:xpack.synthetics.alerts.tls/uptime/alert/getAuthorizedAlertsIndices", + "alerting:xpack.synthetics.alerts.tls/uptime/alert/getAlertSummary", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/get", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/find", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/getAlertSummary", + "app:observability", + "ui:catalogue/observability", + "ui:navLinks/observability", + "ui:observability/read", "alerting:apm.error_rate/observability/rule/get", "alerting:apm.error_rate/observability/rule/getRuleState", "alerting:apm.error_rate/observability/rule/getAlertSummary", @@ -10281,6 +20682,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.error_rate/observability/rule/getRuleExecutionKPI", "alerting:apm.error_rate/observability/rule/getBackfill", "alerting:apm.error_rate/observability/rule/findBackfill", + "alerting:apm.error_rate/alerts/rule/get", + "alerting:apm.error_rate/alerts/rule/getRuleState", + "alerting:apm.error_rate/alerts/rule/getAlertSummary", + "alerting:apm.error_rate/alerts/rule/getExecutionLog", + "alerting:apm.error_rate/alerts/rule/getActionErrorLog", + "alerting:apm.error_rate/alerts/rule/find", + "alerting:apm.error_rate/alerts/rule/getRuleExecutionKPI", + "alerting:apm.error_rate/alerts/rule/getBackfill", + "alerting:apm.error_rate/alerts/rule/findBackfill", "alerting:apm.transaction_error_rate/observability/rule/get", "alerting:apm.transaction_error_rate/observability/rule/getRuleState", "alerting:apm.transaction_error_rate/observability/rule/getAlertSummary", @@ -10290,6 +20700,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.transaction_error_rate/observability/rule/getRuleExecutionKPI", "alerting:apm.transaction_error_rate/observability/rule/getBackfill", "alerting:apm.transaction_error_rate/observability/rule/findBackfill", + "alerting:apm.transaction_error_rate/alerts/rule/get", + "alerting:apm.transaction_error_rate/alerts/rule/getRuleState", + "alerting:apm.transaction_error_rate/alerts/rule/getAlertSummary", + "alerting:apm.transaction_error_rate/alerts/rule/getExecutionLog", + "alerting:apm.transaction_error_rate/alerts/rule/getActionErrorLog", + "alerting:apm.transaction_error_rate/alerts/rule/find", + "alerting:apm.transaction_error_rate/alerts/rule/getRuleExecutionKPI", + "alerting:apm.transaction_error_rate/alerts/rule/getBackfill", + "alerting:apm.transaction_error_rate/alerts/rule/findBackfill", "alerting:apm.transaction_duration/observability/rule/get", "alerting:apm.transaction_duration/observability/rule/getRuleState", "alerting:apm.transaction_duration/observability/rule/getAlertSummary", @@ -10299,6 +20718,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.transaction_duration/observability/rule/getRuleExecutionKPI", "alerting:apm.transaction_duration/observability/rule/getBackfill", "alerting:apm.transaction_duration/observability/rule/findBackfill", + "alerting:apm.transaction_duration/alerts/rule/get", + "alerting:apm.transaction_duration/alerts/rule/getRuleState", + "alerting:apm.transaction_duration/alerts/rule/getAlertSummary", + "alerting:apm.transaction_duration/alerts/rule/getExecutionLog", + "alerting:apm.transaction_duration/alerts/rule/getActionErrorLog", + "alerting:apm.transaction_duration/alerts/rule/find", + "alerting:apm.transaction_duration/alerts/rule/getRuleExecutionKPI", + "alerting:apm.transaction_duration/alerts/rule/getBackfill", + "alerting:apm.transaction_duration/alerts/rule/findBackfill", "alerting:apm.anomaly/observability/rule/get", "alerting:apm.anomaly/observability/rule/getRuleState", "alerting:apm.anomaly/observability/rule/getAlertSummary", @@ -10308,6 +20736,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.anomaly/observability/rule/getRuleExecutionKPI", "alerting:apm.anomaly/observability/rule/getBackfill", "alerting:apm.anomaly/observability/rule/findBackfill", + "alerting:apm.anomaly/alerts/rule/get", + "alerting:apm.anomaly/alerts/rule/getRuleState", + "alerting:apm.anomaly/alerts/rule/getAlertSummary", + "alerting:apm.anomaly/alerts/rule/getExecutionLog", + "alerting:apm.anomaly/alerts/rule/getActionErrorLog", + "alerting:apm.anomaly/alerts/rule/find", + "alerting:apm.anomaly/alerts/rule/getRuleExecutionKPI", + "alerting:apm.anomaly/alerts/rule/getBackfill", + "alerting:apm.anomaly/alerts/rule/findBackfill", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/get", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/getRuleState", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/getAlertSummary", @@ -10326,42 +20763,200 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.synthetics.alerts.tls/observability/rule/getRuleExecutionKPI", "alerting:xpack.synthetics.alerts.tls/observability/rule/getBackfill", "alerting:xpack.synthetics.alerts.tls/observability/rule/findBackfill", - "alerting:slo.rules.burnRate/observability/alert/get", - "alerting:slo.rules.burnRate/observability/alert/find", - "alerting:slo.rules.burnRate/observability/alert/getAuthorizedAlertsIndices", - "alerting:slo.rules.burnRate/observability/alert/getAlertSummary", - "alerting:observability.rules.custom_threshold/observability/alert/get", - "alerting:observability.rules.custom_threshold/observability/alert/find", - "alerting:observability.rules.custom_threshold/observability/alert/getAuthorizedAlertsIndices", - "alerting:observability.rules.custom_threshold/observability/alert/getAlertSummary", - "alerting:.es-query/observability/alert/get", - "alerting:.es-query/observability/alert/find", - "alerting:.es-query/observability/alert/getAuthorizedAlertsIndices", - "alerting:.es-query/observability/alert/getAlertSummary", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/get", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/find", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAuthorizedAlertsIndices", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAlertSummary", - "alerting:metrics.alert.inventory.threshold/observability/alert/get", - "alerting:metrics.alert.inventory.threshold/observability/alert/find", - "alerting:metrics.alert.inventory.threshold/observability/alert/getAuthorizedAlertsIndices", - "alerting:metrics.alert.inventory.threshold/observability/alert/getAlertSummary", + "alerting:metrics.alert.threshold/observability/rule/get", + "alerting:metrics.alert.threshold/observability/rule/getRuleState", + "alerting:metrics.alert.threshold/observability/rule/getAlertSummary", + "alerting:metrics.alert.threshold/observability/rule/getExecutionLog", + "alerting:metrics.alert.threshold/observability/rule/getActionErrorLog", + "alerting:metrics.alert.threshold/observability/rule/find", + "alerting:metrics.alert.threshold/observability/rule/getRuleExecutionKPI", + "alerting:metrics.alert.threshold/observability/rule/getBackfill", + "alerting:metrics.alert.threshold/observability/rule/findBackfill", + "alerting:metrics.alert.threshold/alerts/rule/get", + "alerting:metrics.alert.threshold/alerts/rule/getRuleState", + "alerting:metrics.alert.threshold/alerts/rule/getAlertSummary", + "alerting:metrics.alert.threshold/alerts/rule/getExecutionLog", + "alerting:metrics.alert.threshold/alerts/rule/getActionErrorLog", + "alerting:metrics.alert.threshold/alerts/rule/find", + "alerting:metrics.alert.threshold/alerts/rule/getRuleExecutionKPI", + "alerting:metrics.alert.threshold/alerts/rule/getBackfill", + "alerting:metrics.alert.threshold/alerts/rule/findBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/get", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleState", + "alerting:metrics.alert.inventory.threshold/observability/rule/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/rule/getExecutionLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/getActionErrorLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/find", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleExecutionKPI", + "alerting:metrics.alert.inventory.threshold/observability/rule/getBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/findBackfill", + "alerting:metrics.alert.inventory.threshold/alerts/rule/get", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getRuleState", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getExecutionLog", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getActionErrorLog", + "alerting:metrics.alert.inventory.threshold/alerts/rule/find", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getRuleExecutionKPI", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getBackfill", + "alerting:metrics.alert.inventory.threshold/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.tls/observability/rule/get", + "alerting:xpack.uptime.alerts.tls/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.tls/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tls/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tls/observability/rule/find", + "alerting:xpack.uptime.alerts.tls/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tls/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.tls/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/get", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/find", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/get", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/find", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/get", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/find", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/findBackfill", + "alerting:logs.alert.document.count/observability/rule/get", + "alerting:logs.alert.document.count/observability/rule/getRuleState", + "alerting:logs.alert.document.count/observability/rule/getAlertSummary", + "alerting:logs.alert.document.count/observability/rule/getExecutionLog", + "alerting:logs.alert.document.count/observability/rule/getActionErrorLog", + "alerting:logs.alert.document.count/observability/rule/find", + "alerting:logs.alert.document.count/observability/rule/getRuleExecutionKPI", + "alerting:logs.alert.document.count/observability/rule/getBackfill", + "alerting:logs.alert.document.count/observability/rule/findBackfill", + "alerting:logs.alert.document.count/alerts/rule/get", + "alerting:logs.alert.document.count/alerts/rule/getRuleState", + "alerting:logs.alert.document.count/alerts/rule/getAlertSummary", + "alerting:logs.alert.document.count/alerts/rule/getExecutionLog", + "alerting:logs.alert.document.count/alerts/rule/getActionErrorLog", + "alerting:logs.alert.document.count/alerts/rule/find", + "alerting:logs.alert.document.count/alerts/rule/getRuleExecutionKPI", + "alerting:logs.alert.document.count/alerts/rule/getBackfill", + "alerting:logs.alert.document.count/alerts/rule/findBackfill", + "alerting:slo.rules.burnRate/observability/rule/get", + "alerting:slo.rules.burnRate/observability/rule/getRuleState", + "alerting:slo.rules.burnRate/observability/rule/getAlertSummary", + "alerting:slo.rules.burnRate/observability/rule/getExecutionLog", + "alerting:slo.rules.burnRate/observability/rule/getActionErrorLog", + "alerting:slo.rules.burnRate/observability/rule/find", + "alerting:slo.rules.burnRate/observability/rule/getRuleExecutionKPI", + "alerting:slo.rules.burnRate/observability/rule/getBackfill", + "alerting:slo.rules.burnRate/observability/rule/findBackfill", + "alerting:slo.rules.burnRate/alerts/rule/get", + "alerting:slo.rules.burnRate/alerts/rule/getRuleState", + "alerting:slo.rules.burnRate/alerts/rule/getAlertSummary", + "alerting:slo.rules.burnRate/alerts/rule/getExecutionLog", + "alerting:slo.rules.burnRate/alerts/rule/getActionErrorLog", + "alerting:slo.rules.burnRate/alerts/rule/find", + "alerting:slo.rules.burnRate/alerts/rule/getRuleExecutionKPI", + "alerting:slo.rules.burnRate/alerts/rule/getBackfill", + "alerting:slo.rules.burnRate/alerts/rule/findBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/get", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleState", + "alerting:observability.rules.custom_threshold/observability/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/observability/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/observability/rule/find", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/observability/rule/getBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/findBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/get", + "alerting:observability.rules.custom_threshold/alerts/rule/getRuleState", + "alerting:observability.rules.custom_threshold/alerts/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/alerts/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/alerts/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/alerts/rule/find", + "alerting:observability.rules.custom_threshold/alerts/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/alerts/rule/getBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/findBackfill", + "alerting:.es-query/observability/rule/get", + "alerting:.es-query/observability/rule/getRuleState", + "alerting:.es-query/observability/rule/getAlertSummary", + "alerting:.es-query/observability/rule/getExecutionLog", + "alerting:.es-query/observability/rule/getActionErrorLog", + "alerting:.es-query/observability/rule/find", + "alerting:.es-query/observability/rule/getRuleExecutionKPI", + "alerting:.es-query/observability/rule/getBackfill", + "alerting:.es-query/observability/rule/findBackfill", + "alerting:.es-query/alerts/rule/get", + "alerting:.es-query/alerts/rule/getRuleState", + "alerting:.es-query/alerts/rule/getAlertSummary", + "alerting:.es-query/alerts/rule/getExecutionLog", + "alerting:.es-query/alerts/rule/getActionErrorLog", + "alerting:.es-query/alerts/rule/find", + "alerting:.es-query/alerts/rule/getRuleExecutionKPI", + "alerting:.es-query/alerts/rule/getBackfill", + "alerting:.es-query/alerts/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/findBackfill", "alerting:apm.error_rate/observability/alert/get", "alerting:apm.error_rate/observability/alert/find", "alerting:apm.error_rate/observability/alert/getAuthorizedAlertsIndices", "alerting:apm.error_rate/observability/alert/getAlertSummary", + "alerting:apm.error_rate/alerts/alert/get", + "alerting:apm.error_rate/alerts/alert/find", + "alerting:apm.error_rate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.error_rate/alerts/alert/getAlertSummary", "alerting:apm.transaction_error_rate/observability/alert/get", "alerting:apm.transaction_error_rate/observability/alert/find", "alerting:apm.transaction_error_rate/observability/alert/getAuthorizedAlertsIndices", "alerting:apm.transaction_error_rate/observability/alert/getAlertSummary", + "alerting:apm.transaction_error_rate/alerts/alert/get", + "alerting:apm.transaction_error_rate/alerts/alert/find", + "alerting:apm.transaction_error_rate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_error_rate/alerts/alert/getAlertSummary", "alerting:apm.transaction_duration/observability/alert/get", "alerting:apm.transaction_duration/observability/alert/find", "alerting:apm.transaction_duration/observability/alert/getAuthorizedAlertsIndices", "alerting:apm.transaction_duration/observability/alert/getAlertSummary", + "alerting:apm.transaction_duration/alerts/alert/get", + "alerting:apm.transaction_duration/alerts/alert/find", + "alerting:apm.transaction_duration/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_duration/alerts/alert/getAlertSummary", "alerting:apm.anomaly/observability/alert/get", "alerting:apm.anomaly/observability/alert/find", "alerting:apm.anomaly/observability/alert/getAuthorizedAlertsIndices", "alerting:apm.anomaly/observability/alert/getAlertSummary", + "alerting:apm.anomaly/alerts/alert/get", + "alerting:apm.anomaly/alerts/alert/find", + "alerting:apm.anomaly/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.anomaly/alerts/alert/getAlertSummary", "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/get", "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/find", "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/getAuthorizedAlertsIndices", @@ -10370,6 +20965,78 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.synthetics.alerts.tls/observability/alert/find", "alerting:xpack.synthetics.alerts.tls/observability/alert/getAuthorizedAlertsIndices", "alerting:xpack.synthetics.alerts.tls/observability/alert/getAlertSummary", + "alerting:metrics.alert.threshold/observability/alert/get", + "alerting:metrics.alert.threshold/observability/alert/find", + "alerting:metrics.alert.threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.threshold/observability/alert/getAlertSummary", + "alerting:metrics.alert.threshold/alerts/alert/get", + "alerting:metrics.alert.threshold/alerts/alert/find", + "alerting:metrics.alert.threshold/alerts/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.threshold/alerts/alert/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/alert/get", + "alerting:metrics.alert.inventory.threshold/observability/alert/find", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/alerts/alert/get", + "alerting:metrics.alert.inventory.threshold/alerts/alert/find", + "alerting:metrics.alert.inventory.threshold/alerts/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.inventory.threshold/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/observability/alert/get", + "alerting:xpack.uptime.alerts.tls/observability/alert/find", + "alerting:xpack.uptime.alerts.tls/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tls/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/get", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/find", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/get", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/find", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/get", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/find", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/getAlertSummary", + "alerting:logs.alert.document.count/observability/alert/get", + "alerting:logs.alert.document.count/observability/alert/find", + "alerting:logs.alert.document.count/observability/alert/getAuthorizedAlertsIndices", + "alerting:logs.alert.document.count/observability/alert/getAlertSummary", + "alerting:logs.alert.document.count/alerts/alert/get", + "alerting:logs.alert.document.count/alerts/alert/find", + "alerting:logs.alert.document.count/alerts/alert/getAuthorizedAlertsIndices", + "alerting:logs.alert.document.count/alerts/alert/getAlertSummary", + "alerting:slo.rules.burnRate/observability/alert/get", + "alerting:slo.rules.burnRate/observability/alert/find", + "alerting:slo.rules.burnRate/observability/alert/getAuthorizedAlertsIndices", + "alerting:slo.rules.burnRate/observability/alert/getAlertSummary", + "alerting:slo.rules.burnRate/alerts/alert/get", + "alerting:slo.rules.burnRate/alerts/alert/find", + "alerting:slo.rules.burnRate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:slo.rules.burnRate/alerts/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/alert/get", + "alerting:observability.rules.custom_threshold/observability/alert/find", + "alerting:observability.rules.custom_threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/observability/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/alerts/alert/get", + "alerting:observability.rules.custom_threshold/alerts/alert/find", + "alerting:observability.rules.custom_threshold/alerts/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/alerts/alert/getAlertSummary", + "alerting:.es-query/observability/alert/get", + "alerting:.es-query/observability/alert/find", + "alerting:.es-query/observability/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/observability/alert/getAlertSummary", + "alerting:.es-query/alerts/alert/get", + "alerting:.es-query/alerts/alert/find", + "alerting:.es-query/alerts/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/alerts/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/getAlertSummary", ], "read": Array [ "login:", @@ -10450,6 +21117,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.uptime.alerts.tls/uptime/rule/getRuleExecutionKPI", "alerting:xpack.uptime.alerts.tls/uptime/rule/getBackfill", "alerting:xpack.uptime.alerts.tls/uptime/rule/findBackfill", + "alerting:xpack.uptime.alerts.tls/alerts/rule/get", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tls/alerts/rule/find", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tls/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.tls/alerts/rule/findBackfill", "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/get", "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/getRuleState", "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/getAlertSummary", @@ -10459,6 +21135,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/getRuleExecutionKPI", "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/getBackfill", "alerting:xpack.uptime.alerts.tlsCertificate/uptime/rule/findBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/get", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/find", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/rule/findBackfill", "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/get", "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/getRuleState", "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/getAlertSummary", @@ -10468,6 +21153,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/getRuleExecutionKPI", "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/getBackfill", "alerting:xpack.uptime.alerts.monitorStatus/uptime/rule/findBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/get", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/find", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/rule/findBackfill", "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/get", "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/getRuleState", "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/getAlertSummary", @@ -10477,6 +21171,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/getRuleExecutionKPI", "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/getBackfill", "alerting:xpack.uptime.alerts.durationAnomaly/uptime/rule/findBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/get", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getRuleState", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/find", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/getBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/rule/findBackfill", "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/get", "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/getRuleState", "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/getAlertSummary", @@ -10486,6 +21189,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/getRuleExecutionKPI", "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/getBackfill", "alerting:xpack.synthetics.alerts.monitorStatus/uptime/rule/findBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/get", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getRuleState", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getAlertSummary", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getExecutionLog", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getActionErrorLog", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/find", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/getBackfill", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/rule/findBackfill", "alerting:xpack.synthetics.alerts.tls/uptime/rule/get", "alerting:xpack.synthetics.alerts.tls/uptime/rule/getRuleState", "alerting:xpack.synthetics.alerts.tls/uptime/rule/getAlertSummary", @@ -10495,79 +21207,67 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.synthetics.alerts.tls/uptime/rule/getRuleExecutionKPI", "alerting:xpack.synthetics.alerts.tls/uptime/rule/getBackfill", "alerting:xpack.synthetics.alerts.tls/uptime/rule/findBackfill", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/get", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getRuleState", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getAlertSummary", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getExecutionLog", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getActionErrorLog", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/find", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/getBackfill", + "alerting:xpack.synthetics.alerts.tls/alerts/rule/findBackfill", "alerting:xpack.uptime.alerts.tls/uptime/alert/get", "alerting:xpack.uptime.alerts.tls/uptime/alert/find", "alerting:xpack.uptime.alerts.tls/uptime/alert/getAuthorizedAlertsIndices", "alerting:xpack.uptime.alerts.tls/uptime/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/alerts/alert/get", + "alerting:xpack.uptime.alerts.tls/alerts/alert/find", + "alerting:xpack.uptime.alerts.tls/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tls/alerts/alert/getAlertSummary", "alerting:xpack.uptime.alerts.tlsCertificate/uptime/alert/get", "alerting:xpack.uptime.alerts.tlsCertificate/uptime/alert/find", "alerting:xpack.uptime.alerts.tlsCertificate/uptime/alert/getAuthorizedAlertsIndices", "alerting:xpack.uptime.alerts.tlsCertificate/uptime/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/get", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/find", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tlsCertificate/alerts/alert/getAlertSummary", "alerting:xpack.uptime.alerts.monitorStatus/uptime/alert/get", "alerting:xpack.uptime.alerts.monitorStatus/uptime/alert/find", "alerting:xpack.uptime.alerts.monitorStatus/uptime/alert/getAuthorizedAlertsIndices", "alerting:xpack.uptime.alerts.monitorStatus/uptime/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/get", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/find", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.monitorStatus/alerts/alert/getAlertSummary", "alerting:xpack.uptime.alerts.durationAnomaly/uptime/alert/get", "alerting:xpack.uptime.alerts.durationAnomaly/uptime/alert/find", "alerting:xpack.uptime.alerts.durationAnomaly/uptime/alert/getAuthorizedAlertsIndices", "alerting:xpack.uptime.alerts.durationAnomaly/uptime/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/get", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/find", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.durationAnomaly/alerts/alert/getAlertSummary", "alerting:xpack.synthetics.alerts.monitorStatus/uptime/alert/get", "alerting:xpack.synthetics.alerts.monitorStatus/uptime/alert/find", "alerting:xpack.synthetics.alerts.monitorStatus/uptime/alert/getAuthorizedAlertsIndices", "alerting:xpack.synthetics.alerts.monitorStatus/uptime/alert/getAlertSummary", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/get", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/find", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.synthetics.alerts.monitorStatus/alerts/alert/getAlertSummary", "alerting:xpack.synthetics.alerts.tls/uptime/alert/get", "alerting:xpack.synthetics.alerts.tls/uptime/alert/find", "alerting:xpack.synthetics.alerts.tls/uptime/alert/getAuthorizedAlertsIndices", "alerting:xpack.synthetics.alerts.tls/uptime/alert/getAlertSummary", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/get", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/find", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.synthetics.alerts.tls/alerts/alert/getAlertSummary", "app:observability", "ui:catalogue/observability", "ui:navLinks/observability", "ui:observability/read", - "alerting:slo.rules.burnRate/observability/rule/get", - "alerting:slo.rules.burnRate/observability/rule/getRuleState", - "alerting:slo.rules.burnRate/observability/rule/getAlertSummary", - "alerting:slo.rules.burnRate/observability/rule/getExecutionLog", - "alerting:slo.rules.burnRate/observability/rule/getActionErrorLog", - "alerting:slo.rules.burnRate/observability/rule/find", - "alerting:slo.rules.burnRate/observability/rule/getRuleExecutionKPI", - "alerting:slo.rules.burnRate/observability/rule/getBackfill", - "alerting:slo.rules.burnRate/observability/rule/findBackfill", - "alerting:observability.rules.custom_threshold/observability/rule/get", - "alerting:observability.rules.custom_threshold/observability/rule/getRuleState", - "alerting:observability.rules.custom_threshold/observability/rule/getAlertSummary", - "alerting:observability.rules.custom_threshold/observability/rule/getExecutionLog", - "alerting:observability.rules.custom_threshold/observability/rule/getActionErrorLog", - "alerting:observability.rules.custom_threshold/observability/rule/find", - "alerting:observability.rules.custom_threshold/observability/rule/getRuleExecutionKPI", - "alerting:observability.rules.custom_threshold/observability/rule/getBackfill", - "alerting:observability.rules.custom_threshold/observability/rule/findBackfill", - "alerting:.es-query/observability/rule/get", - "alerting:.es-query/observability/rule/getRuleState", - "alerting:.es-query/observability/rule/getAlertSummary", - "alerting:.es-query/observability/rule/getExecutionLog", - "alerting:.es-query/observability/rule/getActionErrorLog", - "alerting:.es-query/observability/rule/find", - "alerting:.es-query/observability/rule/getRuleExecutionKPI", - "alerting:.es-query/observability/rule/getBackfill", - "alerting:.es-query/observability/rule/findBackfill", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/get", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleState", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getAlertSummary", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getExecutionLog", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getActionErrorLog", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/find", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleExecutionKPI", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getBackfill", - "alerting:xpack.ml.anomaly_detection_alert/observability/rule/findBackfill", - "alerting:metrics.alert.inventory.threshold/observability/rule/get", - "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleState", - "alerting:metrics.alert.inventory.threshold/observability/rule/getAlertSummary", - "alerting:metrics.alert.inventory.threshold/observability/rule/getExecutionLog", - "alerting:metrics.alert.inventory.threshold/observability/rule/getActionErrorLog", - "alerting:metrics.alert.inventory.threshold/observability/rule/find", - "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleExecutionKPI", - "alerting:metrics.alert.inventory.threshold/observability/rule/getBackfill", - "alerting:metrics.alert.inventory.threshold/observability/rule/findBackfill", "alerting:apm.error_rate/observability/rule/get", "alerting:apm.error_rate/observability/rule/getRuleState", "alerting:apm.error_rate/observability/rule/getAlertSummary", @@ -10577,6 +21277,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.error_rate/observability/rule/getRuleExecutionKPI", "alerting:apm.error_rate/observability/rule/getBackfill", "alerting:apm.error_rate/observability/rule/findBackfill", + "alerting:apm.error_rate/alerts/rule/get", + "alerting:apm.error_rate/alerts/rule/getRuleState", + "alerting:apm.error_rate/alerts/rule/getAlertSummary", + "alerting:apm.error_rate/alerts/rule/getExecutionLog", + "alerting:apm.error_rate/alerts/rule/getActionErrorLog", + "alerting:apm.error_rate/alerts/rule/find", + "alerting:apm.error_rate/alerts/rule/getRuleExecutionKPI", + "alerting:apm.error_rate/alerts/rule/getBackfill", + "alerting:apm.error_rate/alerts/rule/findBackfill", "alerting:apm.transaction_error_rate/observability/rule/get", "alerting:apm.transaction_error_rate/observability/rule/getRuleState", "alerting:apm.transaction_error_rate/observability/rule/getAlertSummary", @@ -10586,6 +21295,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.transaction_error_rate/observability/rule/getRuleExecutionKPI", "alerting:apm.transaction_error_rate/observability/rule/getBackfill", "alerting:apm.transaction_error_rate/observability/rule/findBackfill", + "alerting:apm.transaction_error_rate/alerts/rule/get", + "alerting:apm.transaction_error_rate/alerts/rule/getRuleState", + "alerting:apm.transaction_error_rate/alerts/rule/getAlertSummary", + "alerting:apm.transaction_error_rate/alerts/rule/getExecutionLog", + "alerting:apm.transaction_error_rate/alerts/rule/getActionErrorLog", + "alerting:apm.transaction_error_rate/alerts/rule/find", + "alerting:apm.transaction_error_rate/alerts/rule/getRuleExecutionKPI", + "alerting:apm.transaction_error_rate/alerts/rule/getBackfill", + "alerting:apm.transaction_error_rate/alerts/rule/findBackfill", "alerting:apm.transaction_duration/observability/rule/get", "alerting:apm.transaction_duration/observability/rule/getRuleState", "alerting:apm.transaction_duration/observability/rule/getAlertSummary", @@ -10595,6 +21313,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.transaction_duration/observability/rule/getRuleExecutionKPI", "alerting:apm.transaction_duration/observability/rule/getBackfill", "alerting:apm.transaction_duration/observability/rule/findBackfill", + "alerting:apm.transaction_duration/alerts/rule/get", + "alerting:apm.transaction_duration/alerts/rule/getRuleState", + "alerting:apm.transaction_duration/alerts/rule/getAlertSummary", + "alerting:apm.transaction_duration/alerts/rule/getExecutionLog", + "alerting:apm.transaction_duration/alerts/rule/getActionErrorLog", + "alerting:apm.transaction_duration/alerts/rule/find", + "alerting:apm.transaction_duration/alerts/rule/getRuleExecutionKPI", + "alerting:apm.transaction_duration/alerts/rule/getBackfill", + "alerting:apm.transaction_duration/alerts/rule/findBackfill", "alerting:apm.anomaly/observability/rule/get", "alerting:apm.anomaly/observability/rule/getRuleState", "alerting:apm.anomaly/observability/rule/getAlertSummary", @@ -10604,6 +21331,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:apm.anomaly/observability/rule/getRuleExecutionKPI", "alerting:apm.anomaly/observability/rule/getBackfill", "alerting:apm.anomaly/observability/rule/findBackfill", + "alerting:apm.anomaly/alerts/rule/get", + "alerting:apm.anomaly/alerts/rule/getRuleState", + "alerting:apm.anomaly/alerts/rule/getAlertSummary", + "alerting:apm.anomaly/alerts/rule/getExecutionLog", + "alerting:apm.anomaly/alerts/rule/getActionErrorLog", + "alerting:apm.anomaly/alerts/rule/find", + "alerting:apm.anomaly/alerts/rule/getRuleExecutionKPI", + "alerting:apm.anomaly/alerts/rule/getBackfill", + "alerting:apm.anomaly/alerts/rule/findBackfill", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/get", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/getRuleState", "alerting:xpack.synthetics.alerts.monitorStatus/observability/rule/getAlertSummary", @@ -10622,42 +21358,200 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.synthetics.alerts.tls/observability/rule/getRuleExecutionKPI", "alerting:xpack.synthetics.alerts.tls/observability/rule/getBackfill", "alerting:xpack.synthetics.alerts.tls/observability/rule/findBackfill", - "alerting:slo.rules.burnRate/observability/alert/get", - "alerting:slo.rules.burnRate/observability/alert/find", - "alerting:slo.rules.burnRate/observability/alert/getAuthorizedAlertsIndices", - "alerting:slo.rules.burnRate/observability/alert/getAlertSummary", - "alerting:observability.rules.custom_threshold/observability/alert/get", - "alerting:observability.rules.custom_threshold/observability/alert/find", - "alerting:observability.rules.custom_threshold/observability/alert/getAuthorizedAlertsIndices", - "alerting:observability.rules.custom_threshold/observability/alert/getAlertSummary", - "alerting:.es-query/observability/alert/get", - "alerting:.es-query/observability/alert/find", - "alerting:.es-query/observability/alert/getAuthorizedAlertsIndices", - "alerting:.es-query/observability/alert/getAlertSummary", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/get", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/find", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAuthorizedAlertsIndices", - "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAlertSummary", - "alerting:metrics.alert.inventory.threshold/observability/alert/get", - "alerting:metrics.alert.inventory.threshold/observability/alert/find", - "alerting:metrics.alert.inventory.threshold/observability/alert/getAuthorizedAlertsIndices", - "alerting:metrics.alert.inventory.threshold/observability/alert/getAlertSummary", + "alerting:metrics.alert.threshold/observability/rule/get", + "alerting:metrics.alert.threshold/observability/rule/getRuleState", + "alerting:metrics.alert.threshold/observability/rule/getAlertSummary", + "alerting:metrics.alert.threshold/observability/rule/getExecutionLog", + "alerting:metrics.alert.threshold/observability/rule/getActionErrorLog", + "alerting:metrics.alert.threshold/observability/rule/find", + "alerting:metrics.alert.threshold/observability/rule/getRuleExecutionKPI", + "alerting:metrics.alert.threshold/observability/rule/getBackfill", + "alerting:metrics.alert.threshold/observability/rule/findBackfill", + "alerting:metrics.alert.threshold/alerts/rule/get", + "alerting:metrics.alert.threshold/alerts/rule/getRuleState", + "alerting:metrics.alert.threshold/alerts/rule/getAlertSummary", + "alerting:metrics.alert.threshold/alerts/rule/getExecutionLog", + "alerting:metrics.alert.threshold/alerts/rule/getActionErrorLog", + "alerting:metrics.alert.threshold/alerts/rule/find", + "alerting:metrics.alert.threshold/alerts/rule/getRuleExecutionKPI", + "alerting:metrics.alert.threshold/alerts/rule/getBackfill", + "alerting:metrics.alert.threshold/alerts/rule/findBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/get", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleState", + "alerting:metrics.alert.inventory.threshold/observability/rule/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/rule/getExecutionLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/getActionErrorLog", + "alerting:metrics.alert.inventory.threshold/observability/rule/find", + "alerting:metrics.alert.inventory.threshold/observability/rule/getRuleExecutionKPI", + "alerting:metrics.alert.inventory.threshold/observability/rule/getBackfill", + "alerting:metrics.alert.inventory.threshold/observability/rule/findBackfill", + "alerting:metrics.alert.inventory.threshold/alerts/rule/get", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getRuleState", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getExecutionLog", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getActionErrorLog", + "alerting:metrics.alert.inventory.threshold/alerts/rule/find", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getRuleExecutionKPI", + "alerting:metrics.alert.inventory.threshold/alerts/rule/getBackfill", + "alerting:metrics.alert.inventory.threshold/alerts/rule/findBackfill", + "alerting:xpack.uptime.alerts.tls/observability/rule/get", + "alerting:xpack.uptime.alerts.tls/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.tls/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tls/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tls/observability/rule/find", + "alerting:xpack.uptime.alerts.tls/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tls/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.tls/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/get", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/find", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/get", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/find", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.monitorStatus/observability/rule/findBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/get", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getRuleState", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getExecutionLog", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getActionErrorLog", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/find", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getRuleExecutionKPI", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/getBackfill", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/rule/findBackfill", + "alerting:logs.alert.document.count/observability/rule/get", + "alerting:logs.alert.document.count/observability/rule/getRuleState", + "alerting:logs.alert.document.count/observability/rule/getAlertSummary", + "alerting:logs.alert.document.count/observability/rule/getExecutionLog", + "alerting:logs.alert.document.count/observability/rule/getActionErrorLog", + "alerting:logs.alert.document.count/observability/rule/find", + "alerting:logs.alert.document.count/observability/rule/getRuleExecutionKPI", + "alerting:logs.alert.document.count/observability/rule/getBackfill", + "alerting:logs.alert.document.count/observability/rule/findBackfill", + "alerting:logs.alert.document.count/alerts/rule/get", + "alerting:logs.alert.document.count/alerts/rule/getRuleState", + "alerting:logs.alert.document.count/alerts/rule/getAlertSummary", + "alerting:logs.alert.document.count/alerts/rule/getExecutionLog", + "alerting:logs.alert.document.count/alerts/rule/getActionErrorLog", + "alerting:logs.alert.document.count/alerts/rule/find", + "alerting:logs.alert.document.count/alerts/rule/getRuleExecutionKPI", + "alerting:logs.alert.document.count/alerts/rule/getBackfill", + "alerting:logs.alert.document.count/alerts/rule/findBackfill", + "alerting:slo.rules.burnRate/observability/rule/get", + "alerting:slo.rules.burnRate/observability/rule/getRuleState", + "alerting:slo.rules.burnRate/observability/rule/getAlertSummary", + "alerting:slo.rules.burnRate/observability/rule/getExecutionLog", + "alerting:slo.rules.burnRate/observability/rule/getActionErrorLog", + "alerting:slo.rules.burnRate/observability/rule/find", + "alerting:slo.rules.burnRate/observability/rule/getRuleExecutionKPI", + "alerting:slo.rules.burnRate/observability/rule/getBackfill", + "alerting:slo.rules.burnRate/observability/rule/findBackfill", + "alerting:slo.rules.burnRate/alerts/rule/get", + "alerting:slo.rules.burnRate/alerts/rule/getRuleState", + "alerting:slo.rules.burnRate/alerts/rule/getAlertSummary", + "alerting:slo.rules.burnRate/alerts/rule/getExecutionLog", + "alerting:slo.rules.burnRate/alerts/rule/getActionErrorLog", + "alerting:slo.rules.burnRate/alerts/rule/find", + "alerting:slo.rules.burnRate/alerts/rule/getRuleExecutionKPI", + "alerting:slo.rules.burnRate/alerts/rule/getBackfill", + "alerting:slo.rules.burnRate/alerts/rule/findBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/get", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleState", + "alerting:observability.rules.custom_threshold/observability/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/observability/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/observability/rule/find", + "alerting:observability.rules.custom_threshold/observability/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/observability/rule/getBackfill", + "alerting:observability.rules.custom_threshold/observability/rule/findBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/get", + "alerting:observability.rules.custom_threshold/alerts/rule/getRuleState", + "alerting:observability.rules.custom_threshold/alerts/rule/getAlertSummary", + "alerting:observability.rules.custom_threshold/alerts/rule/getExecutionLog", + "alerting:observability.rules.custom_threshold/alerts/rule/getActionErrorLog", + "alerting:observability.rules.custom_threshold/alerts/rule/find", + "alerting:observability.rules.custom_threshold/alerts/rule/getRuleExecutionKPI", + "alerting:observability.rules.custom_threshold/alerts/rule/getBackfill", + "alerting:observability.rules.custom_threshold/alerts/rule/findBackfill", + "alerting:.es-query/observability/rule/get", + "alerting:.es-query/observability/rule/getRuleState", + "alerting:.es-query/observability/rule/getAlertSummary", + "alerting:.es-query/observability/rule/getExecutionLog", + "alerting:.es-query/observability/rule/getActionErrorLog", + "alerting:.es-query/observability/rule/find", + "alerting:.es-query/observability/rule/getRuleExecutionKPI", + "alerting:.es-query/observability/rule/getBackfill", + "alerting:.es-query/observability/rule/findBackfill", + "alerting:.es-query/alerts/rule/get", + "alerting:.es-query/alerts/rule/getRuleState", + "alerting:.es-query/alerts/rule/getAlertSummary", + "alerting:.es-query/alerts/rule/getExecutionLog", + "alerting:.es-query/alerts/rule/getActionErrorLog", + "alerting:.es-query/alerts/rule/find", + "alerting:.es-query/alerts/rule/getRuleExecutionKPI", + "alerting:.es-query/alerts/rule/getBackfill", + "alerting:.es-query/alerts/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/observability/rule/findBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/get", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getRuleState", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getExecutionLog", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getActionErrorLog", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/find", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getRuleExecutionKPI", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/getBackfill", + "alerting:xpack.ml.anomaly_detection_alert/alerts/rule/findBackfill", "alerting:apm.error_rate/observability/alert/get", "alerting:apm.error_rate/observability/alert/find", "alerting:apm.error_rate/observability/alert/getAuthorizedAlertsIndices", "alerting:apm.error_rate/observability/alert/getAlertSummary", + "alerting:apm.error_rate/alerts/alert/get", + "alerting:apm.error_rate/alerts/alert/find", + "alerting:apm.error_rate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.error_rate/alerts/alert/getAlertSummary", "alerting:apm.transaction_error_rate/observability/alert/get", "alerting:apm.transaction_error_rate/observability/alert/find", "alerting:apm.transaction_error_rate/observability/alert/getAuthorizedAlertsIndices", "alerting:apm.transaction_error_rate/observability/alert/getAlertSummary", + "alerting:apm.transaction_error_rate/alerts/alert/get", + "alerting:apm.transaction_error_rate/alerts/alert/find", + "alerting:apm.transaction_error_rate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_error_rate/alerts/alert/getAlertSummary", "alerting:apm.transaction_duration/observability/alert/get", "alerting:apm.transaction_duration/observability/alert/find", "alerting:apm.transaction_duration/observability/alert/getAuthorizedAlertsIndices", "alerting:apm.transaction_duration/observability/alert/getAlertSummary", + "alerting:apm.transaction_duration/alerts/alert/get", + "alerting:apm.transaction_duration/alerts/alert/find", + "alerting:apm.transaction_duration/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.transaction_duration/alerts/alert/getAlertSummary", "alerting:apm.anomaly/observability/alert/get", "alerting:apm.anomaly/observability/alert/find", "alerting:apm.anomaly/observability/alert/getAuthorizedAlertsIndices", "alerting:apm.anomaly/observability/alert/getAlertSummary", + "alerting:apm.anomaly/alerts/alert/get", + "alerting:apm.anomaly/alerts/alert/find", + "alerting:apm.anomaly/alerts/alert/getAuthorizedAlertsIndices", + "alerting:apm.anomaly/alerts/alert/getAlertSummary", "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/get", "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/find", "alerting:xpack.synthetics.alerts.monitorStatus/observability/alert/getAuthorizedAlertsIndices", @@ -10666,6 +21560,78 @@ export default function ({ getService }: FtrProviderContext) { "alerting:xpack.synthetics.alerts.tls/observability/alert/find", "alerting:xpack.synthetics.alerts.tls/observability/alert/getAuthorizedAlertsIndices", "alerting:xpack.synthetics.alerts.tls/observability/alert/getAlertSummary", + "alerting:metrics.alert.threshold/observability/alert/get", + "alerting:metrics.alert.threshold/observability/alert/find", + "alerting:metrics.alert.threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.threshold/observability/alert/getAlertSummary", + "alerting:metrics.alert.threshold/alerts/alert/get", + "alerting:metrics.alert.threshold/alerts/alert/find", + "alerting:metrics.alert.threshold/alerts/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.threshold/alerts/alert/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/observability/alert/get", + "alerting:metrics.alert.inventory.threshold/observability/alert/find", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.inventory.threshold/observability/alert/getAlertSummary", + "alerting:metrics.alert.inventory.threshold/alerts/alert/get", + "alerting:metrics.alert.inventory.threshold/alerts/alert/find", + "alerting:metrics.alert.inventory.threshold/alerts/alert/getAuthorizedAlertsIndices", + "alerting:metrics.alert.inventory.threshold/alerts/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tls/observability/alert/get", + "alerting:xpack.uptime.alerts.tls/observability/alert/find", + "alerting:xpack.uptime.alerts.tls/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tls/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/get", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/find", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.tlsCertificate/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/get", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/find", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.monitorStatus/observability/alert/getAlertSummary", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/get", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/find", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.uptime.alerts.durationAnomaly/observability/alert/getAlertSummary", + "alerting:logs.alert.document.count/observability/alert/get", + "alerting:logs.alert.document.count/observability/alert/find", + "alerting:logs.alert.document.count/observability/alert/getAuthorizedAlertsIndices", + "alerting:logs.alert.document.count/observability/alert/getAlertSummary", + "alerting:logs.alert.document.count/alerts/alert/get", + "alerting:logs.alert.document.count/alerts/alert/find", + "alerting:logs.alert.document.count/alerts/alert/getAuthorizedAlertsIndices", + "alerting:logs.alert.document.count/alerts/alert/getAlertSummary", + "alerting:slo.rules.burnRate/observability/alert/get", + "alerting:slo.rules.burnRate/observability/alert/find", + "alerting:slo.rules.burnRate/observability/alert/getAuthorizedAlertsIndices", + "alerting:slo.rules.burnRate/observability/alert/getAlertSummary", + "alerting:slo.rules.burnRate/alerts/alert/get", + "alerting:slo.rules.burnRate/alerts/alert/find", + "alerting:slo.rules.burnRate/alerts/alert/getAuthorizedAlertsIndices", + "alerting:slo.rules.burnRate/alerts/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/observability/alert/get", + "alerting:observability.rules.custom_threshold/observability/alert/find", + "alerting:observability.rules.custom_threshold/observability/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/observability/alert/getAlertSummary", + "alerting:observability.rules.custom_threshold/alerts/alert/get", + "alerting:observability.rules.custom_threshold/alerts/alert/find", + "alerting:observability.rules.custom_threshold/alerts/alert/getAuthorizedAlertsIndices", + "alerting:observability.rules.custom_threshold/alerts/alert/getAlertSummary", + "alerting:.es-query/observability/alert/get", + "alerting:.es-query/observability/alert/find", + "alerting:.es-query/observability/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/observability/alert/getAlertSummary", + "alerting:.es-query/alerts/alert/get", + "alerting:.es-query/alerts/alert/find", + "alerting:.es-query/alerts/alert/getAuthorizedAlertsIndices", + "alerting:.es-query/alerts/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/observability/alert/getAlertSummary", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/get", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/find", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/getAuthorizedAlertsIndices", + "alerting:xpack.ml.anomaly_detection_alert/alerts/alert/getAlertSummary", ], }, } diff --git a/x-pack/test_serverless/functional/services/deployment_agnostic_services.ts b/x-pack/test_serverless/functional/services/deployment_agnostic_services.ts index 314ecf93fb7be..1f09e7353763f 100644 --- a/x-pack/test_serverless/functional/services/deployment_agnostic_services.ts +++ b/x-pack/test_serverless/functional/services/deployment_agnostic_services.ts @@ -36,7 +36,6 @@ const deploymentAgnosticFunctionalServices = _.pick(functionalServices, [ 'dashboardVisualizations', 'dataGrid', 'dataStreams', - 'docTable', 'dataViews', 'elasticChart', 'embedding', diff --git a/x-pack/test_serverless/functional/test_suites/common/discover/group6/_sidebar.ts b/x-pack/test_serverless/functional/test_suites/common/discover/group6/_sidebar.ts index 61cd9728223d1..e7be4ab2859f5 100644 --- a/x-pack/test_serverless/functional/test_suites/common/discover/group6/_sidebar.ts +++ b/x-pack/test_serverless/functional/test_suites/common/discover/group6/_sidebar.ts @@ -27,12 +27,26 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const retry = getService('retry'); const dataGrid = getService('dataGrid'); const dataViews = getService('dataViews'); + const queryBar = getService('queryBar'); + const log = getService('log'); const INITIAL_FIELD_LIST_SUMMARY = '48 available fields. 5 empty fields. 4 meta fields.'; - describe('discover sidebar', function describeIndexTests() { - // see details: https://github.com/elastic/kibana/issues/195100 - this.tags(['failsOnMKI']); + const expectFieldListDescription = async (expectedNumber: string) => { + return await retry.try(async () => { + await PageObjects.discover.waitUntilSearchingHasFinished(); + await PageObjects.unifiedFieldList.waitUntilSidebarHasLoaded(); + const ariaDescription = await PageObjects.unifiedFieldList.getSidebarAriaDescription(); + if (ariaDescription !== expectedNumber) { + log.warning( + `Expected Sidebar Aria Description: ${expectedNumber}, got: ${ariaDescription}` + ); + await queryBar.submitQuery(); + } + expect(ariaDescription).to.be(expectedNumber); + }); + }; + describe('discover sidebar', function describeIndexTests() { before(async function () { await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/logstash_functional'); await PageObjects.svlCommonPage.loginAsAdmin(); @@ -66,36 +80,21 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.unifiedFieldList.waitUntilSidebarHasLoaded(); await PageObjects.unifiedFieldList.openSidebarFieldFilter(); - expect(await PageObjects.unifiedFieldList.getSidebarAriaDescription()).to.be( - INITIAL_FIELD_LIST_SUMMARY - ); + await expectFieldListDescription(INITIAL_FIELD_LIST_SUMMARY); await testSubjects.click('typeFilter-keyword'); - - await retry.waitFor('first updates', async () => { - return ( - (await PageObjects.unifiedFieldList.getSidebarAriaDescription()) === - '6 available fields. 1 empty field. 3 meta fields.' - ); - }); + // first update + await expectFieldListDescription('6 available fields. 1 empty field. 3 meta fields.'); await testSubjects.click('typeFilter-number'); - await retry.waitFor('second updates', async () => { - return ( - (await PageObjects.unifiedFieldList.getSidebarAriaDescription()) === - '10 available fields. 3 empty fields. 4 meta fields.' - ); - }); + // second update + await expectFieldListDescription('10 available fields. 3 empty fields. 4 meta fields.'); await testSubjects.click('fieldListFiltersFieldTypeFilterClearAll'); - await retry.waitFor('reset', async () => { - return ( - (await PageObjects.unifiedFieldList.getSidebarAriaDescription()) === - INITIAL_FIELD_LIST_SUMMARY - ); - }); + // reset + await expectFieldListDescription(INITIAL_FIELD_LIST_SUMMARY); }); // TODO: ES|QL tests removed since ES|QL isn't supported in Serverless @@ -103,44 +102,23 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { describe('search', function () { beforeEach(async () => { - await PageObjects.header.waitUntilLoadingHasFinished(); - await PageObjects.unifiedFieldList.waitUntilSidebarHasLoaded(); - - expect(await PageObjects.unifiedFieldList.getSidebarAriaDescription()).to.be( - INITIAL_FIELD_LIST_SUMMARY - ); + await expectFieldListDescription(INITIAL_FIELD_LIST_SUMMARY); }); afterEach(async () => { const fieldSearch = await testSubjects.find('clearSearchButton'); await fieldSearch.click(); - await retry.waitFor('reset', async () => { - return ( - (await PageObjects.unifiedFieldList.getSidebarAriaDescription()) === - INITIAL_FIELD_LIST_SUMMARY - ); - }); + // reset + await expectFieldListDescription(INITIAL_FIELD_LIST_SUMMARY); }); it('should be able to search by string', async function () { await PageObjects.unifiedFieldList.findFieldByName('i'); - await retry.waitFor('first updates', async () => { - return ( - (await PageObjects.unifiedFieldList.getSidebarAriaDescription()) === - '28 available fields. 2 empty fields. 3 meta fields.' - ); - }); - + await expectFieldListDescription('28 available fields. 2 empty fields. 3 meta fields.'); await PageObjects.unifiedFieldList.findFieldByName('p'); - - await retry.waitFor('second updates', async () => { - return ( - (await PageObjects.unifiedFieldList.getSidebarAriaDescription()) === - '4 available fields. 0 meta fields.' - ); - }); + await expectFieldListDescription('4 available fields. 0 meta fields.'); expect( (await PageObjects.unifiedFieldList.getSidebarSectionFieldNames('available')).join(', ') @@ -149,13 +127,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { it('should be able to search by wildcard', async function () { await PageObjects.unifiedFieldList.findFieldByName('relatedContent*image'); - - await retry.waitFor('updates', async () => { - return ( - (await PageObjects.unifiedFieldList.getSidebarAriaDescription()) === - '2 available fields. 0 meta fields.' - ); - }); + await expectFieldListDescription('2 available fields. 0 meta fields.'); expect( (await PageObjects.unifiedFieldList.getSidebarSectionFieldNames('available')).join(', ') @@ -165,12 +137,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { it('should be able to search with spaces as wildcard', async function () { await PageObjects.unifiedFieldList.findFieldByName('relatedContent image'); - await retry.waitFor('updates', async () => { - return ( - (await PageObjects.unifiedFieldList.getSidebarAriaDescription()) === - '4 available fields. 0 meta fields.' - ); - }); + await expectFieldListDescription('4 available fields. 0 meta fields.'); expect( (await PageObjects.unifiedFieldList.getSidebarSectionFieldNames('available')).join(', ') @@ -181,13 +148,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { it('should be able to search with fuzzy search (1 typo)', async function () { await PageObjects.unifiedFieldList.findFieldByName('rel4tedContent.art'); - - await retry.waitFor('updates', async () => { - return ( - (await PageObjects.unifiedFieldList.getSidebarAriaDescription()) === - '4 available fields. 0 meta fields.' - ); - }); + await expectFieldListDescription('4 available fields. 0 meta fields.'); expect( (await PageObjects.unifiedFieldList.getSidebarSectionFieldNames('available')).join(', ') @@ -204,9 +165,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); // expect no changes in the list - expect(await PageObjects.unifiedFieldList.getSidebarAriaDescription()).to.be( - INITIAL_FIELD_LIST_SUMMARY - ); + await expectFieldListDescription(INITIAL_FIELD_LIST_SUMMARY); }); }); @@ -311,9 +270,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { (await PageObjects.unifiedFieldList.getSidebarSectionFieldNames('meta')).join(', ') ).to.be('_id, _ignored, _index, _score'); - expect(await PageObjects.unifiedFieldList.getSidebarAriaDescription()).to.be( - INITIAL_FIELD_LIST_SUMMARY - ); + await expectFieldListDescription(INITIAL_FIELD_LIST_SUMMARY); }); it('should show field list groups excluding subfields when searched from source', async function () { @@ -354,7 +311,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { (await PageObjects.unifiedFieldList.getSidebarSectionFieldNames('unmapped')).join(', ') ).to.be('relatedContent'); - expect(await PageObjects.unifiedFieldList.getSidebarAriaDescription()).to.be( + await expectFieldListDescription( '48 available fields. 1 unmapped field. 5 empty fields. 4 meta fields.' ); }); @@ -375,7 +332,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { expect(availableFields.includes('extension')).to.be(true); expect(availableFields.includes('@message')).to.be(true); - expect(await PageObjects.unifiedFieldList.getSidebarAriaDescription()).to.be( + await expectFieldListDescription( '2 selected fields. 2 popular fields. 48 available fields. 5 empty fields. 4 meta fields.' ); @@ -395,7 +352,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { (await PageObjects.unifiedFieldList.getSidebarSectionFieldNames('popular')).join(', ') ).to.be('@message, _id, extension'); - expect(await PageObjects.unifiedFieldList.getSidebarAriaDescription()).to.be( + await expectFieldListDescription( '3 selected fields. 3 popular fields. 48 available fields. 5 empty fields. 4 meta fields.' ); }); @@ -408,20 +365,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { 'test/functional/fixtures/kbn_archiver/index_pattern_without_timefield' ); await browser.refresh(); - await PageObjects.unifiedFieldList.waitUntilSidebarHasLoaded(); - - expect(await PageObjects.unifiedFieldList.getSidebarAriaDescription()).to.be( - INITIAL_FIELD_LIST_SUMMARY - ); - + await expectFieldListDescription(INITIAL_FIELD_LIST_SUMMARY); await dataViews.switchToAndValidate('with-timefield'); - await PageObjects.header.waitUntilLoadingHasFinished(); - await PageObjects.unifiedFieldList.waitUntilSidebarHasLoaded(); - - expect(await PageObjects.unifiedFieldList.getSidebarAriaDescription()).to.be( - '0 available fields. 0 meta fields.' - ); + await expectFieldListDescription('0 available fields. 0 meta fields.'); await testSubjects.missingOrFail( `${PageObjects.unifiedFieldList.getSidebarSectionSelector('available')}-fetchWarning` ); @@ -433,12 +380,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await dataViews.switchToAndValidate('logstash-*'); - await PageObjects.header.waitUntilLoadingHasFinished(); - await PageObjects.unifiedFieldList.waitUntilSidebarHasLoaded(); - - expect(await PageObjects.unifiedFieldList.getSidebarAriaDescription()).to.be( - INITIAL_FIELD_LIST_SUMMARY - ); + await expectFieldListDescription(INITIAL_FIELD_LIST_SUMMARY); await kibanaServer.importExport.unload( 'test/functional/fixtures/kbn_archiver/index_pattern_without_timefield' ); @@ -453,29 +395,16 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { ); await browser.refresh(); - await PageObjects.unifiedFieldList.waitUntilSidebarHasLoaded(); - - expect(await PageObjects.unifiedFieldList.getSidebarAriaDescription()).to.be( - INITIAL_FIELD_LIST_SUMMARY - ); + await expectFieldListDescription(INITIAL_FIELD_LIST_SUMMARY); await dataViews.switchToAndValidate('without-timefield'); - await PageObjects.header.waitUntilLoadingHasFinished(); - await PageObjects.unifiedFieldList.waitUntilSidebarHasLoaded(); - - expect(await PageObjects.unifiedFieldList.getSidebarAriaDescription()).to.be( - '6 available fields. 4 meta fields.' - ); + await expectFieldListDescription('6 available fields. 4 meta fields.'); await dataViews.switchToAndValidate('with-timefield'); - await PageObjects.header.waitUntilLoadingHasFinished(); - await PageObjects.unifiedFieldList.waitUntilSidebarHasLoaded(); + await expectFieldListDescription('0 available fields. 7 empty fields. 4 meta fields.'); - expect(await PageObjects.unifiedFieldList.getSidebarAriaDescription()).to.be( - '0 available fields. 7 empty fields. 4 meta fields.' - ); await testSubjects.existOrFail( `${PageObjects.unifiedFieldList.getSidebarSectionSelector( 'available' @@ -484,12 +413,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await dataViews.switchToAndValidate('logstash-*'); - await PageObjects.header.waitUntilLoadingHasFinished(); - await PageObjects.unifiedFieldList.waitUntilSidebarHasLoaded(); - - expect(await PageObjects.unifiedFieldList.getSidebarAriaDescription()).to.be( - INITIAL_FIELD_LIST_SUMMARY - ); + await expectFieldListDescription(INITIAL_FIELD_LIST_SUMMARY); await kibanaServer.importExport.unload( 'test/functional/fixtures/kbn_archiver/index_pattern_without_timefield' @@ -501,11 +425,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); it('should work when filters change', async () => { - await PageObjects.header.waitUntilLoadingHasFinished(); - - expect(await PageObjects.unifiedFieldList.getSidebarAriaDescription()).to.be( - INITIAL_FIELD_LIST_SUMMARY - ); + await expectFieldListDescription(INITIAL_FIELD_LIST_SUMMARY); await PageObjects.unifiedFieldList.clickFieldListItem('extension'); expect(await testSubjects.getVisibleText('dscFieldStats-topValues')).to.be( @@ -516,9 +436,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.header.waitUntilLoadingHasFinished(); await PageObjects.unifiedFieldList.waitUntilSidebarHasLoaded(); - expect(await PageObjects.unifiedFieldList.getSidebarAriaDescription()).to.be( - INITIAL_FIELD_LIST_SUMMARY - ); + await expectFieldListDescription(INITIAL_FIELD_LIST_SUMMARY); // check that the filter was passed down to the sidebar await PageObjects.unifiedFieldList.clickFieldListItem('extension'); @@ -530,31 +448,16 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await kibanaServer.importExport.load( 'test/functional/fixtures/kbn_archiver/many_fields_data_view' ); - + await dataViews.switchToAndValidate('logstash-*'); await browser.refresh(); - await PageObjects.unifiedFieldList.waitUntilSidebarHasLoaded(); - - expect(await PageObjects.unifiedFieldList.getSidebarAriaDescription()).to.be( - INITIAL_FIELD_LIST_SUMMARY - ); + await expectFieldListDescription(INITIAL_FIELD_LIST_SUMMARY); await dataViews.switchToAndValidate('indices-stats*'); - - await PageObjects.header.waitUntilLoadingHasFinished(); - await PageObjects.unifiedFieldList.waitUntilSidebarHasLoaded(); - - expect(await PageObjects.unifiedFieldList.getSidebarAriaDescription()).to.be( - '6873 available fields. 4 meta fields.' - ); + await expectFieldListDescription('6873 available fields. 4 meta fields.'); await dataViews.switchToAndValidate('logstash-*'); - await PageObjects.header.waitUntilLoadingHasFinished(); - await PageObjects.unifiedFieldList.waitUntilSidebarHasLoaded(); - - expect(await PageObjects.unifiedFieldList.getSidebarAriaDescription()).to.be( - INITIAL_FIELD_LIST_SUMMARY - ); + await expectFieldListDescription(INITIAL_FIELD_LIST_SUMMARY); await kibanaServer.importExport.unload( 'test/functional/fixtures/kbn_archiver/many_fields_data_view' @@ -569,12 +472,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { hasTimeField: true, }); - await PageObjects.discover.waitUntilSearchingHasFinished(); - await PageObjects.unifiedFieldList.waitUntilSidebarHasLoaded(); - - expect(await PageObjects.unifiedFieldList.getSidebarAriaDescription()).to.be( - INITIAL_FIELD_LIST_SUMMARY - ); + await expectFieldListDescription(INITIAL_FIELD_LIST_SUMMARY); await PageObjects.discover.addRuntimeField( '_bytes-runtimefield', @@ -585,12 +483,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { return !(await testSubjects.exists('fieldEditor')); }); - await PageObjects.header.waitUntilLoadingHasFinished(); - await PageObjects.unifiedFieldList.waitUntilSidebarHasLoaded(); - - expect(await PageObjects.unifiedFieldList.getSidebarAriaDescription()).to.be( - '49 available fields. 5 empty fields. 4 meta fields.' - ); + await expectFieldListDescription('49 available fields. 5 empty fields. 4 meta fields.'); let allFields = await PageObjects.unifiedFieldList.getAllFieldNames(); expect(allFields.includes('_bytes-runtimefield')).to.be(true); @@ -604,23 +497,13 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { return !(await testSubjects.exists('fieldEditor')); }); - await PageObjects.header.waitUntilLoadingHasFinished(); - await PageObjects.unifiedFieldList.waitUntilSidebarHasLoaded(); - - expect(await PageObjects.unifiedFieldList.getSidebarAriaDescription()).to.be( - '49 available fields. 5 empty fields. 4 meta fields.' - ); + await expectFieldListDescription('49 available fields. 5 empty fields. 4 meta fields.'); allFields = await PageObjects.unifiedFieldList.getAllFieldNames(); expect(allFields.includes('_bytes-runtimefield2')).to.be(true); expect(allFields.includes('_bytes-runtimefield')).to.be(false); await PageObjects.discover.removeField('_bytes-runtimefield'); - await PageObjects.header.waitUntilLoadingHasFinished(); - await PageObjects.unifiedFieldList.waitUntilSidebarHasLoaded(); - - expect(await PageObjects.unifiedFieldList.getSidebarAriaDescription()).to.be( - INITIAL_FIELD_LIST_SUMMARY - ); + await expectFieldListDescription(INITIAL_FIELD_LIST_SUMMARY); allFields = await PageObjects.unifiedFieldList.getAllFieldNames(); expect(allFields.includes('_bytes-runtimefield2')).to.be(false); @@ -628,11 +511,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); it('should render even when retrieving documents failed with an error', async () => { - await PageObjects.header.waitUntilLoadingHasFinished(); - - expect(await PageObjects.unifiedFieldList.getSidebarAriaDescription()).to.be( - INITIAL_FIELD_LIST_SUMMARY - ); + await expectFieldListDescription(INITIAL_FIELD_LIST_SUMMARY); await PageObjects.discover.addRuntimeField('_invalid-runtimefield', `emit(‘’);`); @@ -641,12 +520,9 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { // error in fetching documents because of the invalid runtime field await PageObjects.discover.showsErrorCallout(); - await PageObjects.unifiedFieldList.waitUntilSidebarHasLoaded(); - // check that the sidebar is rendered - expect(await PageObjects.unifiedFieldList.getSidebarAriaDescription()).to.be( - '49 available fields. 5 empty fields. 4 meta fields.' - ); + await expectFieldListDescription('49 available fields. 5 empty fields. 4 meta fields.'); + let allFields = await PageObjects.unifiedFieldList.getAllFieldNames(); expect(allFields.includes('_invalid-runtimefield')).to.be(true); @@ -671,22 +547,11 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await kibanaServer.importExport.load( 'test/functional/fixtures/kbn_archiver/index_pattern_without_timefield' ); - await browser.refresh(); - await PageObjects.unifiedFieldList.waitUntilSidebarHasLoaded(); - - expect(await PageObjects.unifiedFieldList.getSidebarAriaDescription()).to.be( - INITIAL_FIELD_LIST_SUMMARY - ); + await expectFieldListDescription(INITIAL_FIELD_LIST_SUMMARY); await dataViews.switchToAndValidate('with-timefield'); - - await PageObjects.header.waitUntilLoadingHasFinished(); - await PageObjects.unifiedFieldList.waitUntilSidebarHasLoaded(); - - expect(await PageObjects.unifiedFieldList.getSidebarAriaDescription()).to.be( - '0 available fields. 7 empty fields. 4 meta fields.' - ); + await expectFieldListDescription('0 available fields. 7 empty fields. 4 meta fields.'); await testSubjects.existOrFail( `${PageObjects.unifiedFieldList.getSidebarSectionSelector( 'available' @@ -698,12 +563,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { 'Sep 23, 2019 @ 00:00:00.000' ); - await PageObjects.header.waitUntilLoadingHasFinished(); - await PageObjects.unifiedFieldList.waitUntilSidebarHasLoaded(); - - expect(await PageObjects.unifiedFieldList.getSidebarAriaDescription()).to.be( - '7 available fields. 4 meta fields.' - ); + await expectFieldListDescription('7 available fields. 4 meta fields.'); await kibanaServer.importExport.unload( 'test/functional/fixtures/kbn_archiver/index_pattern_without_timefield' diff --git a/x-pack/test_serverless/functional/test_suites/common/visualizations/group3/open_in_lens/tsvb/dashboard.ts b/x-pack/test_serverless/functional/test_suites/common/visualizations/group3/open_in_lens/tsvb/dashboard.ts index 29a4125f3a94c..8b4a0019433b8 100644 --- a/x-pack/test_serverless/functional/test_suites/common/visualizations/group3/open_in_lens/tsvb/dashboard.ts +++ b/x-pack/test_serverless/functional/test_suites/common/visualizations/group3/open_in_lens/tsvb/dashboard.ts @@ -24,8 +24,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { const kibanaServer = getService('kibanaServer'); const visTitle = 'My TSVB to Lens viz 2'; - // FLAKY: https://github.com/elastic/kibana/issues/190737 - describe.skip('Dashboard to TSVB to Lens', function describeIndexTests() { + describe('Dashboard to TSVB to Lens', function describeIndexTests() { const fixture = 'x-pack/test_serverless/functional/fixtures/kbn_archiver/lens/open_in_lens/tsvb/dashboard.json'; diff --git a/x-pack/test_serverless/functional/test_suites/observability/dataset_quality/dataset_quality_details.ts b/x-pack/test_serverless/functional/test_suites/observability/dataset_quality/dataset_quality_details.ts index 52d114802b524..f4f0c8172de49 100644 --- a/x-pack/test_serverless/functional/test_suites/observability/dataset_quality/dataset_quality_details.ts +++ b/x-pack/test_serverless/functional/test_suites/observability/dataset_quality/dataset_quality_details.ts @@ -365,7 +365,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { ); }); - it('should show the degraded fields table with data when present', async () => { + it('should show the degraded fields table with data and spark plots when present', async () => { await PageObjects.datasetQuality.navigateToDetails({ dataStream: degradedDataStreamName, }); @@ -378,17 +378,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.datasetQuality.getDatasetQualityDetailsDegradedFieldTableRows(); expect(rows.length).to.eql(3); - }); - - it('should display Spark Plot for every row of degraded fields', async () => { - await PageObjects.datasetQuality.navigateToDetails({ - dataStream: degradedDataStreamName, - }); - - await PageObjects.datasetQuality.waitUntilTableLoaded(); - - const rows = - await PageObjects.datasetQuality.getDatasetQualityDetailsDegradedFieldTableRows(); const sparkPlots = await testSubjects.findAll( PageObjects.datasetQuality.testSubjectSelectors.datasetQualitySparkPlot diff --git a/x-pack/test_serverless/functional/test_suites/observability/dataset_quality/degraded_field_flyout.ts b/x-pack/test_serverless/functional/test_suites/observability/dataset_quality/degraded_field_flyout.ts index 42a5a095ed6c4..4b28ba5e897dd 100644 --- a/x-pack/test_serverless/functional/test_suites/observability/dataset_quality/degraded_field_flyout.ts +++ b/x-pack/test_serverless/functional/test_suites/observability/dataset_quality/degraded_field_flyout.ts @@ -22,6 +22,7 @@ import { logsNginxMappings } from './custom_mappings/custom_integration_mappings export default function ({ getService, getPageObjects }: FtrProviderContext) { const PageObjects = getPageObjects([ 'common', + 'header', 'navigationalSearch', 'observabilityLogsExplorer', 'datasetQuality', @@ -43,13 +44,16 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const customComponentTemplateName = 'logs-synth@mappings'; const nginxAccessDatasetName = 'nginx.access'; - const customComponentTemplateNameNginx = 'logs-nginx.access@custom'; + const customComponentTemplateNameNginx = `logs-${nginxAccessDatasetName}@custom`; const nginxAccessDataStreamName = `${type}-${nginxAccessDatasetName}-${defaultNamespace}`; const nginxPkg = { name: 'nginx', version: '1.23.0', }; + const apmAppDatasetName = 'apm.app.tug'; + const apmAppDataStreamName = `${type}-${apmAppDatasetName}-${defaultNamespace}`; + describe('Degraded fields flyout', () => { describe('degraded field flyout open-close', () => { before(async () => { @@ -182,6 +186,29 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { .timestamp(timestamp) ); }), + // Ingest Degraded Logs with 26 fields in Apm DataSet + timerange(moment(to).subtract(count, 'minute'), moment(to)) + .interval('1m') + .rate(1) + .generator((timestamp) => { + return Array(1) + .fill(0) + .flatMap(() => + log + .create() + .dataset(apmAppDatasetName) + .message('a log message') + .logLevel(MORE_THAN_1024_CHARS) + .service(serviceName) + .namespace(defaultNamespace) + .defaults({ + 'service.name': serviceName, + 'trace.id': generateShortId(), + test_field: [MORE_THAN_1024_CHARS, ANOTHER_1024_CHARS], + }) + .timestamp(timestamp) + ); + }), ]); // Set Limit of 25 @@ -197,6 +224,11 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { 'mapping.total_fields.limit': 42, }); + // Set Limit of 26 + await PageObjects.datasetQuality.setDataStreamSettings(apmAppDataStreamName, { + 'mapping.total_fields.limit': 25, + }); + await synthtrace.index([ // Ingest Degraded Logs with 26 field timerange(moment(to).subtract(count, 'minute'), moment(to)) @@ -246,11 +278,36 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { .timestamp(timestamp) ); }), + // Ingest Degraded Logs with 27 fields in Apm APP DataSet + timerange(moment(to).subtract(count, 'minute'), moment(to)) + .interval('1m') + .rate(1) + .generator((timestamp) => { + return Array(1) + .fill(0) + .flatMap(() => + log + .create() + .dataset(apmAppDatasetName) + .message('a log message') + .logLevel(MORE_THAN_1024_CHARS) + .service(serviceName) + .namespace(defaultNamespace) + .defaults({ + 'service.name': serviceName, + 'trace.id': generateShortId(), + test_field: [MORE_THAN_1024_CHARS, ANOTHER_1024_CHARS], + 'cloud.project.id': generateShortId(), + }) + .timestamp(timestamp) + ); + }), ]); // Rollover Datastream to reset the limit to default which is 1000 await PageObjects.datasetQuality.rolloverDataStream(degradedDatasetWithLimitDataStreamName); await PageObjects.datasetQuality.rolloverDataStream(nginxAccessDataStreamName); + await PageObjects.datasetQuality.rolloverDataStream(apmAppDataStreamName); // Set Limit of 26 await PageObjects.datasetQuality.setDataStreamSettings( @@ -272,6 +329,16 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { } ); + // Set Limit of 27 + await PageObjects.datasetQuality.setDataStreamSettings( + PageObjects.datasetQuality.generateBackingIndexNameWithoutVersion({ + dataset: apmAppDatasetName, + }) + '-000002', + { + 'mapping.total_fields.limit': 27, + } + ); + await synthtrace.index([ // Ingest Degraded Logs with 26 field timerange(moment(to).subtract(count, 'minute'), moment(to)) @@ -321,6 +388,30 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { .timestamp(timestamp) ); }), + // Ingest Degraded Logs with 27 fields in Apm APP DataSet + timerange(moment(to).subtract(count, 'minute'), moment(to)) + .interval('1m') + .rate(1) + .generator((timestamp) => { + return Array(1) + .fill(0) + .flatMap(() => + log + .create() + .dataset(apmAppDatasetName) + .message('a log message') + .logLevel(MORE_THAN_1024_CHARS) + .service(serviceName) + .namespace(defaultNamespace) + .defaults({ + 'service.name': serviceName, + 'trace.id': generateShortId(), + test_field: [MORE_THAN_1024_CHARS, ANOTHER_1024_CHARS], + 'cloud.project.id': generateShortId(), + }) + .timestamp(timestamp) + ); + }), ]); await PageObjects.svlCommonPage.loginAsAdmin(); }); @@ -452,6 +543,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { expandedDegradedField: 'test_field', }); + await PageObjects.header.waitUntilLoadingHasFinished(); + await retry.tryForTime(5000, async () => { const fieldIgnoredMessageExists = await PageObjects.datasetQuality.doesTextExist( 'datasetQualityDetailsDegradedFieldFlyoutFieldValue-cause', @@ -469,6 +562,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { expandedDegradedField: 'test_field', }); + await PageObjects.header.waitUntilLoadingHasFinished(); + await retry.tryForTime(5000, async () => { const testFieldValue1Exists = await PageObjects.datasetQuality.doesTextExist( 'datasetQualityDetailsDegradedFieldFlyoutFieldValue-values', @@ -491,6 +586,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { expandedDegradedField: 'test_field', }); + await PageObjects.header.waitUntilLoadingHasFinished(); + await retry.tryForTime(5000, async () => { const limitValueExists = await PageObjects.datasetQuality.doesTextExist( 'datasetQualityDetailsDegradedFieldFlyoutFieldValue-characterLimit', @@ -508,6 +605,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { expandedDegradedField: 'test_field', }); + await PageObjects.header.waitUntilLoadingHasFinished(); + // Possible Mitigation Section should exist await testSubjects.existOrFail( 'datasetQualityDetailsDegradedFieldFlyoutPossibleMitigationTitle' @@ -567,6 +666,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { expandedDegradedField: 'test_field', }); + await PageObjects.header.waitUntilLoadingHasFinished(); await PageObjects.datasetQuality.waitUntilPossibleMitigationsLoaded(); // Possible Mitigation Section should exist @@ -632,6 +732,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { expandedDegradedField: 'cloud', }); + await PageObjects.header.waitUntilLoadingHasFinished(); + await retry.tryForTime(5000, async () => { const fieldLimitMessageExists = await PageObjects.datasetQuality.doesTextExist( 'datasetQualityDetailsDegradedFieldFlyoutFieldValue-cause', @@ -649,6 +751,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { expandedDegradedField: 'cloud', }); + await PageObjects.header.waitUntilLoadingHasFinished(); + await retry.tryForTime(5000, async () => { const limitExists = await PageObjects.datasetQuality.doesTextExist( 'datasetQualityDetailsDegradedFieldFlyoutFieldValue-mappingLimit', @@ -666,6 +770,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { expandedDegradedField: 'cloud', }); + await PageObjects.header.waitUntilLoadingHasFinished(); + await testSubjects.existOrFail( PageObjects.datasetQuality.testSubjectSelectors .datasetQualityDetailsDegradedFieldFlyoutIssueDoesNotExist @@ -680,6 +786,38 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { expandedDegradedField: 'cloud.project.id', }); + await PageObjects.header.waitUntilLoadingHasFinished(); + + // Field Limit Mitigation Section should exist + await testSubjects.existOrFail( + 'datasetQualityDetailsDegradedFieldFlyoutFieldLimitMitigationAccordion' + ); + + // Should display the panel to increase field limit + await testSubjects.existOrFail( + 'datasetQualityDetailsDegradedFieldFlyoutIncreaseFieldLimitPanel' + ); + + // Should display official online documentation link + await testSubjects.existOrFail( + 'datasetQualityManualMitigationsPipelineOfficialDocumentationLink' + ); + + const linkButton = await testSubjects.find( + 'datasetQualityManualMitigationsPipelineOfficialDocumentationLink' + ); + + const linkURL = await linkButton.getAttribute('href'); + + expect(linkURL?.endsWith('mapping-settings-limit.html')).to.be(true); + }); + + it('should display increase field limit as a possible mitigation for special packages like apm app', async () => { + await PageObjects.datasetQuality.navigateToDetails({ + dataStream: apmAppDataStreamName, + expandedDegradedField: 'cloud.project', + }); + // Field Limit Mitigation Section should exist await testSubjects.existOrFail( 'datasetQualityDetailsDegradedFieldFlyoutFieldLimitMitigationAccordion' @@ -710,6 +848,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { expandedDegradedField: 'cloud.project', }); + await PageObjects.header.waitUntilLoadingHasFinished(); + // Field Limit Mitigation Section should exist await testSubjects.existOrFail( 'datasetQualityDetailsDegradedFieldFlyoutFieldLimitMitigationAccordion' @@ -732,6 +872,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { expandedDegradedField: 'cloud.project.id', }); + await PageObjects.header.waitUntilLoadingHasFinished(); + // Should display current field limit await testSubjects.existOrFail('datasetQualityIncreaseFieldMappingCurrentLimitFieldText'); @@ -765,10 +907,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { expect(newFieldLimit).to.be(newLimit); // Should display the apply button - await testSubjects.existOrFail('datasetQualityIncreaseFieldMappingLimitButtonButton'); + await testSubjects.existOrFail('datasetQualityIncreaseFieldMappingLimitButton'); const applyButton = await testSubjects.find( - 'datasetQualityIncreaseFieldMappingLimitButtonButton' + 'datasetQualityIncreaseFieldMappingLimitButton' ); const applyButtonDisabledStatus = await applyButton.getAttribute('disabled'); @@ -782,6 +924,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { expandedDegradedField: 'cloud.project.id', }); + await PageObjects.header.waitUntilLoadingHasFinished(); + // Should not allow values less than current limit of 44 await testSubjects.setValue( 'datasetQualityIncreaseFieldMappingProposedLimitFieldText', @@ -793,7 +937,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { ); const applyButton = await testSubjects.find( - 'datasetQualityIncreaseFieldMappingLimitButtonButton' + 'datasetQualityIncreaseFieldMappingLimitButton' ); const applyButtonDisabledStatus = await applyButton.getAttribute('disabled'); @@ -816,9 +960,11 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { expandedDegradedField: 'cloud.project.id', }); + await PageObjects.header.waitUntilLoadingHasFinished(); + await retry.tryForTime(5000, async () => { const applyButton = await testSubjects.find( - 'datasetQualityIncreaseFieldMappingLimitButtonButton' + 'datasetQualityIncreaseFieldMappingLimitButton' ); await applyButton.click(); @@ -835,8 +981,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { expandedDegradedField: 'cloud.project.id', }); + await PageObjects.header.waitUntilLoadingHasFinished(); + const applyButton = await testSubjects.find( - 'datasetQualityIncreaseFieldMappingLimitButtonButton' + 'datasetQualityIncreaseFieldMappingLimitButton' ); await applyButton.click(); diff --git a/x-pack/test_serverless/functional/test_suites/observability/infra/header_menu.ts b/x-pack/test_serverless/functional/test_suites/observability/infra/header_menu.ts deleted file mode 100644 index 775055825d2e7..0000000000000 --- a/x-pack/test_serverless/functional/test_suites/observability/infra/header_menu.ts +++ /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 { FtrProviderContext } from '../../../ftr_provider_context'; - -import { HOSTS_VIEW_PATH } from './constants'; - -export default ({ getPageObjects, getService }: FtrProviderContext) => { - const esArchiver = getService('esArchiver'); - const pageObjects = getPageObjects(['svlCommonPage', 'common', 'infraHome', 'header']); - - // failing feature flag test, see https://github.com/elastic/kibana/issues/191809 - describe.skip('Header menu', () => { - before(async () => { - await esArchiver.load('x-pack/test/functional/es_archives/infra/metrics_and_logs'); - await pageObjects.svlCommonPage.loginAsViewer(); - }); - - after(async () => { - await esArchiver.unload('x-pack/test/functional/es_archives/infra/metrics_and_logs'); - }); - - describe('Alerts dropdown', () => { - beforeEach(async () => { - await pageObjects.common.navigateToApp(HOSTS_VIEW_PATH); - await pageObjects.header.waitUntilLoadingHasFinished(); - }); - - it('is hidden', async () => { - await pageObjects.infraHome.ensureAlertsAndRulesDropdownIsMissing(); - }); - }); - }); -}; diff --git a/x-pack/test_serverless/functional/test_suites/observability/infra/hosts_page.ts b/x-pack/test_serverless/functional/test_suites/observability/infra/hosts_page.ts index 808b079896464..f6acf29cb3a9e 100644 --- a/x-pack/test_serverless/functional/test_suites/observability/infra/hosts_page.ts +++ b/x-pack/test_serverless/functional/test_suites/observability/infra/hosts_page.ts @@ -40,28 +40,22 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { (await pageObjects.infraHostsView.isKPIChartsLoaded()) ); - // failing feature flag test, see https://github.com/elastic/kibana/issues/191810 - describe.skip('Hosts Page', function () { + describe('Hosts Page', function () { before(async () => { - await Promise.all([ - esArchiver.load('x-pack/test/functional/es_archives/infra/metrics_and_logs'), - ]); + await esArchiver.load('x-pack/test/functional/es_archives/infra/metrics_and_logs'); await pageObjects.svlCommonPage.loginAsViewer(); - await browser.setWindowSize(1600, 1200); + + await pageObjects.common.navigateToApp(HOSTS_VIEW_PATH); + await pageObjects.header.waitUntilLoadingHasFinished(); + + await browser.setWindowSize(1600, 1400); }); after(async () => { - await Promise.all([ - esArchiver.unload('x-pack/test/functional/es_archives/infra/metrics_and_logs'), - ]); + await esArchiver.unload('x-pack/test/functional/es_archives/infra/metrics_and_logs'); }); describe('#Single Host Flyout', () => { - before(async () => { - await pageObjects.common.navigateToApp(HOSTS_VIEW_PATH); - await pageObjects.header.waitUntilLoadingHasFinished(); - }); - describe('Tabs', () => { before(async () => { await pageObjects.timePicker.setAbsoluteRange( @@ -100,10 +94,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { it('should show alerts', async () => { await pageObjects.header.waitUntilLoadingHasFinished(); await pageObjects.assetDetails.overviewAlertsTitleExists(); - const CreateRuleButtonExist = await testSubjects.exists( - 'infraAssetDetailsCreateAlertsRuleButton' - ); - expect(CreateRuleButtonExist).to.be(true); + await pageObjects.assetDetails.overviewOpenAlertsFlyoutExist(); }); }); @@ -123,7 +114,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { }); it('should show processes title', async () => { - await await testSubjects.existOrFail('infraAssetDetailsTopProcessesTitle'); + await testSubjects.existOrFail('infraAssetDetailsTopProcessesTitle'); }); }); @@ -175,7 +166,6 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { describe('Metrics Tab', () => { before(async () => { - await browser.scrollTop(); await pageObjects.infraHostsView.visitMetricsTab(); }); @@ -191,7 +181,6 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { describe('Logs Tab', () => { before(async () => { - await browser.scrollTop(); await pageObjects.infraHostsView.visitLogsTab(); }); @@ -206,7 +195,6 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { describe('Alerts Tab', () => { before(async () => { - await browser.scrollTop(); await pageObjects.infraHostsView.visitAlertTab(); }); diff --git a/x-pack/test_serverless/functional/test_suites/observability/infra/index.ts b/x-pack/test_serverless/functional/test_suites/observability/infra/index.ts index b646ba71f960e..914f7760f900e 100644 --- a/x-pack/test_serverless/functional/test_suites/observability/infra/index.ts +++ b/x-pack/test_serverless/functional/test_suites/observability/infra/index.ts @@ -9,7 +9,6 @@ import { FtrProviderContext } from '../../../ftr_provider_context'; export default function ({ loadTestFile }: FtrProviderContext) { describe('Observability Infra', function () { - loadTestFile(require.resolve('./header_menu')); loadTestFile(require.resolve('./navigation')); loadTestFile(require.resolve('./node_details')); loadTestFile(require.resolve('./hosts_page')); diff --git a/x-pack/test_serverless/functional/test_suites/observability/infra/node_details.ts b/x-pack/test_serverless/functional/test_suites/observability/infra/node_details.ts index 25d30117ad6b5..254bf9e555a13 100644 --- a/x-pack/test_serverless/functional/test_suites/observability/infra/node_details.ts +++ b/x-pack/test_serverless/functional/test_suites/observability/infra/node_details.ts @@ -30,8 +30,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { 'svlCommonPage', ]); - // failing feature flag test, see https://github.com/elastic/kibana/issues/191809 - describe.skip('Node Details', () => { + describe('Node Details', () => { describe('#With Asset Details', () => { before(async () => { await esArchiver.load('x-pack/test/functional/es_archives/infra/metrics_and_logs'); @@ -50,7 +49,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { describe('Osquery Tab', () => { it('should not render in serverless', async () => { const OsqueryExist = await testSubjects.exists('infraAssetDetailsOsqueryTab'); - expect(OsqueryExist).to.be(false); + expect(OsqueryExist).to.be(true); }); }); @@ -68,10 +67,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { it('should show alerts', async () => { await pageObjects.header.waitUntilLoadingHasFinished(); await pageObjects.assetDetails.overviewAlertsTitleExists(); - const CreateRuleButtonExist = await testSubjects.exists( - 'infraAssetDetailsCreateAlertsRuleButton' - ); - expect(CreateRuleButtonExist).to.be(true); + await pageObjects.assetDetails.overviewOpenAlertsFlyoutExist(); }); [ diff --git a/x-pack/test_serverless/functional/test_suites/security/config.cloud_security_posture.agentless.ts b/x-pack/test_serverless/functional/test_suites/security/config.cloud_security_posture.agentless.ts index 692ae096265fb..b203bc6427ed2 100644 --- a/x-pack/test_serverless/functional/test_suites/security/config.cloud_security_posture.agentless.ts +++ b/x-pack/test_serverless/functional/test_suites/security/config.cloud_security_posture.agentless.ts @@ -16,6 +16,8 @@ export default createTestConfig({ reportName: 'Serverless Security Cloud Security Agentless Onboarding Functional Tests', }, kbnServerArgs: [ + `--xpack.cloud.serverless.project_id=some_fake_project_id`, + `--xpack.fleet.packages.0.name=cloud_security_posture`, `--xpack.fleet.packages.0.version=${CLOUD_CREDENTIALS_PACKAGE_VERSION}`, `--xpack.fleet.agentless.enabled=true`, @@ -26,11 +28,10 @@ export default createTestConfig({ `--xpack.fleet.agentPolicies.0.id=agentless`, `--xpack.fleet.agentPolicies.0.name=agentless`, `--xpack.fleet.agentPolicies.0.package_policies=[]`, - `--xpack.cloud.serverless.project_id=some_fake_project_id`, `--xpack.fleet.agentPolicies.0.is_default=true`, `--xpack.fleet.agentPolicies.0.is_default_fleet_server=true`, - // Serverless Agentless API + `--xpack.fleet.agentless.enabled=true`, `--xpack.fleet.agentless.api.url=http://localhost:8089`, `--xpack.fleet.agentless.api.tls.certificate=${KBN_CERT_PATH}`, `--xpack.fleet.agentless.api.tls.key=${KBN_KEY_PATH}`, diff --git a/x-pack/test_serverless/functional/test_suites/security/config.cloud_security_posture.agentless_api.ts b/x-pack/test_serverless/functional/test_suites/security/config.cloud_security_posture.agentless_api.ts deleted file mode 100644 index 0f37f224197ef..0000000000000 --- a/x-pack/test_serverless/functional/test_suites/security/config.cloud_security_posture.agentless_api.ts +++ /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; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { CLOUD_CREDENTIALS_PACKAGE_VERSION } from '@kbn/cloud-security-posture-plugin/common/constants'; -import { CA_CERT_PATH, KBN_CERT_PATH, KBN_KEY_PATH } from '@kbn/dev-utils'; -import { createTestConfig } from '../../config.base'; - -export default createTestConfig({ - serverlessProject: 'security', - junit: { - reportName: 'Serverless Security Cloud Security Agentless API Onboarding Functional Tests', - }, - kbnServerArgs: [ - `--xpack.fleet.packages.0.name=cloud_security_posture`, - `--xpack.fleet.packages.0.version=${CLOUD_CREDENTIALS_PACKAGE_VERSION}`, - - `--xpack.fleet.agents.fleet_server.hosts=["https://ftr.kibana:8220"]`, - `--xpack.fleet.internal.fleetServerStandalone=true`, - - // Agentless Configuration based on Serverless Security Dev Yaml - config/serverless.security.dev.yml - `--xpack.fleet.agentless.enabled=true`, - `--xpack.fleet.agentless.api.url=http://localhost:8089`, - `--xpack.fleet.agentless.api.tls.certificate=${KBN_CERT_PATH}`, - `--xpack.fleet.agentless.api.tls.key=${KBN_KEY_PATH}`, - `--xpack.fleet.agentless.api.tls.ca=${CA_CERT_PATH}`, - `--xpack.cloud.serverless.project_id=some_fake_project_id`, - ], - // load tests in the index file - testFiles: [require.resolve('./ftr/cloud_security_posture/agentless_api')], -}); diff --git a/x-pack/test_serverless/functional/test_suites/security/config.mki_only.ts b/x-pack/test_serverless/functional/test_suites/security/config.mki_only.ts new file mode 100644 index 0000000000000..36d3bd6c7dd93 --- /dev/null +++ b/x-pack/test_serverless/functional/test_suites/security/config.mki_only.ts @@ -0,0 +1,30 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { KBN_CERT_PATH, KBN_KEY_PATH } from '@kbn/dev-utils'; +import { createTestConfig } from '../../config.base'; + +export default createTestConfig({ + serverlessProject: 'security', + testFiles: [require.resolve('./index.mki_only.ts')], + junit: { + reportName: 'Serverless Security MKI Functional Tests', + }, + suiteTags: { exclude: ['skipSvlSec'] }, + + // include settings from project controller + // https://github.com/elastic/project-controller/blob/main/internal/project/security/config/elasticsearch.yml + esServerArgs: ['xpack.ml.nlp.enabled=true'], + kbnServerArgs: [ + '--xpack.dataUsage.enabled=true', + '--xpack.dataUsage.enableExperimental=[]', + // dataUsage.autoops* config is set in kibana controller + '--xpack.dataUsage.autoops.enabled=true', + '--xpack.dataUsage.autoops.api.url=http://localhost:9000', + `--xpack.dataUsage.autoops.api.tls.certificate=${KBN_CERT_PATH}`, + `--xpack.dataUsage.autoops.api.tls.key=${KBN_KEY_PATH}`, + ], +}); diff --git a/x-pack/test_serverless/functional/test_suites/security/ftr/cloud_security_posture/agentless/cis_integration_aws.ts b/x-pack/test_serverless/functional/test_suites/security/ftr/cloud_security_posture/agentless/cis_integration_aws.ts index e669545d135f9..ea499f96da585 100644 --- a/x-pack/test_serverless/functional/test_suites/security/ftr/cloud_security_posture/agentless/cis_integration_aws.ts +++ b/x-pack/test_serverless/functional/test_suites/security/ftr/cloud_security_posture/agentless/cis_integration_aws.ts @@ -8,7 +8,7 @@ import { CLOUD_CREDENTIALS_PACKAGE_VERSION } from '@kbn/cloud-security-posture-p import expect from '@kbn/expect'; import * as http from 'http'; import type { FtrProviderContext } from '../../../../../ftr_provider_context'; -import { setupMockServer } from '../agentless_api/mock_agentless_api'; +import { setupMockServer } from './mock_agentless_api'; export default function ({ getPageObjects, getService }: FtrProviderContext) { const mockAgentlessApiService = setupMockServer(); const pageObjects = getPageObjects([ diff --git a/x-pack/test_serverless/functional/test_suites/security/ftr/cloud_security_posture/agentless/cis_integration_gcp.ts b/x-pack/test_serverless/functional/test_suites/security/ftr/cloud_security_posture/agentless/cis_integration_gcp.ts index 95f855697c5bd..897a6e589fdb3 100644 --- a/x-pack/test_serverless/functional/test_suites/security/ftr/cloud_security_posture/agentless/cis_integration_gcp.ts +++ b/x-pack/test_serverless/functional/test_suites/security/ftr/cloud_security_posture/agentless/cis_integration_gcp.ts @@ -9,7 +9,7 @@ import expect from '@kbn/expect'; import { CLOUD_CREDENTIALS_PACKAGE_VERSION } from '@kbn/cloud-security-posture-plugin/common/constants'; import * as http from 'http'; import type { FtrProviderContext } from '../../../../../ftr_provider_context'; -import { setupMockServer } from '../agentless_api/mock_agentless_api'; +import { setupMockServer } from './mock_agentless_api'; export default function ({ getPageObjects, getService }: FtrProviderContext) { const pageObjects = getPageObjects(['common', 'svlCommonPage', 'cisAddIntegration', 'header']); diff --git a/x-pack/test_serverless/functional/test_suites/security/ftr/cloud_security_posture/agentless_api/create_agent.ts b/x-pack/test_serverless/functional/test_suites/security/ftr/cloud_security_posture/agentless/create_agent.ts similarity index 73% rename from x-pack/test_serverless/functional/test_suites/security/ftr/cloud_security_posture/agentless_api/create_agent.ts rename to x-pack/test_serverless/functional/test_suites/security/ftr/cloud_security_posture/agentless/create_agent.ts index bf9fd31b9e266..14351439ac68f 100644 --- a/x-pack/test_serverless/functional/test_suites/security/ftr/cloud_security_posture/agentless_api/create_agent.ts +++ b/x-pack/test_serverless/functional/test_suites/security/ftr/cloud_security_posture/agentless/create_agent.ts @@ -8,12 +8,9 @@ import { CLOUD_CREDENTIALS_PACKAGE_VERSION } from '@kbn/cloud-security-posture-plugin/common/constants'; import * as http from 'http'; import expect from '@kbn/expect'; -import equals from 'fast-deep-equal'; import { setupMockServer } from './mock_agentless_api'; import type { FtrProviderContext } from '../../../../../ftr_provider_context'; export default function ({ getPageObjects, getService }: FtrProviderContext) { - const agentCreationTimeout = 1000 * 60 * 1; // 1 minute - const retry = getService('retry'); const mockAgentlessApiService = setupMockServer(); const pageObjects = getPageObjects([ 'svlCommonPage', @@ -28,12 +25,11 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { const AWS_SINGLE_ACCOUNT_TEST_ID = 'awsSingleTestId'; describe('Agentless API Serverless', function () { + this.tags(['skipMKI', 'cloud_security_posture_agentless']); let mockApiServer: http.Server; let cisIntegration: typeof pageObjects.cisAddIntegration; before(async () => { - // If process.env.TEST_CLOUD is set, then the test is running in the Serverless Quality Gates - // and this MSW server will be listening for a request that will never come. mockApiServer = mockAgentlessApiService.listen(8089); // Start the usage api mock server on port 8089 await pageObjects.svlCommonPage.loginAsAdmin(); cisIntegration = pageObjects.cisAddIntegration; @@ -57,22 +53,6 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { await cisIntegration.selectSetupTechnology('agentless'); await cisIntegration.selectAwsCredentials('direct'); - if ( - process.env.TEST_CLOUD && - process.env.CSPM_AWS_ACCOUNT_ID && - process.env.CSPM_AWS_SECRET_KEY - ) { - await cisIntegration.fillInTextField( - cisIntegration.testSubjectIds.DIRECT_ACCESS_KEY_ID_TEST_ID, - process.env.CSPM_AWS_ACCOUNT_ID - ); - - await cisIntegration.fillInTextField( - cisIntegration.testSubjectIds.DIRECT_ACCESS_SECRET_KEY_TEST_ID, - process.env.CSPM_AWS_SECRET_KEY - ); - } - await pageObjects.header.waitUntilLoadingHasFinished(); await cisIntegration.clickSaveButton(); @@ -85,13 +65,9 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { integrationPolicyName ); - // wait for eventually Pending or Healthy status - // purpose of this retry is to wait for the agent to be created and the status to be updated - // not to wait for the agent to be healthy - await retry.tryForTime(agentCreationTimeout, async () => { - const resStatus = await cisIntegration.getFirstCspmIntegrationPageAgentlessStatus(); - expect(equals(resStatus, 'Healthy') || equals(resStatus, 'Pending')).to.be(true); - }); + const resStatus = await cisIntegration.getFirstCspmIntegrationPageAgentlessStatus(); + // The status can only be Pending because the agentless agent will never be created + expect(resStatus).to.be('Pending'); }); it(`should create default agent-based agent`, async () => { diff --git a/x-pack/test_serverless/functional/test_suites/security/ftr/cloud_security_posture/agentless/index.ts b/x-pack/test_serverless/functional/test_suites/security/ftr/cloud_security_posture/agentless/index.ts index 235757c508c16..875dd630f2ade 100644 --- a/x-pack/test_serverless/functional/test_suites/security/ftr/cloud_security_posture/agentless/index.ts +++ b/x-pack/test_serverless/functional/test_suites/security/ftr/cloud_security_posture/agentless/index.ts @@ -12,5 +12,6 @@ export default function ({ loadTestFile }: FtrProviderContext) { this.tags(['cloud_security_posture_agentless']); loadTestFile(require.resolve('./cis_integration_aws')); loadTestFile(require.resolve('./cis_integration_gcp')); + loadTestFile(require.resolve('./create_agent')); }); } diff --git a/x-pack/test_serverless/functional/test_suites/security/ftr/cloud_security_posture/agentless_api/mock_agentless_api.ts b/x-pack/test_serverless/functional/test_suites/security/ftr/cloud_security_posture/agentless/mock_agentless_api.ts similarity index 100% rename from x-pack/test_serverless/functional/test_suites/security/ftr/cloud_security_posture/agentless_api/mock_agentless_api.ts rename to x-pack/test_serverless/functional/test_suites/security/ftr/cloud_security_posture/agentless/mock_agentless_api.ts diff --git a/x-pack/test_serverless/functional/test_suites/security/ftr/cloud_security_posture/mki_only/README.md b/x-pack/test_serverless/functional/test_suites/security/ftr/cloud_security_posture/mki_only/README.md new file mode 100644 index 0000000000000..9af4048016c79 --- /dev/null +++ b/x-pack/test_serverless/functional/test_suites/security/ftr/cloud_security_posture/mki_only/README.md @@ -0,0 +1,15 @@ +# MKI Serverless Quality Gates + +This folder contains tests that **ONLY** run in the MKI Serverless Quality Gates. These tests are designed to ensure the security and functionality of the system in a serverless environment. + +## Contributing + +Please prefix the tests in this folder with `mki_` so that is clear to the following developer that these tests run only in MKI and Serverless Quality Gates. + +New MKI only test files should be loaded from the root index.ts file of the mki_only directory + +``` +x-pack/test_serverless/functional/test_suites/security/ftr/cloud_security_posture/mki_only/index.ts +``` + +If you would like to contribute to these tests, please follow the contribution guidelines outlined in the main project repository. diff --git a/x-pack/test_serverless/functional/test_suites/security/ftr/cloud_security_posture/mki_only/agentless/mki_create_agent.ts b/x-pack/test_serverless/functional/test_suites/security/ftr/cloud_security_posture/mki_only/agentless/mki_create_agent.ts new file mode 100644 index 0000000000000..4b357eb8c0f4b --- /dev/null +++ b/x-pack/test_serverless/functional/test_suites/security/ftr/cloud_security_posture/mki_only/agentless/mki_create_agent.ts @@ -0,0 +1,104 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor 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 { CLOUD_CREDENTIALS_PACKAGE_VERSION } from '@kbn/cloud-security-posture-plugin/common/constants'; +import expect from '@kbn/expect'; +import type { FtrProviderContext } from '../../../../../../ftr_provider_context'; +export default function ({ getPageObjects, getService }: FtrProviderContext) { + const testSubjects = getService('testSubjects'); + const pageObjects = getPageObjects([ + 'svlCommonPage', + 'cspSecurity', + 'security', + 'header', + 'cisAddIntegration', + ]); + + const CIS_AWS_OPTION_TEST_ID = 'cisAwsTestId'; + + const AWS_SINGLE_ACCOUNT_TEST_ID = 'awsSingleTestId'; + + // This test suite is only running in the Serverless Quality Gates environment + describe('Agentless API Serverless MKI only', function () { + this.tags(['cloud_security_posture_agentless']); + let cisIntegration: typeof pageObjects.cisAddIntegration; + + before(async () => { + await pageObjects.svlCommonPage.loginAsAdmin(); + cisIntegration = pageObjects.cisAddIntegration; + }); + + it(`should create agentless-agent`, async () => { + const integrationPolicyName = `cloud_security_posture-${new Date().toISOString()}`; + await cisIntegration.navigateToAddIntegrationCspmWithVersionPage( + CLOUD_CREDENTIALS_PACKAGE_VERSION + ); + + await cisIntegration.clickOptionButton(CIS_AWS_OPTION_TEST_ID); + await cisIntegration.clickOptionButton(AWS_SINGLE_ACCOUNT_TEST_ID); + + await cisIntegration.inputIntegrationName(integrationPolicyName); + + await cisIntegration.selectSetupTechnology('agentless'); + await cisIntegration.selectAwsCredentials('direct'); + + await pageObjects.header.waitUntilLoadingHasFinished(); + + if (process.env.CSPM_AWS_ACCOUNT_ID && process.env.CSPM_AWS_SECRET_KEY) { + await cisIntegration.fillInTextField( + cisIntegration.testSubjectIds.DIRECT_ACCESS_KEY_ID_TEST_ID, + process.env.CSPM_AWS_ACCOUNT_ID + ); + + await cisIntegration.fillInTextField( + cisIntegration.testSubjectIds.DIRECT_ACCESS_SECRET_KEY_TEST_ID, + process.env.CSPM_AWS_SECRET_KEY + ); + } + + await cisIntegration.clickSaveButton(); + await pageObjects.header.waitUntilLoadingHasFinished(); + + await cisIntegration.navigateToIntegrationCspList(); + await pageObjects.header.waitUntilLoadingHasFinished(); + + expect(await cisIntegration.getFirstCspmIntegrationPageAgentlessIntegration()).to.be( + integrationPolicyName + ); + + const agentStatusBadge = testSubjects.find('agentlessStatusBadge'); + // The status badge could be either "Pending", "Healthy", or "Unhealthy" so we are just checking that it exists + expect(agentStatusBadge).to.be.ok(); + }); + + it(`should create default agent-based agent`, async () => { + const integrationPolicyName = `cloud_security_posture-${new Date().toISOString()}`; + + await cisIntegration.navigateToAddIntegrationCspmWithVersionPage( + CLOUD_CREDENTIALS_PACKAGE_VERSION + ); + + await cisIntegration.clickOptionButton(CIS_AWS_OPTION_TEST_ID); + await cisIntegration.clickOptionButton(AWS_SINGLE_ACCOUNT_TEST_ID); + + await cisIntegration.inputIntegrationName(integrationPolicyName); + + await cisIntegration.clickSaveButton(); + await pageObjects.header.waitUntilLoadingHasFinished(); + + const agentPolicyName = await cisIntegration.getAgentBasedPolicyValue(); + + await cisIntegration.navigateToIntegrationCspList(); + await pageObjects.header.waitUntilLoadingHasFinished(); + + expect(await cisIntegration.getFirstCspmIntegrationPageIntegration()).to.be( + integrationPolicyName + ); + expect(await cisIntegration.getFirstCspmIntegrationPageAgent()).to.be(agentPolicyName); + }); + }); +} diff --git a/x-pack/test_serverless/functional/test_suites/security/ftr/cloud_security_posture/agentless_api/index.ts b/x-pack/test_serverless/functional/test_suites/security/ftr/cloud_security_posture/mki_only/index.ts similarity index 71% rename from x-pack/test_serverless/functional/test_suites/security/ftr/cloud_security_posture/agentless_api/index.ts rename to x-pack/test_serverless/functional/test_suites/security/ftr/cloud_security_posture/mki_only/index.ts index 0aa5f978445f1..a1b5798f831b3 100644 --- a/x-pack/test_serverless/functional/test_suites/security/ftr/cloud_security_posture/agentless_api/index.ts +++ b/x-pack/test_serverless/functional/test_suites/security/ftr/cloud_security_posture/mki_only/index.ts @@ -9,7 +9,9 @@ import { FtrProviderContext } from '../../../../../ftr_provider_context'; export default function ({ loadTestFile }: FtrProviderContext) { describe('cloud_security_posture', function () { - this.tags(['failsOnMKI', 'cloud_security_posture']); - loadTestFile(require.resolve('./create_agent')); + this.tags(['cloud_security_posture']); + + // do not resolve files which are ending with `.essentials.ts` + loadTestFile(require.resolve('./agentless/mki_create_agent')); }); } diff --git a/x-pack/test_serverless/functional/test_suites/security/index.mki_only.ts b/x-pack/test_serverless/functional/test_suites/security/index.mki_only.ts new file mode 100644 index 0000000000000..baff65fb737f6 --- /dev/null +++ b/x-pack/test_serverless/functional/test_suites/security/index.mki_only.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 { FtrProviderContext } from '../../ftr_provider_context'; + +export default function ({ loadTestFile }: FtrProviderContext) { + describe('serverless security UI MKI only', function () { + this.tags(['security-mki-only ']); + loadTestFile(require.resolve('./ftr/cloud_security_posture/mki_only')); + }); +} diff --git a/x-pack/test_serverless/functional/test_suites/security/index.ts b/x-pack/test_serverless/functional/test_suites/security/index.ts index 833df2edb78cd..30f35c52295ce 100644 --- a/x-pack/test_serverless/functional/test_suites/security/index.ts +++ b/x-pack/test_serverless/functional/test_suites/security/index.ts @@ -8,8 +8,6 @@ import { FtrProviderContext } from '../../ftr_provider_context'; export default function ({ loadTestFile }: FtrProviderContext) { - const isCloud = !!process.env.TEST_CLOUD; - describe('serverless security UI', function () { this.tags(['esGate']); @@ -17,9 +15,5 @@ export default function ({ loadTestFile }: FtrProviderContext) { loadTestFile(require.resolve('./ftr/cases')); loadTestFile(require.resolve('./ftr/advanced_settings')); loadTestFile(require.resolve('./ml')); - if (isCloud) { - // only run the agentless API tests in the Serverless Quality Gates - loadTestFile(require.resolve('./ftr/cloud_security_posture/agentless_api')); - } }); } diff --git a/yarn.lock b/yarn.lock index 5bf9282d9cd88..90429bc21f489 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2197,10 +2197,10 @@ dependencies: object-hash "^1.3.0" -"@elastic/charts@68.0.2": - version "68.0.2" - resolved "https://registry.yarnpkg.com/@elastic/charts/-/charts-68.0.2.tgz#8868a1d998137c41985a9b6da340391a31bae2f0" - integrity sha512-d0+qxiUovKwXeDDSrI4JQgTzk5YCbYnKxQAGV0jH37QLUzTo+t7yKqa7VTcCfEXzmtyD9Fwvihe/hCeHo+ii2w== +"@elastic/charts@68.0.3": + version "68.0.3" + resolved "https://registry.yarnpkg.com/@elastic/charts/-/charts-68.0.3.tgz#dc4aaeb4cdc8751d5759b58dc9958efb3c2639da" + integrity sha512-U+NCTo2LCDDSVkV5kGinhzbiAvfEcVAZ4D2YM/0RZQFRvJfJBvelbG+jDkt6N2mEauJ4ECDDcb33995fbs71TA== dependencies: "@popperjs/core" "^2.11.8" bezier-easing "^2.1.0" @@ -4000,6 +4000,10 @@ version "0.0.0" uid "" +"@kbn/asset-inventory-plugin@link:x-pack/plugins/asset_inventory": + version "0.0.0" + uid "" + "@kbn/audit-log-plugin@link:x-pack/test/security_api_integration/plugins/audit_log": version "0.0.0" uid "" @@ -5320,6 +5324,10 @@ version "0.0.0" uid "" +"@kbn/dependency-ownership@link:packages/kbn-dependency-ownership": + version "0.0.0" + uid "" + "@kbn/dependency-usage@link:packages/kbn-dependency-usage": version "0.0.0" uid "" @@ -6872,6 +6880,10 @@ version "0.0.0" uid "" +"@kbn/saved-search-component@link:packages/kbn-saved-search-component": + version "0.0.0" + uid "" + "@kbn/saved-search-plugin@link:src/plugins/saved_search": version "0.0.0" uid "" @@ -9105,7 +9117,7 @@ require-from-string "^2.0.2" uri-js-replace "^1.0.1" -"@redocly/cli@^1.25.12": +"@redocly/cli@^1.25.14": version "1.25.14" resolved "https://registry.yarnpkg.com/@redocly/cli/-/cli-1.25.14.tgz#05810916bac2193137020ffbfa0bd766caca2258" integrity sha512-HRDOoN3YpFe4+2rWrL/uTqRUDqqyrRtj1MVHFJ0heKTfBLOFEEfXXUYExw7R6yoiY3+GnptR96wePeFpH1gheg== @@ -12047,10 +12059,10 @@ dependencies: "@types/node" "*" -"@types/pngjs@^3.4.0": - version "3.4.2" - resolved "https://registry.yarnpkg.com/@types/pngjs/-/pngjs-3.4.2.tgz#8dc49b45fbcf18a5873179e3664f049388e39ecf" - integrity sha512-LJVPDraJ5YFEnMHnzxTN4psdWz1M61MtaAAWPn3qnDk5fvs7BAmmQ9pd3KPlrdrvozMyne4ktanD4pg0L7x1Pw== +"@types/pngjs@^6.0.5": + version "6.0.5" + resolved "https://registry.yarnpkg.com/@types/pngjs/-/pngjs-6.0.5.tgz#6dec2f7eb8284543ca4e423f3c09b119fa939ea3" + integrity sha512-0k5eKfrA83JOZPppLtS2C7OUtyNAl2wKNxfyYl9Q5g9lPkgBl/9hNyAu6HuEH2J4XmIv2znEpkDd0SaZVxW6iQ== dependencies: "@types/node" "*" @@ -15151,7 +15163,7 @@ chrome-trace-event@^1.0.2: dependencies: tslib "^1.9.0" -chromedriver@^131.0.0: +chromedriver@^131.0.1: version "131.0.1" resolved "https://registry.yarnpkg.com/chromedriver/-/chromedriver-131.0.1.tgz#bfbf47f6c2ad7a65c154ff47d321bd8c33b52a77" integrity sha512-LHRh+oaNU1WowJjAkWsviN8pTzQYJDbv/FvJyrQ7XhjKdIzVh/s3GV1iU7IjMTsxIQnBsTjx+9jWjzCWIXC7ug== @@ -19233,7 +19245,7 @@ foreground-child@^2.0.0: cross-spawn "^7.0.0" signal-exit "^3.0.2" -foreground-child@^3.1.0: +foreground-child@^3.1.0, foreground-child@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.3.0.tgz#0ac8644c06e431439f8561db8ecf29a7b5519c77" integrity sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg== @@ -19321,13 +19333,13 @@ formdata-polyfill@^4.0.10: dependencies: fetch-blob "^3.1.2" -formidable@^3.5.1: - version "3.5.1" - resolved "https://registry.yarnpkg.com/formidable/-/formidable-3.5.1.tgz#9360a23a656f261207868b1484624c4c8d06ee1a" - integrity sha512-WJWKelbRHN41m5dumb0/k8TeAx7Id/y3a+Z7QfhxP/htI9Js5zYaEDtG8uMgG0vM0lOlqnmjE99/kfpOYi/0Og== +formidable@^3.5.1, formidable@^3.5.2: + version "3.5.2" + resolved "https://registry.yarnpkg.com/formidable/-/formidable-3.5.2.tgz#207c33fecdecb22044c82ba59d0c63a12fb81d77" + integrity sha512-Jqc1btCy3QzRbJaICGwKcBfGWuLADRerLzDqi2NwSt/UkXLsHJw2TVResiaoBufHVHy9aSgClOHCeJsSsFLTbg== dependencies: dezalgo "^1.0.4" - hexoid "^1.0.0" + hexoid "^2.0.0" once "^1.4.0" formik@^2.4.6: @@ -20472,10 +20484,10 @@ heap@^0.2.6: resolved "https://registry.yarnpkg.com/heap/-/heap-0.2.6.tgz#087e1f10b046932fc8594dd9e6d378afc9d1e5ac" integrity sha1-CH4fELBGky/IWU3Z5tN4r8nR5aw= -hexoid@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/hexoid/-/hexoid-1.0.0.tgz#ad10c6573fb907de23d9ec63a711267d9dc9bc18" - integrity sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g== +hexoid@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/hexoid/-/hexoid-2.0.0.tgz#fb36c740ebbf364403fa1ec0c7efd268460ec5b9" + integrity sha512-qlspKUK7IlSQv2o+5I7yhUd7TxlOG2Vr5LTa3ve2XSNVKAL/n/u/7KLvKmFNimomDIKvZFXWHv0T12mv7rT8Aw== highlight.js@^10.1.1, highlight.js@~10.4.0: version "10.4.1" @@ -21841,16 +21853,6 @@ istanbul-lib-hook@^3.0.0: dependencies: append-transform "^2.0.0" -istanbul-lib-instrument@^4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz#873c6fff897450118222774696a3f28902d77c1d" - integrity sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ== - dependencies: - "@babel/core" "^7.7.5" - "@istanbuljs/schema" "^0.1.2" - istanbul-lib-coverage "^3.0.0" - semver "^6.3.0" - istanbul-lib-instrument@^5.0.4: version "5.1.0" resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.1.0.tgz#7b49198b657b27a730b8e9cb601f1e1bff24c59a" @@ -21862,7 +21864,7 @@ istanbul-lib-instrument@^5.0.4: istanbul-lib-coverage "^3.2.0" semver "^6.3.0" -istanbul-lib-instrument@^6.0.0: +istanbul-lib-instrument@^6.0.0, istanbul-lib-instrument@^6.0.2: version "6.0.3" resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz#fa15401df6c15874bcb2105f773325d78c666765" integrity sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q== @@ -25149,10 +25151,10 @@ nwsapi@^2.2.2: resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.2.tgz#e5418863e7905df67d51ec95938d67bf801f0bb0" integrity sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw== -nyc@^15.1.0: - version "15.1.0" - resolved "https://registry.yarnpkg.com/nyc/-/nyc-15.1.0.tgz#1335dae12ddc87b6e249d5a1994ca4bdaea75f02" - integrity sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A== +nyc@^17.1.0: + version "17.1.0" + resolved "https://registry.yarnpkg.com/nyc/-/nyc-17.1.0.tgz#b6349a401a62ffeb912bd38ea9a018839fdb6eb1" + integrity sha512-U42vQ4czpKa0QdI1hu950XuNhYqgoM+ZF1HT+VuUHL9hPfDPVvNQyltmMqdE9bUHMVa+8yNbc3QKTj8zQhlVxQ== dependencies: "@istanbuljs/load-nyc-config" "^1.0.0" "@istanbuljs/schema" "^0.1.2" @@ -25161,12 +25163,12 @@ nyc@^15.1.0: decamelize "^1.2.0" find-cache-dir "^3.2.0" find-up "^4.1.0" - foreground-child "^2.0.0" + foreground-child "^3.3.0" get-package-type "^0.1.0" glob "^7.1.6" istanbul-lib-coverage "^3.0.0" istanbul-lib-hook "^3.0.0" - istanbul-lib-instrument "^4.0.0" + istanbul-lib-instrument "^6.0.2" istanbul-lib-processinfo "^2.0.2" istanbul-lib-report "^3.0.0" istanbul-lib-source-maps "^4.0.0" @@ -25371,10 +25373,10 @@ objectorarray@^1.0.4: resolved "https://registry.yarnpkg.com/objectorarray/-/objectorarray-1.0.4.tgz#d69b2f0ff7dc2701903d308bb85882f4ddb49483" integrity sha512-91k8bjcldstRz1bG6zJo8lWD7c6QXcB4nTDUqiEvIL1xAsLoZlOOZZG+nd6YPz+V7zY1580J4Xxh1vZtyv4i/w== -oboe@^2.1.4: - version "2.1.4" - resolved "https://registry.yarnpkg.com/oboe/-/oboe-2.1.4.tgz#20c88cdb0c15371bb04119257d4fdd34b0aa49f6" - integrity sha1-IMiM2wwVNxuwQRklfU/dNLCqSfY= +oboe@^2.1.7: + version "2.1.7" + resolved "https://registry.yarnpkg.com/oboe/-/oboe-2.1.7.tgz#14cb69c750757a964c760383e094887822a32947" + integrity sha512-Y2oCMU2xgITORaNvIDCvUyn2ZG/5NI19lLjMFThgYzCH+GA/fgYvVcwxAqnZPiMiUrPq64jLzCkBXqKSu/R6MA== dependencies: http-https "^1.0.0" @@ -26279,16 +26281,11 @@ png-js@^1.0.0: resolved "https://registry.yarnpkg.com/png-js/-/png-js-1.0.0.tgz#e5484f1e8156996e383aceebb3789fd75df1874d" integrity sha512-k+YsbhpA9e+EFfKjTCH3VW6aoKlyNYI6NYdTfDL4CIvFnvsuO84ttonmZE7rc+v23SLTH8XX+5w/Ak9v0xGY4g== -pngjs@7.0.0: +pngjs@7.0.0, pngjs@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-7.0.0.tgz#a8b7446020ebbc6ac739db6c5415a65d17090e26" integrity sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow== -pngjs@^3.4.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-3.4.0.tgz#99ca7d725965fb655814eaf65f38f12bbdbf555f" - integrity sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w== - pngjs@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-6.0.0.tgz#ca9e5d2aa48db0228a52c419c3308e87720da821" @@ -29118,10 +29115,10 @@ select-hose@^2.0.0: resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo= -selenium-webdriver@^4.26.0: - version "4.26.0" - resolved "https://registry.yarnpkg.com/selenium-webdriver/-/selenium-webdriver-4.26.0.tgz#23163cdad20388214a4ad17c1f38262a0857c902" - integrity sha512-nA7jMRIPV17mJmAiTDBWN96Sy0Uxrz5CCLb7bLVV6PpL417SyBMPc2Zo/uoREc2EOHlzHwHwAlFtgmSngSY4WQ== +selenium-webdriver@^4.27.0: + version "4.27.0" + resolved "https://registry.yarnpkg.com/selenium-webdriver/-/selenium-webdriver-4.27.0.tgz#f0f26ce453805e7dc77151040442c67e441dbe7a" + integrity sha512-LkTJrNz5socxpPnWPODQ2bQ65eYx9JK+DQMYNihpTjMCqHwgWGYQnQTCAAche2W3ZP87alA+1zYPvgS8tHNzMQ== dependencies: "@bazel/runfiles" "^6.3.1" jszip "^3.10.1" @@ -30559,7 +30556,22 @@ stylus-lookup@^5.0.1: dependencies: commander "^10.0.1" -superagent@^9.0.1, superagent@^9.0.2: +superagent@^10.1.1: + version "10.1.1" + resolved "https://registry.yarnpkg.com/superagent/-/superagent-10.1.1.tgz#2f112591a5701a1d4467048580bcfda104e5a94d" + integrity sha512-9pIwrHrOj3uAnqg9gDlW7EA2xv+N5au/dSM0kM22HTqmUu8jBxNT+8uA7tA3UoCnmiqzpSbu8rasIUZvbyamMQ== + dependencies: + component-emitter "^1.3.0" + cookiejar "^2.1.4" + debug "^4.3.4" + fast-safe-stringify "^2.1.1" + form-data "^4.0.0" + formidable "^3.5.2" + methods "^1.1.2" + mime "2.6.0" + qs "^6.11.0" + +superagent@^9.0.1: version "9.0.2" resolved "https://registry.yarnpkg.com/superagent/-/superagent-9.0.2.tgz#a18799473fc57557289d6b63960610e358bdebc1" integrity sha512-xuW7dzkUpcJq7QnhOsnNUgtYp3xRwpt2F7abdRYIpCsAt0hhUqia0EdxyXZQQpNmGtsCzYHryaKSV3q3GJnq7w== @@ -33391,10 +33403,10 @@ xml@^1.0.0: resolved "https://registry.yarnpkg.com/xml/-/xml-1.0.1.tgz#78ba72020029c5bc87b8a81a3cfcd74b4a2fc1e5" integrity sha1-eLpyAgApxbyHuKgaPPzXS0ovweU= -xmlbuilder@13.0.2: - version "13.0.2" - resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-13.0.2.tgz#02ae33614b6a047d1c32b5389c1fdacb2bce47a7" - integrity sha512-Eux0i2QdDYKbdbA6AM6xE4m6ZTZr4G4xF9kahI2ukSEMCzwce2eX9WlTI5J3s+NU7hpasFsr8hWIONae7LluAQ== +xmlbuilder@15.1.1: + version "15.1.1" + resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-15.1.1.tgz#9dcdce49eea66d8d10b42cae94a79c3c8d0c2ec5" + integrity sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg== xmlbuilder@~11.0.0: version "11.0.1"